Skip to content

Commit a174d65

Browse files
committed
Added llvm lifetime annotations to function call argument temporaries.
The goal of this change is to ensure that llvm will do stack slot optimization on these temporaries. This ensures that in code like: ```rust const A: [u8; 1024] = [0; 1024]; fn copy_const() { f(A); f(A); } ``` we only use 1024 bytes of stack space, instead of 2048 bytes.
1 parent 3d829a0 commit a174d65

File tree

1 file changed

+16
-2
lines changed
  • compiler/rustc_codegen_ssa/src/mir

1 file changed

+16
-2
lines changed

compiler/rustc_codegen_ssa/src/mir/block.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
132132
llargs: &[Bx::Value],
133133
destination: Option<(ReturnDest<'tcx, Bx::Value>, mir::BasicBlock)>,
134134
cleanup: Option<mir::BasicBlock>,
135+
argument_tmps: &[PlaceRef<'tcx, <Bx as BackendTypes>::Value>],
135136
) {
136137
// If there is a cleanup block and the function we're calling can unwind, then
137138
// do an invoke, otherwise do a call.
@@ -172,6 +173,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
172173
if let Some((ret_dest, target)) = destination {
173174
bx.switch_to_block(fx.llbb(target));
174175
fx.set_debug_loc(bx, self.terminator.source_info);
176+
for tmp in argument_tmps {
177+
bx.lifetime_end(tmp.llval, tmp.layout.size);
178+
}
175179
fx.store_return(bx, ret_dest, &fn_abi.ret, invokeret);
176180
}
177181
} else {
@@ -186,6 +190,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
186190
}
187191

188192
if let Some((ret_dest, target)) = destination {
193+
for tmp in argument_tmps {
194+
bx.lifetime_end(tmp.llval, tmp.layout.size);
195+
}
189196
fx.store_return(bx, ret_dest, &fn_abi.ret, llret);
190197
self.funclet_br(fx, bx, target);
191198
} else {
@@ -415,6 +422,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
415422
args,
416423
Some((ReturnDest::Nothing, target)),
417424
unwind,
425+
&[],
418426
);
419427
}
420428

@@ -492,7 +500,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
492500
let (fn_abi, llfn) = common::build_langcall(&bx, Some(span), lang_item);
493501

494502
// Codegen the actual panic invoke/call.
495-
helper.do_call(self, &mut bx, fn_abi, llfn, &args, None, cleanup);
503+
helper.do_call(self, &mut bx, fn_abi, llfn, &args, None, cleanup, &[]);
496504
}
497505

498506
fn codegen_abort_terminator(
@@ -508,7 +516,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
508516
let (fn_abi, llfn) = common::build_langcall(&bx, Some(span), LangItem::PanicNoUnwind);
509517

510518
// Codegen the actual panic invoke/call.
511-
helper.do_call(self, &mut bx, fn_abi, llfn, &[], None, None);
519+
helper.do_call(self, &mut bx, fn_abi, llfn, &[], None, None, &[]);
512520
}
513521

514522
/// Returns `true` if this is indeed a panic intrinsic and codegen is done.
@@ -579,6 +587,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
579587
&[msg.0, msg.1, location],
580588
target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)),
581589
cleanup,
590+
&[],
582591
);
583592
} else {
584593
// a NOP
@@ -786,6 +795,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
786795
(args, None)
787796
};
788797

798+
let mut argument_tmps = vec![];
789799
'make_args: for (i, arg) in first_args.iter().enumerate() {
790800
let mut op = self.codegen_operand(&mut bx, arg);
791801

@@ -851,8 +861,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
851861
(&mir::Operand::Copy(_), Ref(_, None, _))
852862
| (&mir::Operand::Constant(_), Ref(_, None, _)) => {
853863
let tmp = PlaceRef::alloca(&mut bx, op.layout);
864+
bx.lifetime_start(tmp.llval, tmp.layout.size);
854865
op.val.store(&mut bx, tmp);
855866
op.val = Ref(tmp.llval, None, tmp.align);
867+
argument_tmps.push(tmp);
856868
}
857869
_ => {}
858870
}
@@ -925,6 +937,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
925937
&llargs,
926938
target.as_ref().map(|&target| (ret_dest, target)),
927939
cleanup,
940+
&argument_tmps,
928941
);
929942

930943
bx.switch_to_block(bb_fail);
@@ -942,6 +955,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
942955
&llargs,
943956
target.as_ref().map(|&target| (ret_dest, target)),
944957
cleanup,
958+
&argument_tmps,
945959
);
946960
}
947961

0 commit comments

Comments
 (0)