diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2014-05-03 00:41:18 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2014-05-03 00:41:18 +0000 |
commit | d78f92fbb26b388b30192dfa88fd614db35dbbad (patch) | |
tree | 3e07496fe683abf375a92778a2229b38ba7cfd55 /clang/lib/Sema/SemaDecl.cpp | |
parent | e39ee215519e6189d56b345e21f2cee2ffeed3ab (diff) | |
download | bcm5719-llvm-d78f92fbb26b388b30192dfa88fd614db35dbbad.tar.gz bcm5719-llvm-d78f92fbb26b388b30192dfa88fd614db35dbbad.zip |
Rewrite NRVO determination. Track NRVO candidates on the parser Scope and apply the NRVO candidate flag to all possible NRVO candidates here, and remove the flags in computeNRVO or upon template instantiation. A variable now has NRVO applied if and only if every return statement in that scope returns that variable. This is nearly optimal.
Performs NRVO roughly 7% more often in a bootstrap build of clang. Patch co-authored by Richard Smith.
llvm-svn: 207890
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 25 |
1 files changed, 8 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 283b41683d1..68e4ad58929 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1373,6 +1373,8 @@ static void CheckPoppedLabel(LabelDecl *L, Sema &S) { } void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { + S->mergeNRVOIntoParent(); + if (S->decl_empty()) return; assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) && "Scope shouldn't contain decls!"); @@ -9797,28 +9799,17 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { /// use the named return value optimization. /// /// This function applies a very simplistic algorithm for NRVO: if every return -/// statement in the function has the same NRVO candidate, that candidate is -/// the NRVO variable. -/// -/// FIXME: Employ a smarter algorithm that accounts for multiple return -/// statements and the lifetimes of the NRVO candidates. We should be able to -/// find a maximal set of NRVO variables. +/// statement in the scope of a variable has the same NRVO candidate, that +/// candidate is an NRVO variable. void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { ReturnStmt **Returns = Scope->Returns.data(); - const VarDecl *NRVOCandidate = 0; for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) { - if (!Returns[I]->getNRVOCandidate()) - return; - - if (!NRVOCandidate) - NRVOCandidate = Returns[I]->getNRVOCandidate(); - else if (NRVOCandidate != Returns[I]->getNRVOCandidate()) - return; + if (const VarDecl *NRVOCandidate = Returns[I]->getNRVOCandidate()) { + if (!NRVOCandidate->isNRVOVariable()) + Returns[I]->setNRVOCandidate(nullptr); + } } - - if (NRVOCandidate) - const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true); } bool Sema::canDelayFunctionBody(const Declarator &D) { |