[llvm-dev] Jit: use @llvm.lifetime.end to optimize away stores to globals used as temporaries
Tom Aernoudt via llvm-dev
llvm-dev at lists.llvm.org
Mon Feb 29 08:01:57 PST 2016
Hi all,
Is it allowed to use the @llvm.lifetime.end intrinsic to optimize away stores to global variables that are used as temporaries?
eg I want use the Jit engine to generate code for the following function 'f':
struct State {
int a;
int tmp;
int b;
};
void f0(State* s) { s->tmp = s->a; }
void f1(State* s) { s->b = s->tmp; }
void f(State* s)
{
f0(s);
f1(s);
}
The Jit engine generates the following code:
define void @_Z1fP5State(%struct.State* %s) #1 {
%1 = getelementptr inbounds %struct.State, %struct.State* %s, i64 0, i32 0
%2 = load i32, i32* %1, align 4, !tbaa !1
%3 = getelementptr inbounds %struct.State, %struct.State* %s, i64 0, i32 1
store i32 %2, i32* %3, align 4, !tbaa !6
%4 = getelementptr inbounds %struct.State, %struct.State* %s, i64 0, i32 2
store i32 %2, i32* %4, align 4, !tbaa !7
ret void
}
Which gives (on x86_64):
_Z1fP5State:
movl (%rdi), %eax
movl %eax, 4(%rdi)
movl %eax, 8(%rdi)
retq
The 'tmp' state variable is only needed during execution of the function 'f'.
After the function has finished to value can be discarded.
How can I tell the optimizer to optimize away to stores to the 'tmp' variable?
Can I use the @llvm.lifetime.end intrinsic to do this?
Eg If I change the function 'f' as follows:
extern "C" void llvm_lifetime_end(unsigned long long, void*);
void cleanup(State* s)
{
// llvm_lifetime_end will be replaced with @llvm.lifetime.end
llvm_lifetime_end(sizeof(s->tmp), (void*)&s->tmp);
}
void f(State* s)
{
f0(s);
f1(s);
cleanup(s);
}
And then use a pass to replace the function llvm_lifetime_end with the intrinsic @llvm.lifetime.end.
I get the following code:
define void @_Z1fP5State(%struct.State* nocapture %s) #0 {
%1 = getelementptr inbounds %struct.State, %struct.State* %s, i64 0, i32 0
%2 = load i32, i32* %1, align 4, !tbaa !1
%3 = getelementptr inbounds %struct.State, %struct.State* %s, i64 0, i32 1
%4 = getelementptr inbounds %struct.State, %struct.State* %s, i64 0, i32 2
store i32 %2, i32* %4, align 4, !tbaa !7
%5 = bitcast i32* %3 to i8*
tail call void @llvm.lifetime.end(i64 4, i8* %5)
ret void
}
_Z1fP5State:
movl (%rdi), %eax
movl %eax, 8(%rdi)
retq
Is this a supported usecase of the @llvm.lifetime.end intrinsic? ie is it allowed to use the intrinsic on a global variable instead of a local variable?
Or is there a better way to get the same result?
Is it ok to only have an @llvm.lifetime.end intrinsic, without a matching @llvm.lifetime.start intrinisic?
If not is there another way to tell the optimizer to optimize away the stores to the 'tmp' state variable?
Thanks,
Tom
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160229/933885d2/attachment.html>
More information about the llvm-dev
mailing list