r280897 - CodeGen: Clean up implementation of vtable initializer builder. NFC.

Peter Collingbourne via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 7 18:14:39 PDT 2016


Author: pcc
Date: Wed Sep  7 20:14:39 2016
New Revision: 280897

URL: http://llvm.org/viewvc/llvm-project?rev=280897&view=rev
Log:
CodeGen: Clean up implementation of vtable initializer builder. NFC.

- Simplify signature of CreateVTableInitializer function.
- Move vtable component builder to a separate function.
- Remove unnecessary accessors from VTableLayout class.

This is in preparation for a future change that will alter the type of the
vtable initializer.

Differential Revision: https://reviews.llvm.org/D22642

Modified:
    cfe/trunk/include/clang/AST/VTableBuilder.h
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGVTables.cpp
    cfe/trunk/lib/CodeGen/CGVTables.h
    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp

Modified: cfe/trunk/include/clang/AST/VTableBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/VTableBuilder.h?rev=280897&r1=280896&r2=280897&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/VTableBuilder.h (original)
+++ cfe/trunk/include/clang/AST/VTableBuilder.h Wed Sep  7 20:14:39 2016
@@ -218,12 +218,6 @@ private:
 class VTableLayout {
 public:
   typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
-
-  typedef const VTableComponent *vtable_component_iterator;
-  typedef const VTableThunkTy *vtable_thunk_iterator;
-  typedef llvm::iterator_range<vtable_component_iterator>
-      vtable_component_range;
-
   typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
 
 private:
@@ -248,31 +242,12 @@ public:
                bool IsMicrosoftABI);
   ~VTableLayout();
 
