aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-01-14 02:29:07 +0000
committerAnders Carlsson <andersca@mac.com>2010-01-14 02:29:07 +0000
commit1bb60990317ba8b8ed138876e70c42f44882bc52 (patch)
tree126601592f0e0ce515b924f6bc0445b94ab83a95 /lib/CodeGen
parentcb4a4fb7810b46fd7d62f1f1e54299d2229cd8dc (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.cpp92
-rw-r--r--lib/CodeGen/CGVtable.h31
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