aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-11-10 07:44:33 +0000
committerMike Stump <mrs@apple.com>2009-11-10 07:44:33 +0000
commit380dd759b33fd059b1aa7dbd85f8e66ca32f7bdc (patch)
tree27f20d2450d139bc1fa37d4f20813b524f1c24a4 /lib/CodeGen
parentd7be78a0524251c30329359c9d92485c6d7ac424 (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.cpp2
-rw-r--r--lib/CodeGen/CGVtable.cpp47
-rw-r--r--lib/CodeGen/CGVtable.h4
-rw-r--r--lib/CodeGen/CodeGenFunction.h6
-rw-r--r--lib/CodeGen/CodeGenModule.h6
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);