-  uint64_t getNumVTableComponents() const {
-    return NumVTableComponents;
-  }
-
-  vtable_component_range vtable_components() const {
-    return vtable_component_range(vtable_component_begin(),
-                                  vtable_component_end());
-  }
-
-  vtable_component_iterator vtable_component_begin() const {
-    return VTableComponents.get();
-  }
-
-  vtable_component_iterator vtable_component_end() const {
-    return VTableComponents.get() + NumVTableComponents;
-  }
-
-  uint64_t getNumVTableThunks() const { return NumVTableThunks; }
-
-  vtable_thunk_iterator vtable_thunk_begin() const {
-    return VTableThunks.get();
+  ArrayRef<VTableComponent> vtable_components() const {
+    return {VTableComponents.get(), NumVTableComponents};
   }
 
-  vtable_thunk_iterator vtable_thunk_end() const {
-    return VTableThunks.get() + NumVTableThunks;
+  ArrayRef<VTableThunkTy> vtable_thunks() const {
+    return {VTableThunks.get(), NumVTableThunks};
   }
 
   uint64_t getAddressPoint(BaseSubobject Base) const {

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=280897&r1=280896&r2=280897&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Sep  7 20:14:39 2016
@@ -1576,7 +1576,7 @@ void CGDebugInfo::CollectVTableInfo(cons
     const VTableLayout &VFTLayout =
         CGM.getMicrosoftVTableContext().getVFTableLayout(RD, CharUnits::Zero());
     unsigned VSlotCount =
-        VFTLayout.getNumVTableComponents() - CGM.getLangOpts().RTTIData;
+        VFTLayout.vtable_components().size() - CGM.getLangOpts().RTTIData;
     unsigned VTableWidth = PtrWidth * VSlotCount;
 
     // Create a very wide void* type and insert it directly in the element list.

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=280897&r1=280896&r2=280897&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Wed Sep  7 20:14:39 2016
@@ -517,139 +517,121 @@ void CodeGenVTables::EmitThunks(GlobalDe
     emitThunk(GD, Thunk, /*ForVTable=*/false);
 }
 
-llvm::Constant *CodeGenVTables::CreateVTableInitializer(
-    const CXXRecordDecl *RD, const VTableComponent *Components,
-    unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks,
-    unsigned NumVTableThunks, llvm::Constant *RTTI) {
-  SmallVector<llvm::Constant *, 64> Inits;
-
-  llvm::Type *Int8PtrTy = CGM.Int8PtrTy;
-  
-  llvm::Type *PtrDiffTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
-
-  unsigned NextVTableThunkIndex = 0;
-
-  llvm::Constant *PureVirtualFn = nullptr, *DeletedVirtualFn = nullptr;
-
-  for (unsigned I = 0; I != NumComponents; ++I) {
-    VTableComponent Component = Components[I];
-
-    llvm::Constant *Init = nullptr;
+llvm::Constant *CodeGenVTables::CreateVTableComponent(
+    unsigned Idx, const VTableLayout &VTLayout, llvm::Constant *RTTI,
+    unsigned &NextVTableThunkIndex) {
+  VTableComponent Component = VTLayout.vtable_components()[Idx];
+
+  auto OffsetConstant = [&](CharUnits Offset) {
+    return llvm::ConstantExpr::getIntToPtr(
+        llvm::ConstantInt::get(CGM.PtrDiffTy, Offset.getQuantity()),
+        CGM.Int8PtrTy);
+  };
+
+  switch (Component.getKind()) {
+  case VTableComponent::CK_VCallOffset:
+    return OffsetConstant(Component.getVCallOffset());
+
+  case VTableComponent::CK_VBaseOffset:
+    return OffsetConstant(Component.getVBaseOffset());
+
+  case VTableComponent::CK_OffsetToTop:
+    return OffsetConstant(Component.getOffsetToTop());
+
+  case VTableComponent::CK_RTTI:
+    return RTTI;
+
+  case VTableComponent::CK_FunctionPointer:
+  case VTableComponent::CK_CompleteDtorPointer:
+  case VTableComponent::CK_DeletingDtorPointer: {
+    GlobalDecl GD;
 
+    // Get the right global decl.
     switch (Component.getKind()) {
-    case VTableComponent::CK_VCallOffset:
-      Init = llvm::ConstantInt::get(PtrDiffTy, 
-                                    Component.getVCallOffset().getQuantity());
-      Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy);
-      break;
-    case VTableComponent::CK_VBaseOffset:
-      Init = llvm::ConstantInt::get(PtrDiffTy, 
-                                    Component.getVBaseOffset().getQuantity());
-      Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy);
+    default:
+      llvm_unreachable("Unexpected vtable component kind");
+    case VTableComponent::CK_FunctionPointer:
+      GD = Component.getFunctionDecl();
       break;
-    case VTableComponent::CK_OffsetToTop:
-      Init = llvm::ConstantInt::get(PtrDiffTy, 
-                                    Component.getOffsetToTop().getQuantity());
-      Init = llvm::ConstantExpr::getIntToPtr(Init, Int8PtrTy);
+    case VTableComponent::CK_CompleteDtorPointer:
+      GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete);
       break;
-    case VTableComponent::CK_RTTI:
-      Init = llvm::ConstantExpr::getBitCast(RTTI, Int8PtrTy);
+    case VTableComponent::CK_DeletingDtorPointer:
+      GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting);
       break;
-    case VTableComponent::CK_FunctionPointer:
-    case VTableComponent::CK_CompleteDtorPointer:
-    case VTableComponent::CK_DeletingDtorPointer: {
-      GlobalDecl GD;
-      
-      // Get the right global decl.
-      switch (Component.getKind()) {
-      default:
-        llvm_unreachable("Unexpected vtable component kind");
-      case VTableComponent::CK_FunctionPointer:
-        GD = Component.getFunctionDecl();
-        break;
-      case VTableComponent::CK_CompleteDtorPointer:
-        GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete);
-        break;
-      case VTableComponent::CK_DeletingDtorPointer:
-        GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting);
-        break;
-      }
+    }
 
-      if (CGM.getLangOpts().CUDA) {
-        // Emit NULL for methods we can't codegen on this
-        // side. Otherwise we'd end up with vtable with unresolved
-        // references.
-        const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
-        // OK on device side: functions w/ __device__ attribute
-        // OK on host side: anything except __device__-only functions.
-        bool CanEmitMethod = CGM.getLangOpts().CUDAIsDevice
-                                 ? MD->hasAttr<CUDADeviceAttr>()
-                                 : (MD->hasAttr<CUDAHostAttr>() ||
-                                    !MD->hasAttr<CUDADeviceAttr>());
-        if (!CanEmitMethod) {
-          Init = llvm::ConstantExpr::getNullValue(Int8PtrTy);
-          break;
-        }
-        // Method is acceptable, continue processing as usual.
-      }
+    if (CGM.getLangOpts().CUDA) {
+      // Emit NULL for methods we can't codegen on this
+      // side. Otherwise we'd end up with vtable with unresolved
+      // references.
+      const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+      // OK on device side: functions w/ __device__ attribute
+      // OK on host side: anything except __device__-only functions.
+      bool CanEmitMethod =
+          CGM.getLangOpts().CUDAIsDevice
+              ? MD->hasAttr<CUDADeviceAttr>()
+              : (MD->hasAttr<CUDAHostAttr>() || !MD->hasAttr<CUDADeviceAttr>());
+      if (!CanEmitMethod)
+        return llvm::ConstantExpr::getNullValue(CGM.Int8PtrTy);
+      // Method is acceptable, continue processing as usual.
+    }
 
-      if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) {
-        // We have a pure virtual member function.
-        if (!PureVirtualFn) {
-          llvm::FunctionType *Ty = 
+    auto SpecialVirtualFn = [&](llvm::Constant *&Cache, StringRef Name) {
+      if (!Cache) {
+        llvm::FunctionType *Ty =
             llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
-          StringRef PureCallName = CGM.getCXXABI().GetPureVirtualCallName();
-          PureVirtualFn = CGM.CreateRuntimeFunction(Ty, PureCallName);
-          if (auto *F = dyn_cast<llvm::Function>(PureVirtualFn))
-            F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-          PureVirtualFn = llvm::ConstantExpr::getBitCast(PureVirtualFn,
-                                                         CGM.Int8PtrTy);
-        }
-        Init = PureVirtualFn;
-      } else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) {
-        if (!DeletedVirtualFn) {
-          llvm::FunctionType *Ty =
-            llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
-          StringRef DeletedCallName =
-            CGM.getCXXABI().GetDeletedVirtualCallName();
-          DeletedVirtualFn = CGM.CreateRuntimeFunction(Ty, DeletedCallName);
-          if (auto *F = dyn_cast<llvm::Function>(DeletedVirtualFn))
-            F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-          DeletedVirtualFn = llvm::ConstantExpr::getBitCast(DeletedVirtualFn,
-                                                         CGM.Int8PtrTy);
-        }
-        Init = DeletedVirtualFn;
-      } else {
-        // Check if we should use a thunk.
-        if (NextVTableThunkIndex < NumVTableThunks &&
-            VTableThunks[NextVTableThunkIndex].first == I) {
-          const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second;
-        
-          maybeEmitThunkForVTable(GD, Thunk);
-          Init = CGM.GetAddrOfThunk(GD, Thunk);
-
-          NextVTableThunkIndex++;
-        } else {
-          llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD);
-        
-          Init = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
-        }
-
-        Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
+        Cache = CGM.CreateRuntimeFunction(Ty, Name);
+        if (auto *F = dyn_cast<llvm::Function>(Cache))
+          F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+        Cache = llvm::ConstantExpr::getBitCast(Cache, CGM.Int8PtrTy);
       }
-      break;
+      return Cache;
+    };
+
+    if (cast<CXXMethodDecl>(GD.getDecl())->isPure())
+      // We have a pure virtual member function.
+      return SpecialVirtualFn(PureVirtualFn,
+                              CGM.getCXXABI().GetPureVirtualCallName());
+
+    if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted())
+      return SpecialVirtualFn(DeletedVirtualFn,
+                              CGM.getCXXABI().GetDeletedVirtualCallName());
+
+    // Check if we should use a thunk.
+    if (NextVTableThunkIndex < VTLayout.vtable_thunks().size() &&
+        VTLayout.vtable_thunks()[NextVTableThunkIndex].first == Idx) {
+      const ThunkInfo &Thunk =
+          VTLayout.vtable_thunks()[NextVTableThunkIndex].second;
+
+      maybeEmitThunkForVTable(GD, Thunk);
+      NextVTableThunkIndex++;
+      return CGM.GetAddrOfThunk(GD, Thunk);
     }
 
-    case VTableComponent::CK_UnusedFunctionPointer:
-      Init = llvm::ConstantExpr::getNullValue(Int8PtrTy);
-      break;
-    };
-    
-    Inits.push_back(Init);
+    llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD);
+    return CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
   }
