diff options
author | Anders Carlsson <andersca@mac.com> | 2010-01-14 02:29:07 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-01-14 02:29:07 +0000 |
commit | 1bb60990317ba8b8ed138876e70c42f44882bc52 (patch) | |
tree | 126601592f0e0ce515b924f6bc0445b94ab83a95 /lib/CodeGen | |
parent | cb4a4fb7810b46fd7d62f1f1e54299d2229cd8dc (diff) |
Store the address points for constructor vtables directly in the VTT builder, because that's the only time they're needed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93412 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 92 | ||||
-rw-r--r-- | lib/CodeGen/CGVtable.h | 31 |
2 files changed, 99 insertions, 24 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index d2ba77d335..ae900d6ae7 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -160,6 +160,9 @@ private: // vtable for use in computing the initializers for the VTT. llvm::DenseMap<CtorVtable_t, int64_t> &subAddressPoints; + /// AddressPoints - Address points for this vtable. + CGVtableInfo::AddressPointsMapTy& AddressPoints; + typedef CXXRecordDecl::method_iterator method_iter; const uint32_t LLVMPointerWidth; Index_t extra; @@ -192,13 +195,15 @@ private: public: VtableBuilder(const CXXRecordDecl *MostDerivedClass, const CXXRecordDecl *l, uint64_t lo, CodeGenModule &cgm, - bool build) + bool build, CGVtableInfo::AddressPointsMapTy& AddressPoints) : BuildVtable(build), MostDerivedClass(MostDerivedClass), LayoutClass(l), LayoutOffset(lo), BLayout(cgm.getContext().getASTRecordLayout(l)), rtti(0), VMContext(cgm.getModule().getContext()),CGM(cgm), PureVirtualFn(0), subAddressPoints(AllocAddressPoint(cgm, l, MostDerivedClass)), - LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) { + AddressPoints(AddressPoints), + LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) + { Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); if (BuildVtable) { QualType ClassType = CGM.getContext().getTagDeclType(MostDerivedClass); @@ -461,6 +466,7 @@ public: RD->getNameAsCString(), Class->getNameAsCString(), LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint)); subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint; + AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint; // Now also add the address point for all our primary bases. while (1) { @@ -477,6 +483,7 @@ public: RD->getNameAsCString(), Class->getNameAsCString(), LayoutClass->getNameAsCString(), (int)Offset, (int)AddressPoint)); subAddressPoints[std::make_pair(RD, Offset)] = AddressPoint; + AddressPoints[BaseSubobject(RD, Offset)] = AddressPoint; } } @@ -1088,7 +1095,8 @@ CGVtableInfo::getAdjustments(GlobalDecl GD) { if (!SavedAdjustmentRecords.insert(RD).second) return 0; - VtableBuilder b(RD, RD, 0, CGM, false); + AddressPointsMapTy AddressPoints; + VtableBuilder b(RD, RD, 0, CGM, false, AddressPoints); D1(printf("vtable %s\n", RD->getNameAsCString())); b.GenerateVtableForBase(RD); b.GenerateVtableForVBases(RD); @@ -1116,7 +1124,8 @@ int64_t CGVtableInfo::getVirtualBaseOffsetIndex(const CXXRecordDecl *RD, // FIXME: This seems expensive. Can we do a partial job to get // just this data. - VtableBuilder b(RD, RD, 0, CGM, false); + AddressPointsMapTy AddressPoints; + VtableBuilder b(RD, RD, 0, CGM, false, AddressPoints); D1(printf("vtable %s\n", RD->getNameAsCString())); b.GenerateVtableForBase(RD); b.GenerateVtableForVBases(RD); @@ -1146,7 +1155,8 @@ llvm::GlobalVariable * CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, const CXXRecordDecl *LayoutClass, - const CXXRecordDecl *RD, uint64_t Offset) { + const CXXRecordDecl *RD, uint64_t Offset, + AddressPointsMapTy& AddressPoints) { llvm::SmallString<256> OutName; if (LayoutClass != RD) CGM.getMangleContext().mangleCXXCtorVtable(LayoutClass, Offset / 8, @@ -1158,7 +1168,8 @@ CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); if (GV == 0 || CGM.getVtableInfo().AddressPoints[LayoutClass] == 0 || GV->isDeclaration()) { - VtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition); + VtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition, + AddressPoints); D1(printf("vtable %s\n", RD->getNameAsCString())); // First comes the vtables for all the non-virtual bases... @@ -1213,6 +1224,42 @@ class VTTBuilder { llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies; bool GenerateDefinition; + + llvm::DenseMap<BaseSubobject, llvm::Constant *> CtorVtables; + llvm::DenseMap<std::pair<const CXXRecordDecl *, BaseSubobject>, uint64_t> + CtorVtableAddressPoints; + + llvm::Constant *getCtorVtable(const BaseSubobject &Base) { + if (!GenerateDefinition) + return 0; + + llvm::Constant *&CtorVtable = CtorVtables[Base]; + if (!CtorVtable) { + // Build the vtable. + CGVtableInfo::CtorVtableInfo Info + = CGM.getVtableInfo().getCtorVtable(Class, Base); + + CtorVtable = Info.Vtable; + + // Add the address points for this base. + for (CGVtableInfo::AddressPointsMapTy::const_iterator I = + Info.AddressPoints.begin(), E = Info.AddressPoints.end(); + I != E; ++I) { + uint64_t &AddressPoint = + CtorVtableAddressPoints[std::make_pair(Base.getBase(), I->first)]; + + // Check if we already have the address points for this base. + if (AddressPoint) + break; + + // Otherwise, insert it. + AddressPoint = I->second; + } + } + + return CtorVtable; + } + /// BuildVtablePtr - Build up a referene to the given secondary vtable llvm::Constant *BuildVtablePtr(llvm::Constant *Vtable, @@ -1277,7 +1324,7 @@ class VTTBuilder { BuildVtablePtr(vtbl, VtblClass, RD, Offset) : 0; else { init = GenerateDefinition ? - CGM.getVtableInfo().getCtorVtable(Class, Base, BaseOffset) : 0; + getCtorVtable(BaseSubobject(Base, BaseOffset)) : 0; subvtbl = init; subVtblClass = Base; @@ -1306,7 +1353,7 @@ class VTTBuilder { VtableClass = Class; } else { Vtable = GenerateDefinition ? - CGM.getVtableInfo().getCtorVtable(Class, RD, Offset) : 0; + getCtorVtable(BaseSubobject(RD, Offset)) : 0; VtableClass = RD; } @@ -1444,28 +1491,37 @@ void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, return; } - Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0); + AddressPointsMapTy AddressPoints; + Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0, + AddressPoints); GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); } llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) { llvm::GlobalVariable *Vtable = Vtables.lookup(RD); - if (!Vtable) + if (!Vtable) { + AddressPointsMapTy AddressPoints; Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage, - /*GenerateDefinition=*/false, RD, RD, 0); + /*GenerateDefinition=*/false, RD, RD, 0, + AddressPoints); + } return Vtable; } -llvm::GlobalVariable * -CGVtableInfo::getCtorVtable(const CXXRecordDecl *LayoutClass, - const CXXRecordDecl *RD, uint64_t Offset) { - return GenerateVtable(llvm::GlobalValue::InternalLinkage, - /*GenerateDefinition=*/true, - LayoutClass, RD, Offset); +CGVtableInfo::CtorVtableInfo +CGVtableInfo::getCtorVtable(const CXXRecordDecl *RD, + const BaseSubobject &Base) { + CtorVtableInfo Info; + + Info.Vtable = GenerateVtable(llvm::GlobalValue::InternalLinkage, + /*GenerateDefinition=*/true, + RD, Base.getBase(), Base.getBaseOffset(), + Info.AddressPoints); + return Info; } - + llvm::GlobalVariable *CGVtableInfo::getVTT(const CXXRecordDecl *RD) { return GenerateVTT(llvm::GlobalValue::ExternalLinkage, /*GenerateDefinition=*/false, RD); diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h index 0caaec2816..471d6384d6 100644 --- a/lib/CodeGen/CGVtable.h +++ b/lib/CodeGen/CGVtable.h @@ -116,6 +116,11 @@ template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> { } }; +// It's OK to treat BaseSubobject as a POD type. +template <> struct isPodLike<clang::CodeGen::BaseSubobject> { + static const bool value = true; +}; + } namespace clang { @@ -131,6 +136,8 @@ public: typedef llvm::DenseMap<const CXXRecordDecl *, AddrSubMap_t *> AddrMap_t; llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> AddressPoints; + typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; + private: CodeGenModule &CGM; @@ -178,7 +185,8 @@ private: llvm::GlobalVariable * GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, const CXXRecordDecl *LayoutClass, - const CXXRecordDecl *RD, uint64_t Offset); + const CXXRecordDecl *RD, uint64_t Offset, + AddressPointsMapTy& AddressPoints); llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, @@ -218,15 +226,26 @@ public: uint64_t getVtableAddressPoint(const CXXRecordDecl *RD); llvm::GlobalVariable *getVtable(const CXXRecordDecl *RD); - llvm::GlobalVariable *getCtorVtable(const CXXRecordDecl *RD, - const CXXRecordDecl *Class, - uint64_t Offset); + + /// CtorVtableInfo - Information about a constructor vtable. + struct CtorVtableInfo { + /// Vtable - The vtable itself. + llvm::GlobalVariable *Vtable; + + /// AddressPoints - The address points in this constructor vtable. + AddressPointsMapTy AddressPoints; + + CtorVtableInfo() : Vtable(0) { } + }; + + CtorVtableInfo getCtorVtable(const CXXRecordDecl *RD, + const BaseSubobject &Base); llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD); void MaybeEmitVtable(GlobalDecl GD); }; -} -} +} // end namespace CodeGen +} // end namespace clang #endif |