[LLVMdev] lifetime.start/end clarification
Philip Reames
listmail at philipreames.com
Wed Nov 5 11:31:40 PST 2014
On 11/05/2014 10:54 AM, Arnaud A. de Grandmaison wrote:
>
> *trimmed for length*
>
> This is not a theoretical question: clang can generate such cases. For
> example, the following testcase:
>
> struct X {
>
> void doSomething();
>
> char b[33];
>
> };
>
> void bar(X &);
>
> void baz();
>
> void test(int i) {
>
> if (i==9) {
>
> X x;
>
> x.doSomething();
>
> label:
>
> bar(x);
>
> } else {
>
> baz();
>
> if (i==0)
>
> goto label;
>
> }
>
> }
>
> Produces:
>
> %struct.X = type { [33 x i8] }
>
> define void @_Z4testi(i32 %i) {
>
> entry:
>
> %x = alloca %struct.X, align 1
>
> %cmp = icmp eq i32 %i, 9
>
> br i1 %cmp, label %if.then, label %if.else
>
> if.then: ; preds = %entry
>
> %0 = getelementptr inbounds %struct.X* %x, i64 0, i32 0, i64 0
>
> call void @llvm.lifetime.start(i64 33, i8* %0)
>
> call void @_ZN1X11doSomethingEv(%struct.X* %x)
>
> br label %label
>
> label: ; preds = %if.else.label_crit_edge, %if.then
>
> %.pre-phi = phi i8* [ %.pre, %if.else.label_crit_edge ], [ %0,
> %if.then ]
>
> call void @_Z3barR1X(%struct.X* dereferenceable(33) %x)
>
> call void @llvm.lifetime.end(i64 33, i8* %.pre-phi)
>
> br label %if.end3
>
> if.else: ; preds = %entry
>
> tail call void @_Z3bazv()
>
> %cmp1 = icmp eq i32 %i, 0
>
> br i1 %cmp1, label %if.else.label_crit_edge, label %if.end3
>
> if.else.label_crit_edge: ; preds = %if.else
>
> %.pre = getelementptr inbounds %struct.X* %x, i64 0, i32 0, i64 0
>
> br label %label
>
> if.end3: ; preds = %if.else, %label
>
> ret void
>
> }
>
> Note that the path thru if.else.label_crit_edge has no lifetime start.
>
> 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?
>
> With the clarification you made on the semantics, the above IR is
> correct, but could be improved when clang generates it: the
> label_crit_edge block should contain a lifetime.start for the alloca.
>
Another approach would be have LLVM prove that %x is uninitialized along
the path through if.else.label_crit_edge and then combine that with the
lifetime.start along the other path. This would require reasoning about
pointer escapes, but that's fairly tractable. It actually doesn't seem
unreasonable that GVN would get this case. Do you have a counter
example where an optimization is missed only when the lifetime.start is
not present?
More generally, are there specific optimizations which aren't kicking in
with the current placement strategy that you'd like to see?
Philip
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141105/f75ceb16/attachment.html>
More information about the llvm-dev
mailing list