pcc updated this revision to Diff 65647.
pcc added a comment.

Use new representation: https://reviews.llvm.org/D22793


https://reviews.llvm.org/D22296

Files:
  include/clang/AST/VTableBuilder.h
  lib/AST/VTableBuilder.cpp
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGVTT.cpp
  lib/CodeGen/CGVTables.cpp
  lib/CodeGen/CGVTables.h
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp

Index: lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1686,17 +1686,14 @@
     return VTable;
   }
 
-  uint64_t NumVTableSlots =
-      VTContext.getVFTableLayout(RD, VFPtr->FullOffsetInMDC)
-          .vtable_components()
-          .size();
+  const VTableLayout &VTLayout =
+      VTContext.getVFTableLayout(RD, VFPtr->FullOffsetInMDC);
   llvm::GlobalValue::LinkageTypes VTableLinkage =
       VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
 
   StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
 
-  llvm::ArrayType *VTableType =
-      llvm::ArrayType::get(CGM.Int8PtrTy, NumVTableSlots);
+  llvm::Type *VTableType = CGM.getVTables().GetVTableType(RD, VTLayout);
 
   // Create a backing variable for the contents of VTable.  The VTable may
   // or may not include space for a pointer to RTTI data.
@@ -1717,8 +1714,9 @@
   // importing it.  We never reference the RTTI data directly so there is no
   // need to make room for it.
   if (VTableAliasIsRequred) {
-    llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
-                                 llvm::ConstantInt::get(CGM.IntTy, 1)};
+    llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.Int32Ty, 0),
+                                 llvm::ConstantInt::get(CGM.Int32Ty, 0),
+                                 llvm::ConstantInt::get(CGM.Int32Ty, 1)};
     // Create a GEP which points just after the first entry in the VFTable,
     // this should be the location of the first virtual method.
     llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -1515,17 +1515,20 @@
                                      const CXXRecordDecl *VTableClass) {
   llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());
 
-  // Find the appropriate vtable within the vtable group.
-  uint64_t AddressPoint = CGM.getItaniumVTableContext()
-                              .getVTableLayout(VTableClass)
-                              .getAddressPoint(Base);
+  // Find the appropriate vtable within the vtable group, and the address point
+  // within that vtable.
+  std::pair<unsigned, unsigned> AddressPoint = CGM.getItaniumVTableContext()
+                                                   .getVTableLayout(VTableClass)
+                                                   .getAddressPoint(Base);
   llvm::Value *Indices[] = {
     llvm::ConstantInt::get(CGM.Int32Ty, 0),
-    llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint)
+    llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.first),
+    llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.second),
   };
 
-  return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable->getValueType(),
-                                                      VTable, Indices);
+  return llvm::ConstantExpr::getGetElementPtr(VTable->getValueType(), VTable,
+                                              Indices, /*InBounds=*/true,
+                                              /*InRangeIndex=*/1);
 }
 
 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
@@ -1567,12 +1570,12 @@
   llvm::raw_svector_ostream Out(Name);
   getMangleContext().mangleCXXVTable(RD, Out);
 
-  ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
-  llvm::ArrayType *ArrayType = llvm::ArrayType::get(
-      CGM.Int8PtrTy, VTContext.getVTableLayout(RD).vtable_components().size());
+  const VTableLayout &VTLayout =
+      CGM.getItaniumVTableContext().getVTableLayout(RD);
+  llvm::Type *VTableType = CGM.getVTables().GetVTableType(RD, VTLayout);
 
   VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
-      Name, ArrayType, llvm::GlobalValue::ExternalLinkage);
+      Name, VTableType, llvm::GlobalValue::ExternalLinkage);
   VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
   if (RD->hasAttr<DLLImportAttr>())
Index: lib/CodeGen/CGVTables.h
===================================================================
--- lib/CodeGen/CGVTables.h
+++ lib/CodeGen/CGVTables.h
@@ -34,7 +34,7 @@
   VTableContextBase *VTContext;
 
   /// VTableAddressPointsMapTy - Address points for a single vtable.
