ldc
ldc copied to clipboard
Annotate variables with `llvm.lifetime.start` `end`
trafficstars
For optimization, we should mark our variables with llvm.lifetime.start and llvm.lifetime.end, but we only have to do that when O-level > 0. For ASan, these lifetime annotations are used for use-after-scope checking, and should be enabled at -O0 already. So enable when Olevel > 0 || ASan_enabled; that's what Clang does.
For optimization, this allows stack reuse. For ASan, it is needed for use-after-scope checking which catches bugs like this:
void useAfterScope() {
int* p;
{
int x = 0;
p = &x; // cannot statically disallow this because
*p = 1; // this is a valid use of things
}
*p = 5; // but then this can happen... bug!
}
I'll start working on this.
Another testcase:
void opaque(int* i);
void foo() {
{
int[100] arr = void;
opaque(&arr[0]);
}
{
int[100] arr = void;
opaque(&arr[0]);
}
}
Currently gives this IR (i.e. without lifetime annotation):
eclare void @_D7example6opaqueFPiZv(i32*)
define void @_D7example3fooFZv() {
%arr = alloca [100 x i32], align 4
%arr1 = alloca [100 x i32], align 4
%1 = bitcast [100 x i32]* %arr to i32*
call void @_D7example6opaqueFPiZv(i32* %1)
%2 = bitcast [100 x i32]* %arr1 to i32*
call void @_D7example6opaqueFPiZv(i32* %2)
ret void
}
with asm:
_D7example3fooFZv: # @_D7example3fooFZv
sub rsp, 808. # 808 bytes stack allocation
...
With lifetime annotation, codegen is better:
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
define void @with_lifetime() {
%arr = alloca [100 x i32], align 4
%arr1 = alloca [100 x i32], align 4
call void @llvm.lifetime.start.p0(i64 400, ptr nonnull %arr)
%1 = bitcast [100 x i32]* %arr to i32*
call void @_D7example6opaqueFPiZv(i32* %1)
call void @llvm.lifetime.end.p0(i64 400, ptr nonnull %arr)
call void @llvm.lifetime.start.p0(i64 400, ptr nonnull %arr1)
%2 = bitcast [100 x i32]* %arr1 to i32*
call void @_D7example6opaqueFPiZv(i32* %2)
call void @llvm.lifetime.end.p0(i64 400, ptr nonnull %arr1)
ret void
}
asm:
with_lifetime: # @with_lifetime
sub rsp, 408. # 408 bytes stack
....
#4395