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