diff options
author | Mike Stump <mrs@apple.com> | 2009-11-10 07:44:33 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-11-10 07:44:33 +0000 |
commit | 380dd759b33fd059b1aa7dbd85f8e66ca32f7bdc (patch) | |
tree | 27f20d2450d139bc1fa37d4f20813b524f1c24a4 /lib/CodeGen | |
parent | d7be78a0524251c30329359c9d92485c6d7ac424 (diff) |
Add vtable caching to prevent multiple vtables for the same class from
being generated.
Add the most derived vtable pointer to the VTT.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86671 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 47 | ||||
-rw-r--r-- | lib/CodeGen/CGVtable.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 6 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 6 |
5 files changed, 41 insertions, 24 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 0e394b56f5..56b38e57e3 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -1492,7 +1492,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0); VtableField = Builder.CreateBitCast(LoadOfThis, PtrPtr8Ty); - llvm::Value *vtable = GenerateVtable(ClassDecl); + llvm::Value *vtable = CGM.getVtableInfo().getVtable(ClassDecl); Builder.CreateStore(vtable, VtableField); } } diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index e65c213b76..3799695b90 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -681,10 +681,10 @@ int64_t CGVtableInfo::getVirtualBaseOffsetIndex(const CXXRecordDecl *RD, return I->second; } -llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { +llvm::Constant *CodeGenModule::GenerateVtable(const CXXRecordDecl *RD) { llvm::SmallString<256> OutName; llvm::raw_svector_ostream Out(OutName); - mangleCXXVtable(CGM.getMangleContext(), RD, Out); + mangleCXXVtable(getMangleContext(), RD, Out); llvm::GlobalVariable::LinkageTypes linktype; linktype = llvm::GlobalValue::LinkOnceODRLinkage; @@ -692,7 +692,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); int64_t AddressPoint; - VtableBuilder b(methods, RD, CGM); + VtableBuilder b(methods, RD, *this); D1(printf("vtable %s\n", RD->getNameAsCString())); // First comes the vtables for all the non-virtual bases... @@ -701,17 +701,19 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { // then the vtables for all the virtual bases. b.GenerateVtableForVBases(RD); - //GenerateVTT(RD); - llvm::Constant *C; llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size()); C = llvm::ConstantArray::get(type, methods); - llvm::Value *vtable = new llvm::GlobalVariable(CGM.getModule(), type, true, - linktype, C, Out.str()); - vtable = Builder.CreateBitCast(vtable, Ptr8Ty); - vtable = Builder.CreateGEP(vtable, - llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - AddressPoint*LLVMPointerWidth/8)); + llvm::Constant *vtable = new llvm::GlobalVariable(getModule(), type, + true, linktype, C, + Out.str()); + vtable = llvm::ConstantExpr::getBitCast(vtable, Ptr8Ty); + llvm::Constant *AddressPointC; + uint32_t LLVMPointerWidth = getContext().Target.getPointerWidth(0); + AddressPointC = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), + AddressPoint*LLVMPointerWidth/8); + vtable = llvm::ConstantExpr::getGetElementPtr(vtable, &AddressPointC, 1); + return vtable; } @@ -725,28 +727,39 @@ class VTTBuilder { public: VTTBuilder(std::vector<llvm::Constant *> &inits, const CXXRecordDecl *c, CodeGenModule &cgm) : Inits(inits), Class(c), CGM(cgm) { + + Inits.push_back(CGM.getVtableInfo().getVtable(Class)); } }; -llvm::Value *CodeGenFunction::GenerateVTT(const CXXRecordDecl *RD) { +llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) { llvm::SmallString<256> OutName; llvm::raw_svector_ostream Out(OutName); - mangleCXXVTT(CGM.getMangleContext(), RD, Out); + mangleCXXVTT(getMangleContext(), RD, Out); llvm::GlobalVariable::LinkageTypes linktype; linktype = llvm::GlobalValue::LinkOnceODRLinkage; std::vector<llvm::Constant *> inits; llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0); - VTTBuilder b(inits, RD, CGM); + VTTBuilder b(inits, RD, *this); D1(printf("vtt %s\n", RD->getNameAsCString())); llvm::Constant *C; llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, inits.size()); C = llvm::ConstantArray::get(type, inits); - llvm::Value *vtt = new llvm::GlobalVariable(CGM.getModule(), type, true, - linktype, C, Out.str()); - vtt = Builder.CreateBitCast(vtt, Ptr8Ty); + llvm::Constant *vtt = new llvm::GlobalVariable(getModule(), type, true, + linktype, C, Out.str()); + vtt = llvm::ConstantExpr::getBitCast(vtt, Ptr8Ty); return vtt; } + +llvm::Constant *CGVtableInfo::getVtable(const CXXRecordDecl *RD) { + llvm::Constant *&vtbl = Vtables[RD]; + if (vtbl) + return vtbl; + vtbl = CGM.GenerateVtable(RD); + CGM.GenerateVTT(RD); + return vtbl; +} diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h index 69fb1f1005..cdba953718 100644 --- a/lib/CodeGen/CGVtable.h +++ b/lib/CodeGen/CGVtable.h @@ -38,6 +38,8 @@ class CGVtableInfo { /// offsets for virtual bases of a class are stored. typedef llvm::DenseMap<ClassPairTy, int64_t> VirtualBaseClassIndiciesTy; VirtualBaseClassIndiciesTy VirtualBaseClassIndicies; + + llvm::DenseMap<const CXXRecordDecl *, llvm::Constant *> Vtables; public: CGVtableInfo(CodeGenModule &CGM) : CGM(CGM) { } @@ -54,6 +56,8 @@ public: /// base. int64_t getVirtualBaseOffsetIndex(const CXXRecordDecl *RD, const CXXRecordDecl *VBase); + + llvm::Constant *getVtable(const CXXRecordDecl *RD); }; } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index fdbab245d0..593840213a 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -381,12 +381,6 @@ public: /// legal to call this function even if there is no current insertion point. void FinishFunction(SourceLocation EndLoc=SourceLocation()); - /// GenerateVtable - Generate the vtable for the given type. - llvm::Value *GenerateVtable(const CXXRecordDecl *RD); - - /// GenerateVTT - Generate the VTT for the given type. - llvm::Value *GenerateVTT(const CXXRecordDecl *RD); - /// DynamicTypeAdjust - Do the non-virtual and virtual adjustments on an /// object pointer to alter the dynamic type of the pointer. Used by /// GenerateCovariantThunk for building thunks. diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index b09f52cf2b..6c433d9d66 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -252,6 +252,12 @@ public: llvm::Constant *GetAddrOfFunction(GlobalDecl GD, const llvm::Type *Ty = 0); + /// GenerateVtable - Generate the vtable for the given type. + llvm::Constant *GenerateVtable(const CXXRecordDecl *RD); + + /// GenerateVTT - Generate the VTT for the given type. + llvm::Constant *GenerateVTT(const CXXRecordDecl *RD); + /// GenerateRtti - Generate the rtti information for the given type. llvm::Constant *GenerateRtti(const CXXRecordDecl *RD); |