rust/src/librustc/middle/trans
Björn Steinbrink 92d1f155da Emit LLVM lifetime intrinsics to improve stack usage and codegen in general
Lifetime intrinsics help to reduce stack usage, because LLVM can apply
stack coloring to reuse the stack slots of dead allocas for new ones.

For example these functions now both use the same amount of stack, while
previous `bar()` used five times as much as `foo()`:

````rust
fn foo() {
  println("{}", 5);
}

fn bar() {
  println("{}", 5);
  println("{}", 5);
  println("{}", 5);
  println("{}", 5);
  println("{}", 5);
}
````

On top of that, LLVM can also optimize out certain operations when it
knows that memory is dead after a certain point. For example, it can
sometimes remove the zeroing used to cancel the drop glue. This is
possible when the glue drop itself was already removed because the
zeroing dominated the drop glue call. For example in:

````rust
pub fn bar(x: (Box<int>, int)) -> (Box<int>, int) {
    x
}
````

With optimizations, this currently results in:

````llvm
define void @_ZN3bar20h330fa42547df8179niaE({ i64*, i64 }* noalias nocapture nonnull sret, { i64*, i64 }* noalias nocapture nonnull) unnamed_addr #0 {
"_ZN29_$LP$Box$LT$int$GT$$C$int$RP$39glue_drop.$x22glue_drop$x22$LP$1347$RP$17h88cf42702e5a322aE.exit":
  %2 = bitcast { i64*, i64 }* %1 to i8*
  %3 = bitcast { i64*, i64 }* %0 to i8*
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 8, i1 false)
  tail call void @llvm.memset.p0i8.i64(i8* %2, i8 0, i64 16, i32 8, i1 false)
  ret void
}
````

But with lifetime intrinsics we get:

````llvm
define void @_ZN3bar20h330fa42547df8179niaE({ i64*, i64 }* noalias nocapture nonnull sret, { i64*, i64 }* noalias nocapture nonnull) unnamed_addr #0 {
"_ZN29_$LP$Box$LT$int$GT$$C$int$RP$39glue_drop.$x22glue_drop$x22$LP$1347$RP$17h88cf42702e5a322aE.exit":
  %2 = bitcast { i64*, i64 }* %1 to i8*
  %3 = bitcast { i64*, i64 }* %0 to i8*
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 8, i1 false)
  tail call void @llvm.lifetime.end(i64 16, i8* %2)
  ret void
}
````

Fixes #15665
2014-07-22 09:17:41 +02:00
..
_match.rs Emit LLVM lifetime intrinsics to improve stack usage and codegen in general 2014-07-22 09:17:41 +02:00
adt.rs librustc: Set enum discriminant only after field translation. 2014-07-18 11:58:45 -07:00
asm.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
base.rs Emit LLVM lifetime intrinsics to improve stack usage and codegen in general 2014-07-22 09:17:41 +02:00
basic_block.rs librustc: Implement lifetime elision. 2014-07-19 13:10:58 -07:00
build.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
builder.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
cabi_arm.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
cabi_mips.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
cabi_x86_64.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
cabi_x86.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
cabi.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
callee.rs librustc: Only emit constructor functions as necessary. 2014-07-18 11:58:45 -07:00
cleanup.rs Emit LLVM lifetime intrinsics to improve stack usage and codegen in general 2014-07-22 09:17:41 +02:00
closure.rs librustc: Set enum discriminant only after field translation. 2014-07-18 11:58:45 -07:00
common.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
consts.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
context.rs Emit LLVM lifetime intrinsics to improve stack usage and codegen in general 2014-07-22 09:17:41 +02:00
controlflow.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
datum.rs Emit LLVM lifetime intrinsics to improve stack usage and codegen in general 2014-07-22 09:17:41 +02:00
debuginfo.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
doc.rs librustc: Remove ~EXPR, ~TYPE, and ~PAT from the language, except 2014-05-06 23:12:54 -07:00
expr.rs Emit LLVM lifetime intrinsics to improve stack usage and codegen in general 2014-07-22 09:17:41 +02:00
foreign.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
glue.rs auto merge of #15784 : dotdash/rust/unreach, r=luqmana 2014-07-20 07:51:32 +00:00
inline.rs change to new trait style for method field refs 2014-07-15 14:46:32 -07:00
intrinsic.rs auto merge of #15784 : dotdash/rust/unreach, r=luqmana 2014-07-20 07:51:32 +00:00
llrepr.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
machine.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
macros.rs Convert most code to new inner attribute syntax. 2014-03-28 17:12:21 -07:00
meth.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
mod.rs Remove special rooting code from trans 2014-04-23 18:19:05 +02:00
monomorphize.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
reflect.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
tvec.rs Emit LLVM lifetime intrinsics to improve stack usage and codegen in general 2014-07-22 09:17:41 +02:00
type_.rs Fix rebase fallout. Sorry. 2014-07-14 12:27:56 -07:00
type_of.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
value.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00