-  
-  llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, NumComponents);
+
+  case VTableComponent::CK_UnusedFunctionPointer:
+    return llvm::ConstantExpr::getNullValue(CGM.Int8PtrTy);
+  }
+}
+
+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));
+  }
+
+  llvm::ArrayType *ArrayType =
+      llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout.vtable_components().size());
   return llvm::ConstantArray::get(ArrayType, Inits);
 }
 
@@ -677,8 +659,8 @@ CodeGenVTables::GenerateConstructionVTab
                            Base.getBase(), Out);
   StringRef Name = OutName.str();
 
-  llvm::ArrayType *ArrayType = 
-    llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout->getNumVTableComponents());
+  llvm::ArrayType *ArrayType =
+      llvm::ArrayType::get(CGM.Int8PtrTy, VTLayout->vtable_components().size());
 
   // Construction vtable symbols are not part of the Itanium ABI, so we cannot
   // guarantee that they actually will be available externally. Instead, when
@@ -700,10 +682,7 @@ CodeGenVTables::GenerateConstructionVTab
       CGM.getContext().getTagDeclType(Base.getBase()));
 
   // Create and set the initializer.
-  llvm::Constant *Init = CreateVTableInitializer(
-      Base.getBase(), VTLayout->vtable_component_begin(),
-      VTLayout->getNumVTableComponents(), VTLayout->vtable_thunk_begin(),
-      VTLayout->getNumVTableThunks(), RTTI);
+  llvm::Constant *Init = CreateVTableInitializer(*VTLayout, RTTI);
   VTable->setInitializer(Init);
   
   CGM.EmitVTableTypeMetadata(VTable, *VTLayout.get());

