[cfe-commits] r140498 - in /cfe/trunk/lib/CodeGen: CGVTT.cpp CGVTables.h

Peter Collingbourne peter at pcc.me.uk
Sun Sep 25 18:56:06 PDT 2011


Author: pcc
Date: Sun Sep 25 20:56:06 2011
New Revision: 140498

URL: http://llvm.org/viewvc/llvm-project?rev=140498&view=rev
Log:
Make the VTTBuilder class independent of LLVM core

Modified:
    cfe/trunk/lib/CodeGen/CGVTT.cpp
    cfe/trunk/lib/CodeGen/CGVTables.h

Modified: cfe/trunk/lib/CodeGen/CGVTT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTT.cpp?rev=140498&r1=140497&r2=140498&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTT.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTT.cpp Sun Sep 25 20:56:06 2011
@@ -21,6 +21,44 @@
 
 namespace {
 
+class VTTVTable {
+  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
+  CharUnits BaseOffset;
+
+public:
+  VTTVTable() {}
+  VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
+    : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
+  VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
+    : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
+      BaseOffset(Base.getBaseOffset()) {}
+
+  const CXXRecordDecl *getBase() const {
+    return BaseAndIsVirtual.getPointer();
+  }
+
+  CharUnits getBaseOffset() const {
+    return BaseOffset;
+  }
+
+  bool isVirtual() const {
+    return BaseAndIsVirtual.getInt();
+  }
+
+  BaseSubobject getBaseSubobject() const {
+    return BaseSubobject(getBase(), getBaseOffset());
+  }
+};
+
+struct VTTComponent {
+  uint64_t VTableIndex;
+  BaseSubobject VTableBase;
+
+  VTTComponent() {}
+  VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
+    : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
+};
+
 /// VTT builder - Class for building VTT layout information.
 class VTTBuilder {
   
@@ -30,7 +68,12 @@
   /// vtable.
   const CXXRecordDecl *MostDerivedClass;
 
-  typedef SmallVector<llvm::Constant *, 64> VTTComponentsVectorTy;
+  typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
+  
+  /// VTTVTables - The VTT vtables.
+  VTTVTablesVectorTy VTTVTables;
+  
+  typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
   
   /// VTTComponents - The VTT components.
   VTTComponentsVectorTy VTTComponents;
@@ -54,25 +97,12 @@
   /// the VTT.
   bool GenerateDefinition;
 
-  /// The linkage to use for any construction vtables required by this VTT.
-  /// Only required if we're building a definition.
-  llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables;
-  
-  /// GetAddrOfVTable - Returns the address of the vtable for the base class in
-  /// the given vtable class.
-  ///
-  /// \param AddressPoints - If the returned vtable is a construction vtable,
-  /// this will hold the address points for it.
-  llvm::Constant *GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual,
-                                  AddressPointsMapTy& AddressPoints);
-
   /// AddVTablePointer - Add a vtable pointer to the VTT currently being built.
   ///
   /// \param AddressPoints - If the vtable is a construction vtable, this has
   /// the address points for it.
-  void AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
-                        const CXXRecordDecl *VTableClass,
-                        const AddressPointsMapTy& AddressPoints);
+  void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
+                        const CXXRecordDecl *VTableClass);
                         
   /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base 
   /// subobject.
@@ -88,9 +118,8 @@
   /// the address points for it.
   void LayoutSecondaryVirtualPointers(BaseSubobject Base, 
                                       bool BaseIsMorallyVirtual,
-                                      llvm::Constant *VTable,
+                                      uint64_t VTableIndex,
                                       const CXXRecordDecl *VTableClass,
-                                      const AddressPointsMapTy& AddressPoints,
                                       VisitedVirtualBasesSetTy &VBases);
   
   /// LayoutSecondaryVirtualPointers - Lay out the secondary virtual pointers
@@ -99,8 +128,7 @@
   /// \param AddressPoints - If the vtable is a construction vtable, this has
   /// the address points for it.
   void LayoutSecondaryVirtualPointers(BaseSubobject Base, 
-                                      llvm::Constant *VTable,
-                                      const AddressPointsMapTy& AddressPoints);
+                                      uint64_t VTableIndex);
 
   /// LayoutVirtualVTTs - Lay out the VTTs for the virtual base classes of the
   /// given record decl.
@@ -113,15 +141,18 @@
   
 public:
   VTTBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerivedClass,
-             bool GenerateDefinition,
-             llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables
-               = (llvm::GlobalVariable::LinkageTypes) -1);
+             bool GenerateDefinition);
 
   // getVTTComponents - Returns a reference to the VTT components.
   const VTTComponentsVectorTy &getVTTComponents() const {
     return VTTComponents;
   }
   
+  // getVTTVTables - Returns a reference to the VTT vtables.
+  const VTTVTablesVectorTy &getVTTVTables() const {
+    return VTTVTables;
+  }
+  
   /// getSubVTTIndicies - Returns a reference to the sub-VTT indices.
   const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
     return SubVTTIndicies;
@@ -138,43 +169,36 @@
 
 VTTBuilder::VTTBuilder(CodeGenModule &CGM,
                        const CXXRecordDecl *MostDerivedClass,
-                       bool GenerateDefinition,
-          llvm::GlobalVariable::LinkageTypes LinkageForConstructionVTables)
+                       bool GenerateDefinition)
   : CGM(CGM), MostDerivedClass(MostDerivedClass), 
   MostDerivedClassLayout(CGM.getContext().getASTRecordLayout(MostDerivedClass)),
-    GenerateDefinition(GenerateDefinition),
-    LinkageForConstructionVTables(LinkageForConstructionVTables) {
-  assert(!GenerateDefinition ||
-         LinkageForConstructionVTables
-           != (llvm::GlobalVariable::LinkageTypes) -1);
-    
+    GenerateDefinition(GenerateDefinition) {
   // Lay out this VTT.
   LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 
             /*BaseIsVirtual=*/false);
 }
 
-llvm::Constant *
-VTTBuilder::GetAddrOfVTable(BaseSubobject Base, bool BaseIsVirtual, 
-                            AddressPointsMapTy& AddressPoints) {
-  if (!GenerateDefinition)
-    return 0;
-  
-  if (Base.getBase() == MostDerivedClass) {
-    assert(Base.getBaseOffset().isZero() &&
+llvm::Constant *GetAddrOfVTTVTable(CodeGenVTables &CGVT,
+                                   const CXXRecordDecl *MostDerivedClass,
+                                   const VTTVTable &VTable,
+                                   llvm::GlobalVariable::LinkageTypes Linkage,
+                       llvm::DenseMap<BaseSubobject, uint64_t> &AddressPoints) {
+  if (VTable.getBase() == MostDerivedClass) {
+    assert(VTable.getBaseOffset().isZero() &&
            "Most derived class vtable must have a zero offset!");
     // This is a regular vtable.
-    return CGM.getVTables().GetAddrOfVTable(MostDerivedClass);
+    return CGVT.GetAddrOfVTable(MostDerivedClass);
   }
   
-  return CGM.getVTables().GenerateConstructionVTable(MostDerivedClass, 
-                                                     Base, BaseIsVirtual,
-                                           LinkageForConstructionVTables,
-                                                     AddressPoints);
+  return CGVT.GenerateConstructionVTable(MostDerivedClass, 
+                                         VTable.getBaseSubobject(),
+                                         VTable.isVirtual(),
+                                         Linkage,
+                                         AddressPoints);
 }
 
-void VTTBuilder::AddVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
-                                  const CXXRecordDecl *VTableClass,
-                                  const AddressPointsMapTy& AddressPoints) {
+void VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
+                                  const CXXRecordDecl *VTableClass) {
   // Store the vtable pointer index if we're generating the primary VTT.
   if (VTableClass == MostDerivedClass) {
     assert(!SecondaryVirtualPointerIndices.count(Base) &&
@@ -183,37 +207,11 @@
   }
 
   if (!GenerateDefinition) {
-    VTTComponents.push_back(0);
+    VTTComponents.push_back(VTTComponent());
     return;
   }
 
-  uint64_t AddressPoint;
-  if (VTableClass != MostDerivedClass) {
-    // The vtable is a construction vtable, look in the construction vtable
-    // address points.
-    AddressPoint = AddressPoints.lookup(Base);
-    assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
-  } else {
-    // Just get the address point for the regular vtable.
-    AddressPoint = CGM.getVTables().getAddressPoint(Base, VTableClass);
-    assert(AddressPoint != 0 && "Did not find vtable address point!");
-  }
-
-  if (!AddressPoint) AddressPoint = 0;
-  
-  llvm::Value *Idxs[] = {
-    llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0),
-    llvm::ConstantInt::get(llvm::Type::getInt64Ty(CGM.getLLVMContext()), 
-                           AddressPoint)
-  };
-  
-  llvm::Constant *Init = 
-    llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs);
-  
-  llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
-  Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
-  
-  VTTComponents.push_back(Init);
+  VTTComponents.push_back(VTTComponent(VTableIndex, Base));
 }
 
 void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
@@ -240,11 +238,10 @@
 
 void
 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 
-                                        bool BaseIsMorallyVirtual,
-                                        llvm::Constant *VTable,
-                                        const CXXRecordDecl *VTableClass,
-                                        const AddressPointsMapTy& AddressPoints,
-                                        VisitedVirtualBasesSetTy &VBases) {
+                                           bool BaseIsMorallyVirtual,
+                                           uint64_t VTableIndex,
+                                           const CXXRecordDecl *VTableClass,
+                                           VisitedVirtualBasesSetTy &VBases) {
   const CXXRecordDecl *RD = Base.getBase();
   
   // We're not interested in bases that don't have virtual bases, and not
@@ -296,24 +293,23 @@
     if (!BaseDeclIsNonVirtualPrimaryBase &&
         (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
       // Add the vtable pointer.
-      AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTable, 
-                       VTableClass, AddressPoints);
+      AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTableIndex, 
+                       VTableClass);
     }
 
     // And lay out the secondary virtual pointers for the base class.
     LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
