[cfe-commits] r99508 - in /cfe/trunk/lib/CodeGen: CGVtable.cpp CGVtable.h
Anders Carlsson
andersca at mac.com
Thu Mar 25 08:26:28 PDT 2010
Author: andersca
Date: Thu Mar 25 10:26:28 2010
New Revision: 99508
URL: http://llvm.org/viewvc/llvm-project?rev=99508&view=rev
Log:
When -fdump-vtable-layouts is specified, construction vtable initializers will be generated using the new vtable layout code. (The code is still not completely in place but this is a huge step forward).
Modified:
cfe/trunk/lib/CodeGen/CGVtable.cpp
cfe/trunk/lib/CodeGen/CGVtable.h
Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=99508&r1=99507&r2=99508&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Thu Mar 25 10:26:28 2010
@@ -1328,6 +1328,14 @@
return AddressPoints.end();
}
+ VtableThunksMapTy::const_iterator vtable_thunks_begin() const {
+ return VTableThunks.begin();
+ }
+
+ VtableThunksMapTy::const_iterator vtable_thunks_end() const {
+ return VTableThunks.end();
+ }
+
/// dumpLayout - Dump the vtable layout.
void dumpLayout(llvm::raw_ostream&);
};
@@ -3995,6 +4003,72 @@
GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
}
+llvm::Constant *
+CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
+ const uint64_t *Components,
+ unsigned NumComponents,
+ const VTableThunksTy &VTableThunks) {
+ llvm::SmallVector<llvm::Constant *, 64> Inits;
+
+ const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+
+ for (unsigned I = 0; I != NumComponents; ++I) {
+ // FIXME: Better value.
+ llvm::Constant *Init = llvm::Constant::getNullValue(Int8PtrTy);
+
+ Inits.push_back(Init);
+ }
+
+ llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, NumComponents);
+ return llvm::ConstantArray::get(ArrayType, Inits.data(), Inits.size());
+}
+
+/// GetGlobalVariable - Will return a global variable of the given type.
+/// If a variable with a different type already exists then a new variable
+/// with the right type will be created.
+/// FIXME: We should move this to CodeGenModule and rename it to something
+/// better and then use it in CGVTT and CGRTTI.
+static llvm::GlobalVariable *
+GetGlobalVariable(llvm::Module &Module, llvm::StringRef Name,
+ const llvm::Type *Ty,
+ llvm::GlobalValue::LinkageTypes Linkage) {
+
+ llvm::GlobalVariable *GV = Module.getNamedGlobal(Name);
+ llvm::GlobalVariable *OldGV = 0;
+
+ if (GV) {
+ // Check if the variable has the right type.
+ if (GV->getType()->getElementType() == Ty) {
+ // Set the correct linkage.
+ GV->setLinkage(Linkage);
+ return GV;
+ }
+
+ assert(GV->isDeclaration() && "Declaration has wrong type!");
+
+ OldGV = GV;
+ }
+
+ // Create a new variable.
+ GV = new llvm::GlobalVariable(Module, Ty, /*isConstant=*/true,
+ Linkage, 0, Name);
+
+ if (OldGV) {
+ // Replace occurrences of the old variable if needed.
+ GV->takeName(OldGV);
+
+ if (!OldGV->use_empty()) {
+ llvm::Constant *NewPtrForOldDecl =
+ llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+ OldGV->replaceAllUsesWith(NewPtrForOldDecl);
+ }
+
+ OldGV->eraseFromParent();
+ }
+
+ return GV;
+}
+
llvm::Constant *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) {
llvm::SmallString<256> OutName;
CGM.getMangleContext().mangleCXXVtable(RD, OutName);
@@ -4025,29 +4099,64 @@
const BaseSubobject &Base,
bool BaseIsVirtual,
AddressPointsMapTy& AddressPoints) {
+ if (!CGM.getLangOptions().DumpVtableLayouts) {
+ llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPoints;
- llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPoints;
-
- llvm::GlobalVariable *VTable =
- GenerateVtable(llvm::GlobalValue::InternalLinkage,
- /*GenerateDefinition=*/true,
- RD, Base.getBase(), Base.getBaseOffset(),
- BaseIsVirtual, VTableAddressPoints);
-
- // Add the address points for this base.
- for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
- VTableAddressPoints.begin(), E = VTableAddressPoints.end();
- I != E; ++I) {
+ llvm::GlobalVariable *VTable =
+ GenerateVtable(llvm::GlobalValue::InternalLinkage,
+ /*GenerateDefinition=*/true,
+ RD, Base.getBase(), Base.getBaseOffset(),
+ BaseIsVirtual, VTableAddressPoints);
+
+ // Add the address points for this base.
+ for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I =
+ VTableAddressPoints.begin(), E = VTableAddressPoints.end();
+ I != E; ++I) {
- uint64_t &AddressPoint =
- AddressPoints[std::make_pair(Base.getBase(), I->first)];
+ uint64_t &AddressPoint =
+ AddressPoints[std::make_pair(Base.getBase(), I->first)];
- // Check if we already have the address points for this base.
- assert(!AddressPoint && "Address point already exists for this base!");
+ // Check if we already have the address points for this base.
+ assert(!AddressPoint && "Address point already exists for this base!");
- AddressPoint = I->second;
+ AddressPoint = I->second;
+ }
+
+ return VTable;
}
+ VtableBuilder Builder(*this, Base.getBase(), Base.getBaseOffset(),
+ /*MostDerivedClassIsVirtual=*/BaseIsVirtual, RD);
+
+ Builder.dumpLayout(llvm::errs());
+
+ // Get the mangled construction vtable name.
+ llvm::SmallString<256> OutName;
+ CGM.getMangleContext().mangleCXXCtorVtable(RD, Base.getBaseOffset() / 8,
+ Base.getBase(), OutName);
+ llvm::StringRef Name = OutName.str();
+
+ const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+ llvm::ArrayType *ArrayType =
+ llvm::ArrayType::get(Int8PtrTy, Builder.getNumVTableComponents());
+
+ // Create the variable that will hold the construction vtable.
+ llvm::GlobalVariable *VTable =
+ GetGlobalVariable(CGM.getModule(), Name, ArrayType,
+ llvm::GlobalValue::InternalLinkage);
+
+ // Add the thunks.
+ VTableThunksTy VTableThunks;
+ VTableThunks.append(Builder.vtable_thunks_begin(),
+ Builder.vtable_thunks_end());
+
+ // Create and set the initializer.
+ llvm::Constant *Init =
+ CreateVTableInitializer(Base.getBase(),
+ Builder.vtable_components_data_begin(),
+ Builder.getNumVTableComponents(), VTableThunks);
+ VTable->setInitializer(Init);
+
return VTable;
}
Modified: cfe/trunk/lib/CodeGen/CGVtable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.h?rev=99508&r1=99507&r2=99508&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.h (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.h Thu Mar 25 10:26:28 2010
@@ -274,6 +274,15 @@
/// Address points - Vtable address points.
AddressPointsMapTy AddressPoints;
+ typedef llvm::SmallVector<std::pair<uint64_t, ThunkInfo>, 1>
+ VTableThunksTy;
+
+ typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy>
+ VTableThunksMapTy;
+
+ /// VTableThunksMap - Contains thunks needed by vtables.
+ VTableThunksMapTy VTableThunksMap;
+
uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const {
assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
@@ -310,6 +319,15 @@
/// given record decl.
void ComputeVTableRelatedInformation(const CXXRecordDecl *RD);
+ /// CreateVTableInitializer - Create a vtable initializer for the given record
+ /// decl.
+ /// \param Components - The vtable components; this is really an array of
+ /// VTableComponents.
+ llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD,
+ const uint64_t *Components,
+ unsigned NumComponents,
+ const VTableThunksTy &VTableThunks);
+
public:
CodeGenVTables(CodeGenModule &CGM)
: CGM(CGM) { }
More information about the cfe-commits
mailing list