[LLVMdev] lifetime.start/end clarification

Hal Finkel hfinkel at anl.gov
Tue Nov 4 08:54:39 PST 2014


----- Original Message -----
> From: "Arnaud A. de Grandmaison" <arnaud.degrandmaison at arm.com>
> To: "Hal Finkel" <hfinkel at anl.gov>
> Cc: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu>
> Sent: Tuesday, November 4, 2014 10:39:45 AM
> Subject: RE: [LLVMdev] lifetime.start/end clarification
> 
> 
> 
> > -----Original Message-----
> > From: Hal Finkel [mailto:hfinkel at anl.gov]
> > Sent: 04 November 2014 17:16
> > To: Arnaud De Grandmaison
> > Cc: LLVM Developers Mailing List
> > Subject: Re: [LLVMdev] lifetime.start/end clarification
> > 
> > ----- Original Message -----
> > > From: "Arnaud A. de Grandmaison" <arnaud.degrandmaison at arm.com>
> > > To: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu>
> > > Sent: Tuesday, November 4, 2014 5:59:28 AM
> > > Subject: [LLVMdev] lifetime.start/end clarification
> > >
> > > The LRM
> > > (http://llvm.org/docs/LangRef.html#llvm-lifetime-start-intrinsic)
> > > essentially states that:
> > >
> > > - ptr is dead before a call to “lifetime.start size, ptr”
> > >
> > > - ptr is dead after a call to “lifetime.end size, ptr”
> > >
> > >
> > >
> > > This is all good and fine, and the expected use case is that all
> > > “lifetime.end size, ptr” markers are matched with a preceding
> > > “lifetime.start size, ptr” in the CFG.
> > >
> > >
> > >
> > > What is supposed to happen when a “lifetime.end size, ptr” is not
> > > matched with a “lifetime.start size, ptr” ? I think there are a
> > > few
> > > possible answers:
> > >
> > > - the memory area pointed to by ptr is assumed to be alive since
> > > function entry
> > >
> > > - the memory area pointed to by ptr is assumed to be dead since
> > > function entry, as it has not been marked alive
> > >
> > > - this is an unexpected situation
> > >
> > 
> > When you say "unmatched", do you mean not visible in any dominating
> > block? Assuming we realize that the lifetime begin could also be
> > inside a
> > function called by any of these dominating blocks (assuming the
> > pointer is an
> > argument or is captured prior to the call), it seems most logical
> > to say that the
> > ptr is alive (and invariant) from the function entry.
> 
> Yes, I meant not visible in any dominating block. I believe assuming
> the ptr is alive from the function entry is conservatively correct,
> but not optimal. In my testcase, a lifetime.start could be inserted
> in the crit_edge bb.

I think that the conservative behavior is what we want for the definition of the intrinsics themselves. Now if we can do better in some cases by deducing subset of the CFG where the allocation is actually used (either in the backend or by using some cleanup pass that adds them), that's fine.

> 
> Do we really want to handle cross-function stack lifetime analysis ?
> That's an interesting point. Until now, I supposed this all stayed
> inside the same function.

As currently defined, that's unavoidable. Philip, as I recall, ran into this recently. If you've not already done so, I recommend you read the recent thread on 'Optimization hints for "constant" loads'.

 -Hal

> 
> > 
> > >
> > >
> > > I think this ambiguity should be cleared in the LRM, because
> > > today’s
> > > implicit assumption
> > 
> > What is today's implicit assumption?
> 
> To be honest: I don't know. I have to dig it out of the stack
> coloring pass, which I think (but I may be wrong) is the only user
> of the lifetime markers.
> 
> > 
> > Thanks again,
> > Hal
> > 
> > > may be broken at any time.
> > >
> > >
> > >
> > > 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.
> > >
> > >
> > >
> > > Cheers,
> > >
> > > --
> > >
> > > Arnaud
> > >
> > >
> > > _______________________________________________
> > > 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
> 
> 
> 
> 
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory




More information about the llvm-dev mailing list