[LLVMdev] lifetime.start/end clarification

Arnaud A. de Grandmaison arnaud.degrandmaison at arm.com
Tue Nov 4 08:39:45 PST 2014



> -----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.

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. 

> 
> >
> >
> > 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








More information about the llvm-dev mailing list