Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function body is translated more than once #7349

Closed
dotdash opened this issue Jun 24, 2013 · 6 comments
Closed

Function body is translated more than once #7349

dotdash opened this issue Jun 24, 2013 · 6 comments
Labels
A-codegen Area: Code generation I-slow Issue: Problems and improvements with respect to performance of generated code.

Comments

@dotdash
Copy link
Contributor

dotdash commented Jun 24, 2013

The closures in std::os::with_env_lock are translated multiple times, probably once for each monomorphic version of that function. Since the closure isn't actually generic, we end up with a single function that has its body repeated multiple times:

define void @_ZN2os13with_env_lock18rust_take_env_lock16_df5982df3c0192c6_07preE({ i64, %tydesc*, i8*, i8*, i8 }*) #9 {
static_allocas:
br label %1

return: ; preds = %1
ret void

; <label>:1 ; preds = %static_allocas
call void @rust_take_env_lock()
br label %return

static_allocas1: ; No predecessors!
br label %2

return2: ; preds = %2
ret void

; <label>:2 ; preds = %static_allocas1
call void @rust_take_env_lock()
br label %return2

static_allocas3: ; No predecessors!
br label %3

return4: ; preds = %3
ret void

; <label>:3 ; preds = %static_allocas3
call void @rust_take_env_lock()
br label %return4

static_allocas5: ; No predecessors!
br label %4

return6: ; preds = %4
ret void

; <label>:4 ; preds = %static_allocas5
call void @rust_take_env_lock()
br label %return6
}

This is not limited to closures, the same happens for rustc::middle::typeck::astconv::ast_ty_to_ty::check_path_args, which contains its body 6 times.

@msullivan
Copy link
Contributor

This is a little tricky with closures. Note that even though the closures are not polymorphic, they can close over type variables. The first closure in with_env_lock does use polymorphic things that it closed over...

@dotdash
Copy link
Contributor Author

dotdash commented Jul 2, 2013

Oops, looking at the ll code, it's not actually the closure that is translated multiple times, but the FFI wrapper, sorry.

@catamorphism
Copy link
Contributor

Nominating for milestone 5, production-ready

@catamorphism
Copy link
Contributor

Needs more explanation; not a milestone issue.

@dotdash
Copy link
Contributor Author

dotdash commented Dec 31, 2013

The original code isn't present anymore, but here's a testcase:

fn outer<T>(x: T) -> T {
    fn inner(x: uint) -> uint {
        x
    }

    x
}

fn main() {
    outer(5i);
    outer(5u);
}

Results in:

; Function Attrs: uwtable
define internal i64 @_ZN5outer5inner67h7600d001aed24abe20f7e4097463dde0dedcf59bbd47ee5a6329d5a851388702ap4v0.0E({ i64, %tydesc*, i8*, i8*, i8 }*, i64) unnamed_addr #4 {
"function top level":
  %__arg = alloca i64
  store i64 %1, i64* %__arg
  %2 = load i64* %__arg
  ret i64 %2

"function top level1":                            ; No predecessors!
  %__arg2 = alloca i64
  store i64 %1, i64* %__arg2
  %3 = load i64* %__arg2
  ret i64 %3

"function top level3":                            ; No predecessors!
  %__arg4 = alloca i64
  store i64 %1, i64* %__arg4
  %4 = load i64* %__arg4
  ret i64 %4
}

i.e. inner is translated three times. Once for the generic version and once more for each of the monomorphized versions of outer.

@luqmana
Copy link
Member

luqmana commented Aug 19, 2014

Fixed by #16059.

@luqmana luqmana closed this as completed Aug 19, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation I-slow Issue: Problems and improvements with respect to performance of generated code.
Projects
None yet
Development

No branches or pull requests

4 participants