Modified: cfe/trunk/lib/CodeGen/CGVTables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.h?rev=280897&r1=280896&r2=280897&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.h (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.h Wed Sep  7 20:14:39 2016
@@ -49,6 +49,12 @@ class CodeGenVTables {
   /// indices.
   SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
 
+  /// Cache for the pure virtual member call function.
+  llvm::Constant *PureVirtualFn = nullptr;
+
+  /// Cache for the deleted virtual member call function.
+  llvm::Constant *DeletedVirtualFn = nullptr;
+
   /// emitThunk - Emit a single thunk.
   void emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, bool ForVTable);
 
@@ -56,15 +62,16 @@ class CodeGenVTables {
   /// the ABI.
   void maybeEmitThunkForVTable(GlobalDecl GD, const ThunkInfo &Thunk);
 
+  llvm::Constant *CreateVTableComponent(unsigned Idx,
+                                        const VTableLayout &VTLayout,
+                                        llvm::Constant *RTTI,
+                                        unsigned &NextVTableThunkIndex);
+
 public:
-  /// CreateVTableInitializer - Create a vtable initializer for the given record
-  /// decl.
-  /// \param Components - The vtable components; this is really an array of
-  /// VTableComponents.
-  llvm::Constant *CreateVTableInitializer(
-      const CXXRecordDecl *RD, const VTableComponent *Components,
-      unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks,
-      unsigned NumVTableThunks, llvm::Constant *RTTI);
+  /// CreateVTableInitializer - Create a vtable initializer with the given
+  /// layout.
+  llvm::Constant *CreateVTableInitializer(const VTableLayout &VTLayout,
+                                          llvm::Constant *RTTI);
 
   CodeGenVTables(CodeGenModule &CGM);
 

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=280897&r1=280896&r2=280897&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Wed Sep  7 20:14:39 2016
@@ -1462,9 +1462,7 @@ void ItaniumCXXABI::emitVTableDefinition
       CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
 
   // Create and set the initializer.
-  llvm::Constant *Init = CGVT.CreateVTableInitializer(
-      RD, VTLayout.vtable_component_begin(), VTLayout.getNumVTableComponents(),
-      VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks(), RTTI);
+  llvm::Constant *Init = CGVT.CreateVTableInitializer(VTLayout, RTTI);
   VTable->setInitializer(Init);
 
   // Set the correct linkage.
@@ -1575,7 +1573,7 @@ llvm::GlobalVariable *ItaniumCXXABI::get
 
   ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
   llvm::ArrayType *ArrayType = llvm::ArrayType::get(
-      CGM.Int8PtrTy, VTContext.getVTableLayout(RD).getNumVTableComponents());
+      CGM.Int8PtrTy, VTContext.getVTableLayout(RD).vtable_components().size());
 
   VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
       Name, ArrayType, llvm::GlobalValue::ExternalLinkage);

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=280897&r1=280896&r2=280897&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Sep  7 20:14:39 2016
@@ -1575,10 +1575,7 @@ void MicrosoftCXXABI::emitVTableDefiniti
                [](const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
       RTTI = getMSCompleteObjectLocator(RD, Info);
 
-    llvm::Constant *Init = CGVT.CreateVTableInitializer(
-        RD, VTLayout.vtable_component_begin(),
-        VTLayout.getNumVTableComponents(), VTLayout.vtable_thunk_begin(),
-        VTLayout.getNumVTableThunks(), RTTI);
+    llvm::Constant *Init = CGVT.CreateVTableInitializer(VTLayout, RTTI);
 
     VTable->setInitializer(Init);
 
@@ -1701,7 +1698,8 @@ llvm::GlobalVariable *MicrosoftCXXABI::g
 
   uint64_t NumVTableSlots =
       VTContext.getVFTableLayout(RD, VFPtr->FullOffsetInMDC)
-          .getNumVTableComponents();
+          .vtable_components()
+          .size();
   llvm::GlobalValue::LinkageTypes VTableLinkage =
       VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
 




More information about the cfe-commits mailing list