]> granicus.if.org Git - clang/commitdiff
Implement the Named Return Value Optimization (NRVO) for blocks.
authorDouglas Gregor <dgregor@apple.com>
Tue, 6 Sep 2011 20:46:03 +0000 (20:46 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 6 Sep 2011 20:46:03 +0000 (20:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139178 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaExpr.cpp
test/CodeGenObjCXX/nrvo.mm

index 814fd27469d4135caf474595b4f9c7725a3edf08..1437469aeb8d613df3ef517d29fa971378715f3a 100644 (file)
@@ -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);
 
index 6a205786d6293747ca1e79705eb46ab24060fbc2..f8b0af49db546952fe5c196840e98f6ce7ab652f 100644 (file)
@@ -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<CXXConstructorDecl>(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);
index ecc756f6a82abda098ab9ca9d5db3a082a9de37c..1954ae74d5ce4cbcd97b337fcec7282843f69b62 100644 (file)
@@ -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);
index d28d54addb5655591cabb063f72c34f62573820f..3cf49553e8c33ec942193154d3070ac51897d469 100644 (file)
@@ -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 / <rdar://problem/10050178>
 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;
+  }() ;
+}
+