]> granicus.if.org Git - clang/commitdiff
IRgen optimization: cache the value of 'this' and 'vtt' instead of
authorJohn McCall <rjmccall@apple.com>
Tue, 16 Feb 2010 22:04:33 +0000 (22:04 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 16 Feb 2010 22:04:33 +0000 (22:04 +0000)
repeatedly reloading from an alloca.  We still need to create the alloca
for debug info purposes (although we currently create it in all cases
because of some abstraction boundaries that're hard to break down).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96403 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CGClass.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h

index 28c4c6b4b57b37ee20b83b1efd9335a189ac6ead..c4c52aac034af3e39b04517cc83fbf25dac2847e 100644 (file)
@@ -28,18 +28,6 @@ using namespace CodeGen;
 
 
 
-llvm::Value *CodeGenFunction::LoadCXXThis() {
-  assert(isa<CXXMethodDecl>(CurFuncDecl) &&
-         "Must be in a C++ member function decl to load 'this'");
-  assert(cast<CXXMethodDecl>(CurFuncDecl)->isInstance() &&
-         "Must be in a C++ member function decl to load 'this'");
-
-  // FIXME: What if we're inside a block?
-  // ans: See how CodeGenFunction::LoadObjCSelf() uses
-  // CodeGenFunction::BlockForwardSelf() for how to do this.
-  return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
-}
-
 void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
   EmitGlobal(GlobalDecl(D, Ctor_Complete));
   EmitGlobal(GlobalDecl(D, Ctor_Base));
index fa5a47f31564940f25e959c0c3d00506d252b012..d9051675ba011ae0c7800356591cf6eb7900fbcb 100644 (file)
@@ -1405,11 +1405,3 @@ void CodeGenFunction::InitializeVtablePtrsRecursive(
   // Store address point
   Builder.CreateStore(VtableAddressPoint, VtableField);
 }
-
-llvm::Value *CodeGenFunction::LoadCXXVTT() {
-  assert((isa<CXXConstructorDecl>(CurFuncDecl) ||
-          isa<CXXDestructorDecl>(CurFuncDecl)) &&
-         "Must be in a C++ ctor or dtor to load the vtt parameter");
-
-  return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
-}
index febffc96973e4c4c592b0f7b490087080daeb794..d803a05aa95e63eae608274d14ca96faeba95596 100644 (file)
@@ -30,7 +30,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
     Builder(cgm.getModule().getContext()),
     DebugInfo(0), IndirectBranch(0),
     SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
-    CXXThisDecl(0), CXXVTTDecl(0),
+    CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
     ConditionalBranchLevel(0), TerminateHandler(0), TrapBB(0),
     UniqueAggrDestructorCount(0) {
   LLVMIntTy = ConvertType(getContext().IntTy);
@@ -225,6 +225,11 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
   EmitStartEHSpec(CurCodeDecl);
   EmitFunctionProlog(*CurFnInfo, CurFn, Args);
 
+  if (CXXThisDecl)
+    CXXThisValue = Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this");
+  if (CXXVTTDecl)
+    CXXVTTValue = Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
+
   // If any of the arguments have a variably modified type, make sure to
   // emit the type size.
   for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
@@ -252,7 +257,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
       // Create the implicit 'this' decl.
       // FIXME: I'm not entirely sure I like using a fake decl just for code
       // generation. Maybe we can come up with a better way?
-      CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0, SourceLocation(),
+      CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0,
+                                              FD->getLocation(),
                                               &getContext().Idents.get("this"),
                                               MD->getThisType(getContext()));
       Args.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType()));
@@ -262,7 +268,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
         // FIXME: The comment about using a fake decl above applies here too.
         QualType T = getContext().getPointerType(getContext().VoidPtrTy);
         CXXVTTDecl = 
-          ImplicitParamDecl::Create(getContext(), 0, SourceLocation(),
+          ImplicitParamDecl::Create(getContext(), 0, FD->getLocation(),
                                     &getContext().Idents.get("vtt"), T);
         Args.push_back(std::make_pair(CXXVTTDecl, CXXVTTDecl->getType()));
       }
index a4db556d397c27f949589af2483a3d6463029538..a694b894df61bbac0541a40cd80e344306eceac2 100644 (file)
@@ -382,11 +382,13 @@ private:
   /// CXXThisDecl - When generating code for a C++ member function,
   /// this will hold the implicit 'this' declaration.
   ImplicitParamDecl *CXXThisDecl;
+  llvm::Value *CXXThisValue;
 
   /// CXXVTTDecl - When generating code for a base object constructor or
   /// base object destructor with virtual bases, this will hold the implicit
   /// VTT parameter.
   ImplicitParamDecl *CXXVTTDecl;
+  llvm::Value *CXXVTTValue;
   
   /// CXXLiveTemporaryInfo - Holds information about a live C++ temporary.
   struct CXXLiveTemporaryInfo {
@@ -745,11 +747,17 @@ public:
 
   /// LoadCXXThis - Load the value of 'this'. This function is only valid while
   /// generating code for an C++ member function.
-  llvm::Value *LoadCXXThis();
+  llvm::Value *LoadCXXThis() {
+    assert(CXXThisValue && "no 'this' value for this function");
+    return CXXThisValue;
+  }
 
   /// LoadCXXVTT - Load the VTT parameter to base constructors/destructors have
   /// virtual bases.
-  llvm::Value *LoadCXXVTT();
+  llvm::Value *LoadCXXVTT() {
+    assert(CXXVTTValue && "no VTT value for this function");
+    return CXXVTTValue;
+  }
 
   /// GetAddressOfBaseOfCompleteClass - Convert the given pointer to a
   /// complete class down to one of its virtual bases.