[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