More vtable work - it's not possible to use the new vtable code for everything by setting a flag inside CGVtable.cpp. My plan is to run some tests and bootstrap and once that's done flip the bit.

llvm-svn: 99804
This commit is contained in:
Anders Carlsson 2010-03-29 03:38:52 +00:00
parent 5a9754187d
commit a627ac7ee6
2 changed files with 78 additions and 22 deletions

View File

@ -3610,16 +3610,24 @@ int64_t CodeGenVTables::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
return I->second;
}
static bool UseNewVTableCode = false;
uint64_t
CodeGenVTables::getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) {
const CodeGenVTables::AddrSubMap_t& AddressPoints = getAddressPoints(RD);
// FIXME: Always use the new vtable code once we know it works.
if (!UseNewVTableCode) {
const CodeGenVTables::AddrSubMap_t& AddressPoints = getAddressPoints(RD);
uint64_t AddressPoint =
AddressPoints.lookup(std::make_pair(Base.getBase(),
Base.getBaseOffset()));
uint64_t AddressPoint =
AddressPoints.lookup(std::make_pair(Base.getBase(),
Base.getBaseOffset()));
assert(AddressPoint && "Address point must not be zero!");
}
uint64_t AddressPoint = AddressPoints.lookup(std::make_pair(RD, Base));
assert(AddressPoint && "Address point must not be zero!");
return AddressPoint;
}
@ -4024,22 +4032,6 @@ void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) {
}
}
void
CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
const CXXRecordDecl *RD) {
llvm::GlobalVariable *&Vtable = Vtables[RD];
if (Vtable) {
assert(Vtable->getInitializer() && "Vtable doesn't have a definition!");
return;
}
llvm::DenseMap<BaseSubobject, uint64_t> AddressPoints;
Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
/*IsVirtual=*/false,
AddressPoints);
GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
}
llvm::Constant *
CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
const uint64_t *Components,
@ -4176,6 +4168,8 @@ GetGlobalVariable(llvm::Module &Module, llvm::StringRef Name,
return GV;
}
// FIXME: When the new code is in place, we can change this to return a
// GlobalVariable.
llvm::Constant *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) {
llvm::SmallString<256> OutName;
CGM.getMangleContext().mangleCXXVtable(RD, OutName);
@ -4186,7 +4180,12 @@ llvm::Constant *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) {
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
llvm::ArrayType *ArrayType =
llvm::ArrayType::get(Int8PtrTy, getNumVTableComponents(RD));
// FIXME: Always use the new vtable code once we know it works.
if (UseNewVTableCode)
return GetGlobalVariable(CGM.getModule(), Name, ArrayType,
llvm::GlobalValue::ExternalLinkage);
llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
if (GV) {
if (!GV->isDeclaration() || GV->getType()->getElementType() == ArrayType)
@ -4201,6 +4200,29 @@ llvm::Constant *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) {
return GV;
}
void
CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable,
llvm::GlobalVariable::LinkageTypes Linkage,
const CXXRecordDecl *RD) {
// Dump the vtable layout if necessary.
if (CGM.getLangOptions().DumpVtableLayouts) {
VtableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD);
Builder.dumpLayout(llvm::errs());
}
assert(VTableThunksMap.count(RD) &&
"No thunk status for this record decl!");
const VTableThunksTy& Thunks = VTableThunksMap[RD];
// Create and set the initializer.
llvm::Constant *Init =
CreateVTableInitializer(RD, getVTableComponentsData(RD),
getNumVTableComponents(RD), Thunks);
VTable->setInitializer(Init);
}
llvm::GlobalVariable *
CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
const BaseSubobject &Base,
@ -4250,6 +4272,28 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
return VTable;
}
void
CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
const CXXRecordDecl *RD) {
llvm::GlobalVariable *&VTable = Vtables[RD];
if (VTable) {
assert(VTable->getInitializer() && "Vtable doesn't have a definition!");
return;
}
// FIXME: Always use the new vtable code once we know it works.
if (UseNewVTableCode) {
VTable = cast<llvm::GlobalVariable>(GetAddrOfVTable(RD));
EmitVTableDefinition(VTable, Linkage, RD);
} else {
llvm::DenseMap<BaseSubobject, uint64_t> AddressPoints;
VTable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
/*IsVirtual=*/false,
AddressPoints);
}
GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
}
void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) {
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
const CXXRecordDecl *RD = MD->getParent();

View File

@ -292,6 +292,13 @@ private:
return VTableLayoutMap.lookup(RD)[0];
}
const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const {
assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
uint64_t *Components = VTableLayoutMap.lookup(RD);
return &Components[1];
}
typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesMapTy;
/// SubVTTIndicies - Contains indices into the various sub-VTTs.
@ -380,6 +387,11 @@ public:
/// GetAddrOfVTable - Get the address of the vtable for the given record decl.
llvm::Constant *GetAddrOfVTable(const CXXRecordDecl *RD);
/// EmitVTableDefinition - Emit the definition of the given vtable.
void EmitVTableDefinition(llvm::GlobalVariable *VTable,
llvm::GlobalVariable::LinkageTypes Linkage,
const CXXRecordDecl *RD);
/// GenerateConstructionVTable - Generate a construction vtable for the given
/// base subobject.
llvm::GlobalVariable *