-                                   BaseDeclIsMorallyVirtual, VTable, 
-                                   VTableClass, AddressPoints, VBases);
+                                   BaseDeclIsMorallyVirtual, VTableIndex, 
+                                   VTableClass, VBases);
   }
 }
 
 void 
 VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base, 
-                                      llvm::Constant *VTable,
-                                      const AddressPointsMapTy& AddressPoints) {
+                                           uint64_t VTableIndex) {
   VisitedVirtualBasesSetTy VBases;
   LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
-                                 VTable, Base.getBase(), AddressPoints, VBases);
+                                 VTableIndex, Base.getBase(), VBases);
 }
 
 void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
@@ -358,17 +354,17 @@
     SubVTTIndicies[Base] = VTTComponents.size();
   }
 
-  AddressPointsMapTy AddressPoints;
-  llvm::Constant *VTable = GetAddrOfVTable(Base, BaseIsVirtual, AddressPoints);
+  uint64_t VTableIndex = VTTVTables.size();
+  VTTVTables.push_back(VTTVTable(Base, BaseIsVirtual));
 
   // Add the primary vtable pointer.
-  AddVTablePointer(Base, VTable, RD, AddressPoints);
+  AddVTablePointer(Base, VTableIndex, RD);
 
   // Add the secondary VTTs.
   LayoutSecondaryVTTs(Base);
   
   // Add the secondary virtual pointers.
-  LayoutSecondaryVirtualPointers(Base, VTable, AddressPoints);
+  LayoutSecondaryVirtualPointers(Base, VTableIndex);
   
   // If this is the primary VTT, we want to lay out virtual VTTs as well.
   if (IsPrimaryVTT) {
@@ -383,14 +379,51 @@
 CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
                                   llvm::GlobalVariable::LinkageTypes Linkage,
                                   const CXXRecordDecl *RD) {
-  VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true, Linkage);
+  VTTBuilder Builder(CGM, RD, /*GenerateDefinition=*/true);
 
-  llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()),
+             *Int64Ty = llvm::Type::getInt64Ty(CGM.getLLVMContext());
   llvm::ArrayType *ArrayType = 
     llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size());
   
-  llvm::Constant *Init = 
-    llvm::ConstantArray::get(ArrayType, Builder.getVTTComponents());
+  SmallVector<llvm::Constant *, 8> VTables;
+  SmallVector<VTableAddressPointsMapTy, 8> VTableAddressPoints;
+  for (const VTTVTable *i = Builder.getVTTVTables().begin(),
+                       *e = Builder.getVTTVTables().end(); i != e; ++i) {
+    VTableAddressPoints.push_back(VTableAddressPointsMapTy());
+    VTables.push_back(GetAddrOfVTTVTable(*this, RD, *i, Linkage,
+                                         VTableAddressPoints.back()));
+  }
+
+  SmallVector<llvm::Constant *, 8> VTTComponents;
+  for (const VTTComponent *i = Builder.getVTTComponents().begin(),
+                          *e = Builder.getVTTComponents().end(); i != e; ++i) {
+    const VTTVTable &VTTVT = Builder.getVTTVTables()[i->VTableIndex];
+    llvm::Constant *VTable = VTables[i->VTableIndex];
+    uint64_t AddressPoint;
+    if (VTTVT.getBase() == RD) {
+      // Just get the address point for the regular vtable.
+      AddressPoint = getAddressPoint(i->VTableBase, RD);
+      assert(AddressPoint != 0 && "Did not find vtable address point!");
+    } else {
+      AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase);
+      assert(AddressPoint != 0 && "Did not find ctor vtable address point!");
+    }
+
+     llvm::Value *Idxs[] = {
+       llvm::ConstantInt::get(Int64Ty, 0),
+       llvm::ConstantInt::get(Int64Ty, AddressPoint)
+     };
+
+     llvm::Constant *Init = 
+       llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Idxs);
+
+     Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
+
+     VTTComponents.push_back(Init);
+  }
+
+  llvm::Constant *Init = llvm::ConstantArray::get(ArrayType, VTTComponents);
 
   VTT->setInitializer(Init);
 

Modified: cfe/trunk/lib/CodeGen/CGVTables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.h?rev=140498&r1=140497&r2=140498&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.h (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.h Sun Sep 25 20:56:06 2011
@@ -37,6 +37,7 @@
   CharUnits BaseOffset;
   
 public:
+  BaseSubobject() { }
   BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
     : Base(Base), BaseOffset(BaseOffset) { }
   





More information about the cfe-commits mailing list