[cfe-dev] Detecting (N)RVO
Kim Gräsman via cfe-dev
cfe-dev at lists.llvm.org
Wed Nov 4 02:41:24 PST 2015
Hi Richard,
Thanks, good info!
On Tue, Nov 3, 2015 at 10:51 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> On Tue, Nov 3, 2015 at 1:34 PM, Kim Gräsman <cfe-dev at lists.llvm.org> wrote:
> >
>> > 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 figured as much, makes sense, thanks!
>> 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.
OK, so IR generation can basically choose to make a copy even if
Sema/CodeGen has marked something as eligible for copy elision? Does
this interact with other optimizations?
> 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.
Cool, that's a nice development! This makes it possible to reason more
formally about when elision will happen.
My attribute-guided warning was intended more for user guidance. A
function marked as `requires_rvo` will be able to maintain that
property even if someone changes the code in a way that RVO can't
happen, e.g. from
[[clang::requires_rvo]]
std::string f() {
// copy elision
return std::string("Hello world");
}
to
[[clang::requires_rvo]]
std::string f(int v) {
std::string a = "Hello world", b = "Farewell to arms";
if (v < 20)
return b;
return a;
}
(assuming the latter disables NRVO, maybe it doesn't?)
> 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.
This looks easier to implement, but less useful for the case I
presented above. I'm worried about code that assumes RVO is working,
but where user changes suddenly render the compiler unable to deliver.
I generally trust the compiler to do the right thing.
A per-variable attribute would be more of a guide to the compiler to
make the NRVO analysis user-directed, right?
> (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.)
I think that's the current behavior, you and Nick Lewycky seem to have
fixed that in:
https://github.com/llvm-mirror/clang/commit/130d63a029bc588cb61a6aaea2db6b9ed4c5cc56
Thanks,
- Kim
More information about the cfe-dev
mailing list