[LLVMdev] lifetime.start/end clarification
Hal Finkel
hfinkel at anl.gov
Wed Nov 5 12:48:32 PST 2014
----- Original Message -----
> From: "Nick Lewycky" <nlewycky at google.com>
> To: "Hal Finkel" <hfinkel at anl.gov>
> Cc: "Reid Kleckner" <rnk at google.com>, "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu>
> Sent: Wednesday, November 5, 2014 2:39:38 PM
> Subject: Re: [LLVMdev] lifetime.start/end clarification
>
> On 5 November 2014 11:51, Hal Finkel < hfinkel at anl.gov > wrote:
>
>
> ----- 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.
>
>
>
> It removes them because it does (or will) remove the associated
> alloca anyways as part of turning loads and stores into SSA. There's
> no need for lifetime intrinsic equivalents on SSA given that we have
> use-lists and tools like the dominator tree.
Good point, I did not think too carefully about what the code was doing, but rather pointing out that there is special-case code dealing with lifetime intrinsics that needs to be looked at, and code that does not deal specifically with lifetime intrinsics that may have to do so. I certainly agree that we don't need them for SSA values.
For the code in question, I don't see why you wouldn't just RAUW the alloca with undef and then let DCE remove the intrinsics (this is, however, somewhat off-topic for this thread).
>
>
>
>
> > 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.
>
> I think the idea is to define them with the semantics of storing
> undef bytes, but keep them implemented as intrinsic function calls,
> so that the optimizer does not simply delete them. It's a way of
> communicating that these are deliberate and valuable stores to
> undef, as opposed to stores of SSA values that were later found to
> be undef.
I did not get that impression, and if that is what was proposed, I don't see how that differs, in practice, from what we have now.
Thanks again,
Hal
>
>
>
> -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
>
>
> _______________________________________________
> 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