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

Inefficient codegen for function returning String #34861

Closed
jrmuizel opened this issue Jul 16, 2016 · 4 comments
Closed

Inefficient codegen for function returning String #34861

jrmuizel opened this issue Jul 16, 2016 · 4 comments

Comments

@jrmuizel
Copy link
Contributor

jrmuizel commented Jul 16, 2016

The following code seems generate inefficient code compared to the C++ equivalent:

pub fn goo() -> String {
    let url_prefix = "https://".to_string();
    url_prefix
}

gives:

define void @_ZN8rust_out3goo17h4b78ef91328cd5a8E(%"3.std::string::String"* noalias nocapture sret dereferenceable(24)) unnamed_addr #0 personality i32 (i32, i32, i64, %"8.unwind::libunwind::_Unwind_Exception"*, %"8.unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality {
_ZN19std..string..String9drop.734817h847d71ab7fd1dc50E.exit:
  %url_prefix = alloca %"3.std::string::String", align 8
  %1 = bitcast %"3.std::string::String"* %url_prefix to i8*
  call void @llvm.lifetime.start(i64 24, i8* %1)
  call void @"_ZN80_$LT$string..String$u20$as$u20$core..convert..From$LT$$RF$$u27$a$u20$str$GT$$GT$4from17hfac1f2dc216f571bE"(%"3.std::string::String"* noalias nocapture nonnull sret dereferenceable(24) %url_prefix, i8* noalias nonnull readonly getelementptr inbounds ([8 x i8], [8 x i8]* @str7345, i64 0, i64 0), i64 8)
  %2 = bitcast %"3.std::string::String"* %0 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %1, i64 24, i32 8, i1 false)
  call void @llvm.lifetime.end(i64 24, i8* %1)
  ret void
}

vs.

define void @_Z3goov(%"class.std::__1::basic_string"* noalias sret %agg.result) #0 {
  tail call void @_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcm(%"class.std::__1::basic_string"* %agg.result, i8* getelementptr inbounds ([56 x i8]* @.str, i64 0, i64 0), i64 55)
  ret void
}

The rust code has an additional alloca and a memcpy

@jrmuizel
Copy link
Contributor Author

pub fn goo() -> String {
"https://".to_string()
}

Gives:
define void @_ZN8rust_out3goo17h4b78ef91328cd5a8E(%"3.std::string::String"* noalias nocapture sret dereferenceable(24)) unnamed_addr #0 {
entry-block:
tail call void @"ZN80$LT$string..String$u20$as$u20$core..convert..From$LT$$RF$$u27$a$u20$str$GT$$GT$4from17hfac1f2dc216f571bE"(%"3.std::string::String"* noalias nocapture nonnull sret dereferenceable(24) %0, i8* noalias nonnull readonly getelementptr inbounds ([8 x i8], [8 x i8]* @str7329, i64 0, i64 0), i64 8)
ret void
}

so it looks like this is just rust-lang/rfcs#788

@jrmuizel jrmuizel reopened this Aug 3, 2017
@jrmuizel
Copy link
Contributor Author

jrmuizel commented Aug 3, 2017

Perhaps #32966 is more appropriate dup of this.

@jrmuizel
Copy link
Contributor Author

This is indeed fixed with panic=abort in nightly. I suspect it was fixed by #44992

@jrmuizel
Copy link
Contributor Author

I filed #45499 about the missing tail calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant