[LLVMdev] lifetime.start/end clarification
Hal Finkel
hfinkel at anl.gov
Wed Nov 5 11:51:45 PST 2014
----- Original Message -----
> From: "Reid Kleckner" <rnk at google.com>
> To: "Philip Reames" <listmail at philipreames.com>
> Cc: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu>
> Sent: Wednesday, November 5, 2014 12:54:30 PM
> Subject: Re: [LLVMdev] lifetime.start/end clarification
>
> This seems fine to me. The optimizer can (soundly) conclude that %p
> is dead after the "lifetime.end" (for the two instructions), and
> dead before the "lifetime.start" (for the *single* instruction in
> that basic block, *not* for the previous BB). This seems like the
> proper result for this example, am I missing something?
>
>
> What if I put that in a loop, unroll it once, and prove that the
> lifetime.start is unreachable? We would end up with IR like:
>
>
> loop:
> ... use %p
> call void @lifetime.end( %p )
>
> ... use %p
> call void @lifetime.end( %p )
> br i1 %c, label %loop, label %exit
>
>
> Are the second uses of %p uses of dead memory?
>
>
> We have similar issues if the optimizer somehow removes the lifetime
> end and keeps the start:
>
>
>
> loop:
> call void @lifetime.start( %p )
>
> ... use %p
> call void @lifetime.start( %p )
>
>
> ... use %p
> br i1 %c, label %loop, label %exit
>
>
> For this reason, it has been suggested that these intrinsics are
> horribly broken,
I disagree, these just seem like bugs. lifetime_start are marked as IntrReadWriteArgMem, but this is not really sufficient to prevent their removal should the memory be subsequently unused. Plus there are other places that just delete the lifetime intrinsics, like this in lib/Transforms/Scalar/SROA.cpp:
// FIXME: Currently the SSAUpdater infrastructure doesn't reason about
// lifetime intrinsics and so we strip them (and the bitcasts+GEPs
// leading to them) here. Eventually it should use them to optimize the
// scalar values produced.
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
assert(II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end);
II->eraseFromParent();
continue;
}
we need to go through the various places that might delete these intrinsics and fix them. The same will be true with any other mechanism.
> and both should be remodeled to just mean "store of
> undef bytes to this memory".
This is a bad idea. Stores of undef bytes can be removed if we can prove that the address is dereferenceable. And if they can't be removed, then they have side effects that can't ever be removed. Please don't do that.
-Hal
> If "use %p" is a load, for example, in
> both cases we can safely say it returns undef, because it's a
> use-after-scope.
>
>
> I think coming up with a new representation with simpler semantics is
> the way to go. One allocation or lifetime start, and one
> deallocation and end.
>
>
> Implementing this in Clang will be tricky, though. Clang's IRGen is
> supposed to be a dumb AST walk, but it has already strayed from that
> path. Needs more thought...
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
More information about the llvm-dev
mailing list