[cfe-commits] r93412 - in /cfe/trunk/lib/CodeGen: CGVtable.cpp CGVtable.h

Anders Carlsson andersca at mac.com
Wed Jan 13 18:29:08 PST 2010


Author: andersca
Date: Wed Jan 13 20:29:07 2010
New Revision: 93412

URL: http://llvm.org/viewvc/llvm-project?rev=93412&view=rev
Log:
Store the address points for constructor vtables directly in the VTT builder, because that's the only time they're needed.

Modified:
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/lib/CodeGen/CGVtable.h

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=93412&r1=93411&r2=93412&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Wed Jan 13 20:29:07 2010
@@ -160,6 +160,9 @@
   // vtable for use in computing the initializers for the VTT.
   llvm::DenseMap<CtorVtable_t, int64_t> &subAddressPoints;
 
+  /// AddressPoints - Address points for this vtable.
+  CGVtableInfo::AddressPointsMapTy& AddressPoints;
+  
   typedef CXXRecordDecl::method_iterator method_iter;
   const uint32_t LLVMPointerWidth;
   Index_t extra;
@@ -192,13 +195,15 @@
 public:
   VtableBuilder(const CXXRecordDecl *MostDerivedClass,
                 const CXXRecordDecl *l, uint64_t lo, CodeGenModule &cgm,
-                bool build)
+                bool build, CGVtableInfo::AddressPointsMapTy& AddressPoints)
     : BuildVtable(build), MostDerivedClass(MostDerivedClass), LayoutClass(l),
       LayoutOffset(lo), BLayout(cgm.getContext().getASTRecordLayout(l)),
       rtti(0), VMContext(cgm.getModule().getContext()),CGM(cgm),
       PureVirtualFn(0),
       subAddressPoints(AllocAddressPoint(cgm, l, MostDerivedClass)),
-      LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) {
+      AddressPoints(AddressPoints),
+      LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0))
+      {
     Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
     if (BuildVtable) {
       QualType ClassType = CGM.getContext().getTagDeclType(MostDerivedClass);
@@ -461,6 +466,7 @@
               RD->getNameAsCString(), Class->getNameAsCString(),
               LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint));
     subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint;
+    AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint;
 
     // Now also add the address point for all our primary bases.
     while (1) {
@@ -477,6 +483,7 @@
                 RD->getNameAsCString(), Class->getNameAsCString(),
                 LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint));
       subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint;
+      AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint;
     }
   }
 
@@ -1088,7 +1095,8 @@
   if (!SavedAdjustmentRecords.insert(RD).second)
     return 0;
 
-  VtableBuilder b(RD, RD, 0, CGM, false);
+  AddressPointsMapTy AddressPoints;
+  VtableBuilder b(RD, RD, 0, CGM, false, AddressPoints);
   D1(printf("vtable %s\n", RD->getNameAsCString()));
   b.GenerateVtableForBase(RD);
   b.GenerateVtableForVBases(RD);
@@ -1116,7 +1124,8 @@
   
   // FIXME: This seems expensive.  Can we do a partial job to get
   // just this data.
-  VtableBuilder b(RD, RD, 0, CGM, false);
+  AddressPointsMapTy AddressPoints;
+  VtableBuilder b(RD, RD, 0, CGM, false, AddressPoints);
   D1(printf("vtable %s\n", RD->getNameAsCString()));
   b.GenerateVtableForBase(RD);
   b.GenerateVtableForVBases(RD);
@@ -1146,7 +1155,8 @@
 CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
                              bool GenerateDefinition,
                              const CXXRecordDecl *LayoutClass,
-                             const CXXRecordDecl *RD, uint64_t Offset) {
+                             const CXXRecordDecl *RD, uint64_t Offset,
+                             AddressPointsMapTy& AddressPoints) {
   llvm::SmallString<256> OutName;
   if (LayoutClass != RD)
     CGM.getMangleContext().mangleCXXCtorVtable(LayoutClass, Offset / 8, 
@@ -1158,7 +1168,8 @@
   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
   if (GV == 0 || CGM.getVtableInfo().AddressPoints[LayoutClass] == 0 || 
       GV->isDeclaration()) {
-    VtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition);
+    VtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition,
+                    AddressPoints);
 
     D1(printf("vtable %s\n", RD->getNameAsCString()));
     // First comes the vtables for all the non-virtual bases...
@@ -1213,6 +1224,42 @@
   llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies;
   
   bool GenerateDefinition;
+
+  llvm::DenseMap<BaseSubobject, llvm::Constant *> CtorVtables;
+  llvm::DenseMap<std::pair<const CXXRecordDecl *, BaseSubobject>, uint64_t> 
+    CtorVtableAddressPoints;
+  
+  llvm::Constant *getCtorVtable(const BaseSubobject &Base) {
+    if (!GenerateDefinition)
+      return 0;
+
+    llvm::Constant *&CtorVtable = CtorVtables[Base];
+    if (!CtorVtable) {
+      // Build the vtable.
+      CGVtableInfo::CtorVtableInfo Info
+        = CGM.getVtableInfo().getCtorVtable(Class, Base);
+      
+      CtorVtable = Info.Vtable;
+      
+      // Add the address points for this base.
+      for (CGVtableInfo::AddressPointsMapTy::const_iterator I =
+           Info.AddressPoints.begin(), E = Info.AddressPoints.end(); 
+           I != E; ++I) {
+        uint64_t &AddressPoint = 
+          CtorVtableAddressPoints[std::make_pair(Base.getBase(), I->first)];
+        
+        // Check if we already have the address points for this base.
+        if (AddressPoint)
+          break;
+
+        // Otherwise, insert it.
+        AddressPoint = I->second;
+      }      
+    }
+    
+    return CtorVtable;
+  }
+  
   
   /// BuildVtablePtr - Build up a referene to the given secondary vtable
   llvm::Constant *BuildVtablePtr(llvm::Constant *Vtable,
@@ -1277,7 +1324,7 @@
             BuildVtablePtr(vtbl, VtblClass, RD, Offset) : 0;
         else {
           init = GenerateDefinition ?
-            CGM.getVtableInfo().getCtorVtable(Class, Base, BaseOffset) : 0;
+            getCtorVtable(BaseSubobject(Base, BaseOffset)) : 0;
           
           subvtbl = init;
           subVtblClass = Base;
@@ -1306,7 +1353,7 @@
       VtableClass = Class;
     } else {
       Vtable = GenerateDefinition ? 
-        CGM.getVtableInfo().getCtorVtable(Class, RD, Offset) : 0;
+        getCtorVtable(BaseSubobject(RD, Offset)) : 0;
       VtableClass = RD;
     }
     
@@ -1444,28 +1491,37 @@
     return;
   }
   
-  Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0);
+  AddressPointsMapTy AddressPoints;
+  Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
+                          AddressPoints);
   GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);  
 }
 
 llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
   llvm::GlobalVariable *Vtable = Vtables.lookup(RD);
   
