From f8b7f7177d722d254e255a7754446148ef514789 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 6 Sep 2011 20:46:03 +0000 Subject: [PATCH] Implement the Named Return Value Optimization (NRVO) for blocks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139178 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 1 + lib/Sema/SemaDecl.cpp | 6 +++--- lib/Sema/SemaExpr.cpp | 2 ++ test/CodeGenObjCXX/nrvo.mm | 13 ++++++++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 814fd27469..1437469aeb 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1056,6 +1056,7 @@ public: Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D); void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); + void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope); Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body); Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6a205786d6..f8b0af49db 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6626,7 +6626,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { /// 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. -static void ComputeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { +void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { ReturnStmt **Returns = Scope->Returns.data(); const VarDecl *NRVOCandidate = 0; @@ -6687,7 +6687,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (CXXConstructorDecl *Constructor = dyn_cast(FD)) MarkVTableUsed(FD->getLocation(), Constructor->getParent()); - ComputeNRVO(Body, getCurFunction()); + computeNRVO(Body, getCurFunction()); } assert(FD == getCurFunctionDecl() && "Function parsing confused"); @@ -6702,7 +6702,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, MD->getResultType(), MD); if (Body) - ComputeNRVO(Body, getCurFunction()); + computeNRVO(Body, getCurFunction()); } if (ObjCShouldCallSuperDealloc) { Diag(MD->getLocEnd(), diag::warn_objc_missing_super_dealloc); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ecc756f6a8..1954ae74d5 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -8755,6 +8755,8 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, getCurFunction()->setHasBranchProtectedScope(); } + computeNRVO(Body, getCurBlock()); + BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy); const AnalysisBasedWarnings::Policy &WP = AnalysisWarnings.getDefaultPolicy(); PopFunctionOrBlockScope(&WP, Result->getBlockDecl(), Result); diff --git a/test/CodeGenObjCXX/nrvo.mm b/test/CodeGenObjCXX/nrvo.mm index d28d54addb..3cf49553e8 100644 --- a/test/CodeGenObjCXX/nrvo.mm +++ b/test/CodeGenObjCXX/nrvo.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s -O1 -triple x86_64-apple-darwin10.0.0 | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - -fblocks %s -O1 -triple x86_64-apple-darwin10.0.0 | FileCheck %s // PR10835 / struct X { @@ -19,3 +19,14 @@ struct X { return x; } @end + +X blocksNRVO() { + return ^{ + // CHECK: define internal void @__blocksNRVO_block_invoke_0 + X x; + // CHECK: tail call void @_ZN1XC1Ev + // CHECK-NEXT: ret void + return x; + }() ; +} + -- 2.40.0