-  typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
+  typedef VTableLayout::AddressPointsMapTy VTableAddressPointsMapTy;
 
   typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
   typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy;
@@ -117,6 +117,12 @@
   void GenerateClassData(const CXXRecordDecl *RD);
 
   bool isVTableExternal(const CXXRecordDecl *RD);
+
+  /// Returns the type of a vtable with the given layout. Normally a struct of
+  /// arrays of pointers, with one struct element for each vtable in the vtable
+  /// group.
+  llvm::Type *GetVTableType(const CXXRecordDecl *RD,
+                            const VTableLayout &VTLayout);
 };
 
 } // end namespace CodeGen
Index: lib/CodeGen/CGVTables.cpp
===================================================================
--- lib/CodeGen/CGVTables.cpp
+++ lib/CodeGen/CGVTables.cpp
@@ -621,21 +621,44 @@
   }
 }
 
+llvm::Type *CodeGenVTables::GetVTableType(const CXXRecordDecl *RD,
+                                          const VTableLayout &VTLayout) {
+  ArrayRef<size_t> Idxs = VTLayout.getVTableIndices();
+
+  std::vector<llvm::Type *> Tys;
+  for (unsigned I = 0, E = Idxs.size(); I != E; ++I) {
+    size_t ThisIndex = Idxs[I];
+    size_t NextIndex =
+        (I + 1 == E) ? VTLayout.vtable_components().size() : Idxs[I + 1];
+    Tys.push_back(llvm::ArrayType::get(CGM.Int8PtrTy, NextIndex - ThisIndex));
+  }
+
+  return llvm::StructType::get(CGM.getLLVMContext(), Tys);
+}
+ 
 llvm::Constant *
 CodeGenVTables::CreateVTableInitializer(const VTableLayout &VTLayout,
                                         llvm::Constant *RTTI) {
   SmallVector<llvm::Constant *, 64> Inits;
   unsigned NextVTableThunkIndex = 0;
 
-  for (unsigned I = 0, E = VTLayout.vtable_components().size(); I != E; ++I) {
-    llvm::Constant *Init =
-        CreateVTableComponent(I, VTLayout, RTTI, NextVTableThunkIndex);
-    Inits.push_back(llvm::ConstantExpr::getBitCast(Init, CGM.Int8PtrTy));
+  ArrayRef<size_t> Idxs = VTLayout.getVTableIndices();
+  for (unsigned I = 0, E = Idxs.size(); I != E; ++I) {
+    size_t ThisIndex = Idxs[I];
+    size_t NextIndex =
+        (I + 1 == E) ? VTLayout.vtable_components().size() : Idxs[I + 1];
+    SmallVector<llvm::Constant *, 64> ArrayInits;
+    for (unsigned I = ThisIndex; I != NextIndex; ++I) {
+      llvm::Constant *Init =
+          CreateVTableComponent(I, VTLayout, RTTI, NextVTableThunkIndex);
+      ArrayInits.push_back(llvm::ConstantExpr::getBitCast(Init, CGM.Int8PtrTy));
+    }
+    llvm::ArrayType *ArrayType =
+        llvm::ArrayType::get(CGM.Int8PtrTy, NextIndex - ThisIndex);
+    Inits.push_back(llvm::ConstantArray::get(ArrayType, ArrayInits));
   }
 
-  llvm::ArrayType *ArrayType =
-      llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout.vtable_components().size());
-  return llvm::ConstantArray::get(ArrayType, Inits);
+  return llvm::ConstantStruct::getAnon(Inits);
 }
 
 llvm::GlobalVariable *
@@ -662,8 +685,7 @@
                            Base.getBase(), Out);
   StringRef Name = OutName.str();
 
-  llvm::ArrayType *ArrayType =
-      llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout->vtable_components().size());
+  llvm::Type *VTType = GetVTableType(RD, *VTLayout);
 
   // Construction vtable symbols are not part of the Itanium ABI, so we cannot
   // guarantee that they actually will be available externally. Instead, when