-  if (!Vtable)
+  if (!Vtable) {
+    AddressPointsMapTy AddressPoints;
     Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage, 
-                            /*GenerateDefinition=*/false, RD, RD, 0);
+                            /*GenerateDefinition=*/false, RD, RD, 0,
+                            AddressPoints);
+  }
 
   return Vtable;
 }
 
-llvm::GlobalVariable *
-CGVtableInfo::getCtorVtable(const CXXRecordDecl *LayoutClass,
-                            const CXXRecordDecl *RD, uint64_t Offset) {
-  return GenerateVtable(llvm::GlobalValue::InternalLinkage, 
-                        /*GenerateDefinition=*/true,
-                        LayoutClass, RD, Offset);
+CGVtableInfo::CtorVtableInfo 
+CGVtableInfo::getCtorVtable(const CXXRecordDecl *RD, 
+                            const BaseSubobject &Base) {
+  CtorVtableInfo Info;
+  
+  Info.Vtable = GenerateVtable(llvm::GlobalValue::InternalLinkage,
+                               /*GenerateDefinition=*/true,
+                               RD, Base.getBase(), Base.getBaseOffset(),
+                               Info.AddressPoints);
+  return Info;
 }
-
+ 
 llvm::GlobalVariable *CGVtableInfo::getVTT(const CXXRecordDecl *RD) {
   return GenerateVTT(llvm::GlobalValue::ExternalLinkage, 
                      /*GenerateDefinition=*/false, RD);

Modified: cfe/trunk/lib/CodeGen/CGVtable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.h?rev=93412&r1=93411&r2=93412&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.h (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.h Wed Jan 13 20:29:07 2010
@@ -116,6 +116,11 @@
   }
 };
 
+// It's OK to treat BaseSubobject as a POD type.
+template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
+  static const bool value = true;
+};
+
 }
 
 namespace clang {
@@ -131,6 +136,8 @@
   typedef llvm::DenseMap<const CXXRecordDecl *, AddrSubMap_t *> AddrMap_t;
   llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> AddressPoints;
 
+  typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
+
 private:
   CodeGenModule &CGM;
 
@@ -178,7 +185,8 @@
   llvm::GlobalVariable *
   GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
                  bool GenerateDefinition, const CXXRecordDecl *LayoutClass, 
-                 const CXXRecordDecl *RD, uint64_t Offset);
+                 const CXXRecordDecl *RD, uint64_t Offset,
+                 AddressPointsMapTy& AddressPoints);
 
   llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
                                     bool GenerateDefinition,
@@ -218,15 +226,26 @@
   uint64_t getVtableAddressPoint(const CXXRecordDecl *RD);
   
   llvm::GlobalVariable *getVtable(const CXXRecordDecl *RD);
-  llvm::GlobalVariable *getCtorVtable(const CXXRecordDecl *RD,
-                                      const CXXRecordDecl *Class, 
-                                      uint64_t Offset);
+  
+  /// CtorVtableInfo - Information about a constructor vtable.
+  struct CtorVtableInfo {
+    /// Vtable - The vtable itself.
+    llvm::GlobalVariable *Vtable;
+  
+    /// AddressPoints - The address points in this constructor vtable.
+    AddressPointsMapTy AddressPoints;
+    
+    CtorVtableInfo() : Vtable(0) { }
+  };
+  
+  CtorVtableInfo getCtorVtable(const CXXRecordDecl *RD, 
+                               const BaseSubobject &Base);
   
   llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
   
   void MaybeEmitVtable(GlobalDecl GD);
 };
 
-}
-}
+} // end namespace CodeGen
+} // end namespace clang
 #endif





More information about the cfe-commits mailing list