<div dir="ltr">This specific testcase shows 2 problems:<div> - unamed variables are not handled the same way than named variables</div><div> - if using a named temporary instead; the object size is the second problem</div>
<div><br></div><div>Cheers,</div><div>--</div><div>Arnaud</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 25, 2014 at 12:58 PM, Hal Finkel <span dir="ltr"><<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="">----- Original Message -----<br>
> From: "David Blaikie" <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>><br>
> To: "Jiangning Liu" <<a href="mailto:liujiangning1@gmail.com">liujiangning1@gmail.com</a>><br>
> Cc: "cfe-dev Developers" <<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a>><br>
> Sent: Wednesday, June 25, 2014 1:14:16 AM<br>
> Subject: Re: [cfe-dev] About NRVO (named return value optimization)<br>
><br>
> This isn't related to NRVO - as the name suggests, NRVO is about<br>
> named<br>
> return values. The example you gave has no return values and no named<br>
> values.<br>
><br>
> The optimization necessary here is stack reuse, which classically<br>
> LLVM/Clang haven't done a great job on. I'm not sure of the precise<br>
> details of the current state, but there have been some efforts to<br>
> make<br>
> it better.<br>
<br>
</div>There is now an enabled-by-default stack coloring optimization (and has been for a while now); but Jiangning's comment that our lack of interprocedural alias analysis might be defeating it here is plausible.<br>

<div class=""><br>
><br>
> One part of that is the lifetime intrinsics (<br>
> <a href="http://llvm.org/docs/LangRef.html#memory-use-markers" target="_blank">http://llvm.org/docs/LangRef.html#memory-use-markers</a> ) which would<br>
> allow the backend to know that the stack memory used by the first<br>
> temporary is dead before the first use of the stack memory for the<br>
> second temporary, and thus reuse the stack. I don't know what the<br>
> current state of the lifetime markers is (I guess we don't turn them<br>
> on by default? not sure whether they're brokne/inefficient/slow/not<br>
> valuable enough yet) and whether they're a viable way forward, but<br>
> someone thought so at some point.<br>
<br>
</div>As I recall, clang does generate lifetime markers by default (at least in some circumstances), they now work well, and this does seem like a good use case for them. I recommend investigating why this is not happening here. One thing to look at is in CodeGen/CGDecl.cpp:<br>

<br>
/// Should we use the LLVM lifetime intrinsics for the given local variable?<br>
static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D,<br>
                                     unsigned Size) {<br>
  // For now, only in optimized builds.<br>
  if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0)<br>
    return false;<br>
<br>
  // Limit the size of marked objects to 32 bytes. We don't want to increase<br>
  // compile time by marking tiny objects.<br>
  unsigned SizeThreshold = 32;<br>
<br>
  return Size > SizeThreshold;<br>
}<br>
<br>
Maybe the problem is that sizeof(X) < 32? If so, further testing of this limit's impact on compile time might be worthy of investigation.<br>
<br>
 -Hal<br>
<div class="HOEnZb"><div class="h5"><br>
><br>
> - David<br>
><br>
> On Tue, Jun 24, 2014 at 10:57 PM, Jiangning Liu<br>
> <<a href="mailto:liujiangning1@gmail.com">liujiangning1@gmail.com</a>> wrote:<br>
> > Hi,<br>
> ><br>
> > For the following small test case,<br>
> ><br>
> > // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o -<br>
> > %s |<br>
> > FileCheck %s<br>
> ><br>
> > // Test code generation for the named return value optimization.<br>
> > class X {<br>
> > public:<br>
> >   X();<br>
> > };<br>
> ><br>
> > void f(const X& x);<br>
> > void test10(bool b) {<br>
> >   f(X());<br>
> >   f(X());<br>
> > }<br>
> ><br>
> > we are generating the following LLVM IR with "<br>
> ><br>
> > %class.X = type { i8 }<br>
> ><br>
> > ; Function Attrs: nounwind<br>
> > define void @_Z6test10b(i1 zeroext %b) #0 {<br>
> > entry:<br>
> >   %ref.tmp = alloca %class.X, align 1<br>
> >   %ref.tmp1 = alloca %class.X, align 1<br>
> >   call void @_ZN1XC1Ev(%class.X* %ref.tmp) #2<br>
> >   call void @_Z1fRK1X(%class.X* nonnull %ref.tmp) #2<br>
> >   call void @_ZN1XC1Ev(%class.X* %ref.tmp1) #2<br>
> >   call void @_Z1fRK1X(%class.X* nonnull %ref.tmp1) #2<br>
> >   ret void<br>
> > }<br>
> ><br>
> > declare void @_Z1fRK1X(%class.X* nonnull) #1<br>
> > declare void @_ZN1XC1Ev(%class.X*) #1<br>
> ><br>
> > So my questions is should NRVO be able to know ref.tmp and ref.tmp1<br>
> > can be<br>
> > merged to be a single one? That is, I'm expecting the following<br>
> > LLVM IR code<br>
> > to be generated,<br>
> ><br>
> > define void @_Z6test10b(i1 zeroext %b) #0 {<br>
> > entry:<br>
> >   %ref.tmp = alloca %class.X, align 1<br>
> >   call void @_ZN1XC1Ev(%class.X* %ref.tmp) #2<br>
> >   call void @_Z1fRK1X(%class.X* nonnull %ref.tmp) #2<br>
> >   call void @_ZN1XC1Ev(%class.X* %ref.tmp) #2<br>
> >   call void @_Z1fRK1X(%class.X* nonnull %ref.tmp) #2<br>
> >   ret void<br>
> > }<br>
> ><br>
> > If we leave both ref.tmp and ref.tmp1 to LLVM IR, it seems to be<br>
> > hard for<br>
> > middle-end to combine them unless we demangle the function name<br>
> > _ZN1XC1Ev to<br>
> > know it is a C++ constructor and do more alias analysis.<br>
> ><br>
> > Any idea?<br>
> ><br>
> > Thanks,<br>
> > -Jiangning<br>
> ><br>
> > _______________________________________________<br>
> > cfe-dev mailing list<br>
> > <a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
> > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
> ><br>
> _______________________________________________<br>
> cfe-dev mailing list<br>
> <a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
><br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
Hal Finkel<br>
Assistant Computational Scientist<br>
Leadership Computing Facility<br>
Argonne National Laboratory<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br></div>