@@ -675,7 +697,7 @@
 
   // Create the variable that will hold the construction vtable.
   llvm::GlobalVariable *VTable = 
-    CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, Linkage);
+    CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage);
   CGM.setGlobalVisibility(VTable, RD);
 
   // V-tables are always unnamed_addr.
@@ -928,7 +950,9 @@
   std::vector<BSEntry> BitsetEntries;
   // Create a bit set entry for each address point.
   for (auto &&AP : VTLayout.getAddressPoints())
-    BitsetEntries.push_back(std::make_pair(AP.first.getBase(), AP.second));
+    BitsetEntries.push_back(std::make_pair(
+        AP.first.getBase(),
+        VTLayout.getVTableIndices()[AP.second.first] + AP.second.second));
 
   // Sort the bit set entries for determinism.
   std::sort(BitsetEntries.begin(), BitsetEntries.end(),
Index: lib/CodeGen/CGVTT.cpp
===================================================================
--- lib/CodeGen/CGVTT.cpp
+++ lib/CodeGen/CGVTT.cpp
@@ -23,7 +23,7 @@
                    const CXXRecordDecl *MostDerivedClass,
                    const VTTVTable &VTable,
                    llvm::GlobalVariable::LinkageTypes Linkage,
-                   llvm::DenseMap<BaseSubobject, uint64_t> &AddressPoints) {
+                   VTableLayout::AddressPointsMapTy &AddressPoints) {
   if (VTable.getBase() == MostDerivedClass) {
     assert(VTable.getBaseOffset().isZero() &&
            "Most derived class vtable must have a zero offset!");
@@ -62,25 +62,28 @@
                           *e = Builder.getVTTComponents().end(); i != e; ++i) {
     const VTTVTable &VTTVT = Builder.getVTTVTables()[i->VTableIndex];
     llvm::GlobalVariable *VTable = VTables[i->VTableIndex];
-    uint64_t AddressPoint;
+    std::pair<unsigned, unsigned> AddressPoint;
     if (VTTVT.getBase() == RD) {
       // Just get the address point for the regular vtable.
       AddressPoint =
           getItaniumVTableContext().getVTableLayout(RD).getAddressPoint(
               i->VTableBase);
-      assert(AddressPoint != 0 && "Did not find vtable address point!");
+      assert(AddressPoint.second != 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!");
+      assert(AddressPoint.second != 0 &&
+             "Did not find ctor vtable address point!");
     }
 
      llvm::Value *Idxs[] = {
        llvm::ConstantInt::get(Int32Ty, 0),
-       llvm::ConstantInt::get(Int32Ty, AddressPoint)
+       llvm::ConstantInt::get(Int32Ty, AddressPoint.first),
+       llvm::ConstantInt::get(Int32Ty, AddressPoint.second),
      };
 
-     llvm::Constant *Init = llvm::ConstantExpr::getInBoundsGetElementPtr(
-         VTable->getValueType(), VTable, Idxs);
+     llvm::Constant *Init = llvm::ConstantExpr::getGetElementPtr(
+         VTable->getValueType(), VTable, Idxs, /*InBounds=*/true,
+         /*InRangeIndex=*/1);
 
      Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
 
Index: lib/CodeGen/CGCXX.cpp
===================================================================
--- lib/CodeGen/CGCXX.cpp
+++ lib/CodeGen/CGCXX.cpp
@@ -273,10 +273,11 @@
   VTable = CGF.Builder.CreateBitCast(VTable, Ty);
   assert(VTable && "BuildVirtualCall = kext vtbl pointer is null");
   uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
-  uint64_t AddressPoint =
-    CGM.getItaniumVTableContext().getVTableLayout(RD)
-       .getAddressPoint(BaseSubobject(RD, CharUnits::Zero()));
-  VTableIndex += AddressPoint;
+  const VTableLayout &VTLayout = CGM.getItaniumVTableContext().getVTableLayout(RD);
+  std::pair<unsigned, unsigned> AddressPoint =
+      VTLayout.getAddressPoint(BaseSubobject(RD, CharUnits::Zero()));
+  VTableIndex +=
+      VTLayout.getVTableIndices()[AddressPoint.first] + AddressPoint.second;
   llvm::Value *VFuncPtr =
     CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt");
   return CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.PointerAlignInBytes);
Index: lib/AST/VTableBuilder.cpp
===================================================================
--- lib/AST/VTableBuilder.cpp
+++ lib/AST/VTableBuilder.cpp
@@ -777,9 +777,8 @@
   
   typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> 
     VBaseOffsetOffsetsMapTy;
-  
-  typedef llvm::DenseMap<BaseSubobject, uint64_t> 
-    AddressPointsMapTy;
+
+  typedef VTableLayout::AddressPointsMapTy AddressPointsMapTy;
 
   typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
 
@@ -817,7 +816,7 @@
   /// VBaseOffsetOffsets - Contains the offsets of the virtual base offsets for
   /// the most derived class.
   VBaseOffsetOffsetsMapTy VBaseOffsetOffsets;
-  
+
   /// Components - The components of the vtable being built.
   SmallVector<VTableComponent, 64> Components;
 
@@ -982,6 +981,10 @@
   }
 
 public:
+  /// Component indices of the first component of each of the vtables in the
+  /// vtable group.
+  std::vector<size_t> VTableIndices;
+
   ItaniumVTableBuilder(ItaniumVTableContext &VTables,
                        const CXXRecordDecl *MostDerivedClass,
                        CharUnits MostDerivedClassOffset,
@@ -1639,6 +1642,9 @@
     bool BaseIsVirtualInLayoutClass, CharUnits OffsetInLayoutClass) {
   assert(Base.getBase()->isDynamicClass() && "class does not have a vtable!");
 
+  unsigned VTableIndex = Components.size();
+  VTableIndices.push_back(VTableIndex);
+
   // Add vcall and vbase offsets for this vtable.
   VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, LayoutClass, &Overriders,
                                      Base, BaseIsVirtualInLayoutClass, 
@@ -1696,8 +1702,9 @@
   // Add all address points.
   while (true) {
     AddressPoints.insert(std::make_pair(
-      BaseSubobject(RD, OffsetInLayoutClass),
-      AddressPoint));
+        BaseSubobject(RD, OffsetInLayoutClass),
+        std::pair<unsigned, unsigned>{VTableIndices.size() - 1,
+                                      AddressPoint - VTableIndex}));
 
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
     const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
@@ -1901,7 +1908,7 @@
   std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex;
   for (const auto &AP : AddressPoints) {
     const BaseSubobject &Base = AP.first;
-    uint64_t Index = AP.second;
+    uint64_t Index = VTableIndices[AP.second.first] + AP.second.second;
 
     AddressPointsByIndex.insert(std::make_pair(Index, Base));
   }
@@ -2203,18 +2210,18 @@
 }
 }
 
