diff options
author | Taiju Tsuiki <tzik@google.com> | 2018-05-30 03:53:16 +0000 |
---|---|---|
committer | Taiju Tsuiki <tzik@google.com> | 2018-05-30 03:53:16 +0000 |
commit | 91f75751594865638d42325edebf781bbb6c8293 (patch) | |
tree | f173eff5604e3e5989737ef8dbc12794e2e1a9ef /lib/Sema/SemaStmt.cpp | |
parent | 7a3b3665c7782ff7a4a7468a60201227587b4774 (diff) | |
download | clang-91f75751594865638d42325edebf781bbb6c8293.tar.gz |
Update NRVO logic to support early return
Summary:
The previous implementation misses an opportunity to apply NRVO (Named Return Value
Optimization) below. That discourages user to write early return code.
```
struct Foo {};
Foo f(bool b) {
if (b)
return Foo();
Foo oo;
return oo;
}
```
That is, we can/should apply RVO for a local variable if:
* It's directly returned by at least one return statement.
* And, all reachable return statements in its scope returns the variable directly.
While, the previous implementation disables the RVO in a scope if there are multiple return
statements that refers different variables.
On the new algorithm, local variables are in NRVO_Candidate state at first, and a return
statement changes it to NRVO_Disabled for all visible variables but the return statement refers.
Then, at the end of the function AST traversal, NRVO is enabled for variables in NRVO_Candidate
state and refers from at least one return statement.
Reviewers: rsmith
Reviewed By: rsmith
Subscribers: xbolva00, Quuxplusone, arthur.j.odwyer, cfe-commits
Differential Revision: https://reviews.llvm.org/D47067
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@333500 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index ccf25ee9eb..04f5114510 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -3455,12 +3455,9 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, ExpressionEvaluationContext::DiscardedStatement) return R; - if (VarDecl *VD = - const_cast<VarDecl*>(cast<ReturnStmt>(R.get())->getNRVOCandidate())) { - CurScope->addNRVOCandidate(VD); - } else { - CurScope->setNoNRVO(); - } + VarDecl *VD = + const_cast<VarDecl*>(cast<ReturnStmt>(R.get())->getNRVOCandidate()); + CurScope->setNRVOCandidate(VD); CheckJumpOutOfSEHFinally(*this, ReturnLoc, *CurScope->getFnParent()); |