[cfe-dev] Detecting (N)RVO

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Tue Nov 3 13:51:59 PST 2015


On Tue, Nov 3, 2015 at 1:34 PM, Kim Gräsman <cfe-dev at lists.llvm.org> wrote:

> On Tue, Nov 3, 2015 at 9:49 PM, Kim Gräsman <kim.grasman at gmail.com> wrote:
> >
> > I'm experimenting with a patch to let users mark functions with an
> attribute
> >
> > [[clang::requires_rvo]]
> > std::string f() {
> >     return std::string("Hello world");
> > }
> >
> > and in the presence of this attribute, warn if (N)RVO didn't happen.
> > This would be useful to prevent small code changes from disabling RVO
> > in critical paths.
> >
> > I have the attribute in place, and I've seen that I can check if it
> > exists with FunctionDecl::hasAttr. But finding where NRVO is actually
> > decided for a given function turns out to be more difficult...
> >
> > SemaInit appears to do something for NRVO/copy elision more generally
> > when constructors are called. But it only marks the CXXConstructExpr
> > as elidable, as far as I can see, and I'm not sure if this is used to
> > effect RVO later (I found something in
> > CodeGenFunction::EmitCXXConstructExpr, but there seems to be more
> > playing into the decision of whether to construct at caller or not.
> >
> > Also, I'm not sure if my terminology is right; I haven't found any
> > references to RVO-sans-the-N, is that refered to as copy elision? NRVO
> > only seems to address VarDecls and their lifetime.
>

RVO is a special case of copy elision, where the elided copy is
initializing the returned object.


> I guess the more direct question is: is there a single place where I
> can detect if copy elision/NRVO/RVO has happened or will definitely
> happen for the return value of a function?
>

Not really, no, our current model marks the places where it's permissible
then leaves the details up to IR generation.


> If not, I guess I'm thinking about the problem the wrong way; is there
> a more correct way to ask this question?


P0135R0 was accepted by C++'s evolution working group in Kona, so RVO is
likely to be guaranteed by the language semantics in C++17 onwards.

For NRVO, I think the best model would be an attribute on the variable:

  std::string f() {
    [[clang::returned]] std::string x = "Hello world";
    return x;
  }

... which would give an error if we can't apply NRVO to it.

(Also of note: clang's NRVO heuristic is currently quite weak, and
improving it would seem like a good idea. In principle, we should be able
to put a variable into the return slot in all cases where all
return-statements within its scope return it.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20151103/55c28e4e/attachment.html>


More information about the cfe-dev mailing list