-VTableLayout::VTableLayout(uint64_t NumVTableComponents,
+VTableLayout::VTableLayout(ArrayRef<size_t> VTableIndices,
+                           uint64_t NumVTableComponents,
                            const VTableComponent *VTableComponents,
                            uint64_t NumVTableThunks,
                            const VTableThunkTy *VTableThunks,
                            const AddressPointsMapTy &AddressPoints,
                            bool IsMicrosoftABI)
-  : NumVTableComponents(NumVTableComponents),
-    VTableComponents(new VTableComponent[NumVTableComponents]),
-    NumVTableThunks(NumVTableThunks),
-    VTableThunks(new VTableThunkTy[NumVTableThunks]),
-    AddressPoints(AddressPoints),
-    IsMicrosoftABI(IsMicrosoftABI) {
+    : VTableIndices(VTableIndices), NumVTableComponents(NumVTableComponents),
+      VTableComponents(new VTableComponent[NumVTableComponents]),
+      NumVTableThunks(NumVTableThunks),
+      VTableThunks(new VTableThunkTy[NumVTableThunks]),
+      AddressPoints(AddressPoints), IsMicrosoftABI(IsMicrosoftABI) {
   std::copy(VTableComponents, VTableComponents+NumVTableComponents,
             this->VTableComponents.get());
   std::copy(VTableThunks, VTableThunks+NumVTableThunks,
@@ -2284,11 +2291,10 @@
   SmallVector<VTableLayout::VTableThunkTy, 1>
     VTableThunks(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
 
-  return new VTableLayout(Builder.getNumVTableComponents(),
-                          Builder.vtable_component_begin(),
-                          VTableThunks.size(),
-                          VTableThunks.data(),
-                          Builder.getAddressPoints(),
+  return new VTableLayout(Builder.VTableIndices,
+                          Builder.getNumVTableComponents(),
+                          Builder.vtable_component_begin(), VTableThunks.size(),
+                          VTableThunks.data(), Builder.getAddressPoints(),
                           /*IsMicrosoftABI=*/false);
 }
 
@@ -3592,7 +3598,7 @@
     SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks(
         Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
     VFTableLayouts[id] = new VTableLayout(
-        Builder.getNumVTableComponents(), Builder.vtable_component_begin(),
+        {0}, Builder.getNumVTableComponents(), Builder.vtable_component_begin(),
         VTableThunks.size(), VTableThunks.data(), EmptyAddressPointsMap, true);
     Thunks.insert(Builder.thunks_begin(), Builder.thunks_end());
 
Index: include/clang/AST/VTableBuilder.h
===================================================================
--- include/clang/AST/VTableBuilder.h
+++ include/clang/AST/VTableBuilder.h
@@ -224,9 +224,12 @@
   typedef llvm::iterator_range<vtable_component_iterator>
       vtable_component_range;
 
-  typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
+  typedef llvm::DenseMap<BaseSubobject, std::pair<unsigned, unsigned>>
+      AddressPointsMapTy;
 
 private:
+  std::vector<size_t> VTableIndices;
+
   uint64_t NumVTableComponents;
   std::unique_ptr<VTableComponent[]> VTableComponents;
 
@@ -240,12 +243,10 @@
   bool IsMicrosoftABI;
 
 public:
-  VTableLayout(uint64_t NumVTableComponents,
+  VTableLayout(ArrayRef<size_t> VTableIndices, uint64_t NumVTableComponents,
                const VTableComponent *VTableComponents,
-               uint64_t NumVTableThunks,
-               const VTableThunkTy *VTableThunks,
-               const AddressPointsMapTy &AddressPoints,
-               bool IsMicrosoftABI);
+               uint64_t NumVTableThunks, const VTableThunkTy *VTableThunks,
+               const AddressPointsMapTy &AddressPoints, bool IsMicrosoftABI);
   ~VTableLayout();
 
   ArrayRef<VTableComponent> vtable_components() const {
@@ -256,20 +257,26 @@
     return {VTableThunks.get(), NumVTableThunks};
   }
 
-  uint64_t getAddressPoint(BaseSubobject Base) const {
+  std::pair<unsigned, unsigned> getAddressPoint(BaseSubobject Base) const {
     assert(AddressPoints.count(Base) &&
            "Did not find address point!");
 
-    uint64_t AddressPoint = AddressPoints.lookup(Base);
-    assert(AddressPoint != 0 || IsMicrosoftABI);
+    std::pair<unsigned, unsigned> AddressPoint = AddressPoints.lookup(Base);
+    assert(AddressPoint.second != 0 || IsMicrosoftABI);
     (void)IsMicrosoftABI;
 
     return AddressPoint;
   }
 
   const AddressPointsMapTy &getAddressPoints() const {
     return AddressPoints;
   }
+
+  /// Get the component indices of the first component of each virtual table in
+  /// the virtual table group.
+  ArrayRef<size_t> getVTableIndices() const {
+    return VTableIndices;
+  }
 };
 
 class VTableContextBase {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to