Skip to content

Suboptimal invoke-related codegen for default trait impls #43150

Closed
@alexcrichton

Description

@alexcrichton

It looks like default methods in traits will always use invoke whereas defined methods will hit the optimization to not use invoke:

// bar.rs
#![crate_type = "rlib"]
pub fn bar() {}
// foo.rs
#![crate_type = "rlib"]
extern crate bar;

pub trait A: Sized {
    fn foo1(self) {
        bar::bar();
    }
    fn foo2(self);
}

impl A for i32 {
    fn foo2(self) {
        bar::bar();
    }
}

fn main() {
    0i32.foo1();
    0i32.foo2();
}
$ rustc bar.rs
$ rustc foo.rs -L . --emit llvm-ir
$ cat foo.ll

will yield this IR, notably:

; foo::A::foo1
; Function Attrs: uwtable
define internal void @_ZN3foo1A4foo117hcfa03453b669bd94E(i32) unnamed_addr #0 personality i32 (i32, i32, i64, %"unwind::libunwind::_Unwind_Exception"*, %"unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality {
start:
  %personalityslot = alloca { i8*, i32 }
; invoke bar::bar
  invoke void @_ZN3bar3bar17h21868f3a4452d05bE()
          to label %bb3 unwind label %cleanup

; ...
}


; <i32 as foo::A>::foo2
; Function Attrs: uwtable
define void @"_ZN30_$LT$i32$u20$as$u20$foo..A$GT$4foo217h68eec0bc305998eeE"(i32) unnamed_addr #0 {
start:
; call bar::bar
  call void @_ZN3bar3bar17h21868f3a4452d05bE()
  br label %bb1

bb1:                                              ; preds = %start
  ret void
}

Note that <i32 as A>::foo1 uses an invoke instruction whereas <i32 as A>::foo2 does not.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions