Uh oh!
There was an error while loading. Please reload this page.
Mark by-value parameters that are passed on the stack as nocapture - #12494
Mark by-value parameters that are passed on the stack as nocapture#12494dotdash wants to merge 1 commit into
Conversation
The by-value argument is a copy that is only valid for the duration of the function call, therefore keeping any pointer to it that outlives the call is illegal.
brson
commented
Feb 24, 2014
@dotdash thanks for the explanation. do you have an example where this leads to TCO? |
dotdash
commented
Feb 24, 2014
Generic example: #[inline(never)]fnhuge_fn(x:&str,d:int){println!("{}: {}", x, d);}fnrec(d:int){huge_fn("Test", d);rec(d+1);}pubfnmain(){rec(0);}Since In In can check larger libs like |
dotdash
commented
Feb 24, 2014
Further checking tells that there may be more TCO changes in A different example that doesn't involve recursion is this: #[crate_type="lib"];#[inline(never)]pubfnfunc(foo:Option<int>){println!("{:?}", foo);}#[inline(never)]pubfnfunc2(foo:int){println!("{:?}", foo);}pubfnbar(foo_opt:Option<int>){func(foo_opt);match foo_opt {Some(foo) => func2(foo),
_ => {}}}With the change, the call to I also found this change in the IR for librustc: Old: %283 = bitcast [4 x i64]* %282toi8*%284 = loadi8*%283, align8, !range!1switchi8%284, label%match_else42 [
;...%285 = bitcast [4 x i64]* %282to { i8, %"struct.syntax::ast::DefId[#9]", i8, { i64, void (i8*)*, i8*, i8*, %"struct.syntax::ast::Method[#9]" }* }*
;...%impl_did.sroa.0.0.idx = getelementptrinbounds { i8, %"struct.syntax::ast::DefId[#9]", i8, { i64, void (i8*)*, i8*, i8*, %"struct.syntax::ast::Method[#9]" }* }* %285, i640, i321, i320%impl_did.sroa.0.0.copyload = loadi32*%impl_did.sroa.0.0.idx, align4New: %283 = getelementptrinbounds [4 x i64]* %282, i640, i640%284 = loadi64*%283, align8%285 = trunci64%284toi8%286 = lshri64%284, 32%287 = trunci64%286toi32switchi8%285, label%match_else42 [LLVM could deduce that the value doesn't change between the two loads and combine them to a single load instead (+ shifting). Unfortunately, I don't have a simple rust example that exposes this. |
brson
commented
Feb 24, 2014
@dotdash Thanks for the details. @nikomatsakis Can you review? |
The by-value argument is a copy that is only valid for the duration of
the function call, therefore keeping any pointer to it that outlives the
call is illegal.