forked from OSchip/llvm-project
Add vtable caching to prevent multiple vtables for the same class from
being generated. Add the most derived vtable pointer to the VTT. llvm-svn: 86671
This commit is contained in:
parent
1559bedcc7
commit
d846d0825b
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue