From 5c6c1d9eca7ce932eff011cd3e592f606e60b4be Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Wed, 24 Mar 2010 03:57:14 +0000 Subject: [PATCH] More vtable work; preparations for moving over to the new vtable layout code (finally). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99381 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGClass.cpp | 12 +++--- lib/CodeGen/CGVTT.cpp | 2 +- lib/CodeGen/CGVtable.cpp | 41 ++++++++++++++----- lib/CodeGen/CGVtable.h | 11 +++-- lib/CodeGen/CodeGenFunction.h | 2 +- .../copy-constructor-synthesis-2.cpp | 2 +- .../vtable-pointer-initialization.cpp | 8 ++-- 7 files changed, 53 insertions(+), 25 deletions(-) diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 4d5fdfe06e..af846329af 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -1560,9 +1560,10 @@ void CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) { if (!ClassDecl->isDynamicClass()) return; - llvm::Constant *VTable = CGM.getVTables().getVtable(ClassDecl); - CodeGenVTables::AddrSubMap_t& AddressPoints = - *(*CGM.getVTables().AddressPoints[ClassDecl])[ClassDecl]; + llvm::Constant *VTable = CGM.getVTables().getAddrOfVTable(ClassDecl); + const CodeGenVTables::AddrSubMap_t& AddressPoints = + CGM.getVTables().getAddressPoints(ClassDecl); + llvm::Value *ThisPtr = LoadCXXThis(); const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl); @@ -1584,7 +1585,7 @@ void CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) { void CodeGenFunction::InitializeVtablePtrsRecursive( const CXXRecordDecl *ClassDecl, llvm::Constant *Vtable, - CodeGenVTables::AddrSubMap_t& AddressPoints, + const CodeGenVTables::AddrSubMap_t& AddressPoints, llvm::Value *ThisPtr, uint64_t Offset) { if (!ClassDecl->isDynamicClass()) @@ -1607,7 +1608,8 @@ void CodeGenFunction::InitializeVtablePtrsRecursive( // Compute the address point assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) && "Missing address point for class"); - uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)]; + uint64_t AddressPoint = + AddressPoints.lookup(std::make_pair(ClassDecl, Offset)); llvm::Value *VtableAddressPoint = Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint); diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index 990a5f625d..b7b24b84b6 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -268,7 +268,7 @@ public: GenerateDefinition(GenerateDefinition) { // First comes the primary virtual table pointer for the complete class... - ClassVtbl = GenerateDefinition ? CGM.getVTables().getVtable(Class) : 0; + ClassVtbl = GenerateDefinition ? CGM.getVTables().getAddrOfVTable(Class) :0; llvm::Constant *Init = BuildVtablePtr(ClassVtbl, Class, Class, 0); Inits.push_back(Init); diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index f4921699be..c9b099bcd9 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -3551,6 +3551,19 @@ int64_t CodeGenVTables::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, return I->second; } +const CodeGenVTables::AddrSubMap_t & +CodeGenVTables::getAddressPoints(const CXXRecordDecl *RD) { + if (!AddressPoints[RD]) { + AddressPointsMapTy AddressPoints; + OldVtableBuilder b(RD, RD, 0, CGM, false, AddressPoints); + + b.GenerateVtableForBase(RD, 0); + b.GenerateVtableForVBases(RD, 0); + } + + return *(*AddressPoints[RD])[RD]; +} + llvm::GlobalVariable * CodeGenVTables::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, @@ -3583,8 +3596,7 @@ CodeGenVTables::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, llvm::StringRef Name = OutName.str(); llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); - if (GV == 0 || CGM.getVTables().AddressPoints[LayoutClass] == 0 || - GV->isDeclaration()) { + if (GV == 0 || GV->isDeclaration()) { OldVtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition, AddressPoints); @@ -3906,17 +3918,26 @@ CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); } -llvm::GlobalVariable *CodeGenVTables::getVtable(const CXXRecordDecl *RD) { - llvm::GlobalVariable *Vtable = Vtables.lookup(RD); +llvm::Constant *CodeGenVTables::getAddrOfVTable(const CXXRecordDecl *RD) { + llvm::SmallString<256> OutName; + CGM.getMangleContext().mangleCXXVtable(RD, OutName); + llvm::StringRef Name = OutName.str(); + + const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); + llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, 0); - if (!Vtable) { - AddressPointsMapTy AddressPoints; - Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage, - /*GenerateDefinition=*/false, RD, RD, 0, - /*IsVirtual=*/false, AddressPoints); + llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); + if (GV) { + if (!GV->isDeclaration() || GV->getType()->getElementType() == ArrayType) + return GV; + + return llvm::ConstantExpr::getBitCast(GV, ArrayType->getPointerTo()); } + + GV = new llvm::GlobalVariable(CGM.getModule(), ArrayType, /*isConstant=*/true, + llvm::GlobalValue::ExternalLinkage, 0, Name); - return Vtable; + return GV; } void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) { diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h index ebccb514e9..a38153bc4b 100644 --- a/lib/CodeGen/CGVtable.h +++ b/lib/CodeGen/CGVtable.h @@ -222,13 +222,17 @@ public: typedef std::pair CtorVtable_t; typedef llvm::DenseMap AddrSubMap_t; typedef llvm::DenseMap AddrMap_t; - llvm::DenseMap AddressPoints; typedef llvm::DenseMap AddressPointsMapTy; + const CodeGenVTables::AddrSubMap_t& getAddressPoints(const CXXRecordDecl *RD); + + llvm::DenseMap AddressPoints; + private: CodeGenModule &CGM; + /// MethodVtableIndices - Contains the index (relative to the vtable address /// point) where the function pointer for a virtual function is stored. typedef llvm::DenseMap MethodVtableIndicesTy; @@ -312,8 +316,9 @@ public: int64_t getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase); - llvm::GlobalVariable *getVtable(const CXXRecordDecl *RD); - + /// getAddrOfVTable - Get the address of the vtable for the given record decl. + llvm::Constant *getAddrOfVTable(const CXXRecordDecl *RD); + /// CtorVtableInfo - Information about a constructor vtable. struct CtorVtableInfo { /// Vtable - The vtable itself. diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index cc5104516d..f5c25b275e 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -513,7 +513,7 @@ public: void InitializeVtablePtrsRecursive(const CXXRecordDecl *ClassDecl, llvm::Constant *Vtable, - CodeGenVTables::AddrSubMap_t& AddressPoints, + const CodeGenVTables::AddrSubMap_t& AddressPoints, llvm::Value *ThisPtr, uint64_t Offset); diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp index 2f7c79b903..4d40372a56 100644 --- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp +++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp @@ -4,4 +4,4 @@ struct A { virtual void a(); }; A x(A& y) { return y; } // CHECK: define linkonce_odr void @_ZN1AC1ERKS_( -// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) +// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1A, i64 0, i64 2) diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp index 75620ab8e6..bf8575a268 100644 --- a/test/CodeGenCXX/vtable-pointer-initialization.cpp +++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp @@ -21,13 +21,13 @@ struct A : Base { // CHECK: define void @_ZN1AC2Ev( // CHECK: call void @_ZN4BaseC2Ev( -// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) +// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1A, i64 0, i64 2) // CHECK: call void @_ZN5FieldC1Ev( // CHECK: ret void A::A() { } // CHECK: define void @_ZN1AD2Ev( -// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) +// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1A, i64 0, i64 2) // CHECK: call void @_ZN5FieldD1Ev( // CHECK: call void @_ZN4BaseD2Ev( // CHECK: ret void @@ -45,13 +45,13 @@ void f() { B b; } // CHECK: call void @_ZN1BC2Ev( // CHECK: define linkonce_odr void @_ZN1BD1Ev( -// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2) +// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1B, i64 0, i64 2) // CHECK: call void @_ZN5FieldD1Ev( // CHECK: call void @_ZN4BaseD2Ev( // CHECK: ret void // CHECK: define linkonce_odr void @_ZN1BC2Ev( // CHECK: call void @_ZN4BaseC2Ev( -// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2) +// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1B, i64 0, i64 2) // CHECK: call void @_ZN5FieldC1Ev // CHECK: ret void -- 2.40.0