[cfe-commits] r81067 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CodeGenFunction.h CodeGenModule.h Mangle.cpp Mangle.h
Mike Stump
mrs at apple.com
Sat Sep 5 00:20:32 PDT 2009
Author: mrs
Date: Sat Sep 5 02:20:32 2009
New Revision: 81067
URL: http://llvm.org/viewvc/llvm-project?rev=81067&view=rev
Log:
Install thunks later to fixup overrides. Track space taken by vbase
offsets better for thunk refinements. Cleanups. WIP.
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/Mangle.cpp
cfe/trunk/lib/CodeGen/Mangle.h
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=81067&r1=81066&r2=81067&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Sat Sep 5 02:20:32 2009
@@ -855,17 +855,23 @@
llvm::DenseMap<const CXXMethodDecl *, Index_t> Index;
llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall;
llvm::DenseMap<const CXXMethodDecl *, Index_t> VCallOffset;
+ typedef llvm::DenseMap<const CXXMethodDecl *,
+ std::pair<Index_t, Index_t> > Thunks_t;
+ Thunks_t Thunks;
std::vector<Index_t> VCalls;
typedef CXXRecordDecl::method_iterator method_iter;
// FIXME: Linkage should follow vtable
const bool Extern;
+ const uint32_t LLVMPointerWidth;
+ Index_t extra;
public:
VtableBuilder(std::vector<llvm::Constant *> &meth,
const CXXRecordDecl *c,
CodeGenModule &cgm)
: methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
- CGM(cgm), Extern(true) {
+ CGM(cgm), Extern(true),
+ LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) {
Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
}
@@ -913,7 +919,6 @@
// and just replace each instance of an overridden method once. Would be
// nice to measure the cost/benefit on real code.
- // If we can find a previously allocated slot for this, reuse it.
for (meth_iter mi = MD->begin_overridden_methods(),
e = MD->end_overridden_methods();
mi != e; ++mi) {
@@ -925,28 +930,51 @@
for (Index_t i = AddressPoint, e = submethods.size();
i != e; ++i) {
// FIXME: begin_overridden_methods might be too lax, covariance */
- if (submethods[i] == om) {
- int64_t O = VCallOffset[OMD] - Offset/8;
- // FIXME: thunks
- if (O) {
- submethods[i] = CGM.BuildThunk(MD, Extern, true, 0, O);
- } else
- submethods[i] = m;
- // FIXME: audit
- Index[MD] = i - AddressPoint;
- if (MorallyVirtual) {
- VCallOffset[MD] = Offset/8;
- VCalls[VCall[OMD]] = Offset/8 - VCallOffset[OMD];
+ if (submethods[i] != om)
+ continue;
+ submethods[i] = m;
+ Index[MD] = i - AddressPoint;
+
+ Thunks.erase(OMD);
+ if (MorallyVirtual) {
+ VCallOffset[MD] = Offset/8;
+ Index_t &idx = VCall[OMD];
+ if (idx == 0) {
+ idx = VCalls.size()+1;
+ VCalls.push_back(0);
}
- // submethods[VCall[OMD]] = wrap(Offset/8 - VCallOffset[OMD]);
+ VCalls[idx] = Offset/8 - VCallOffset[OMD];
+ VCall[MD] = idx;
+ // FIXME: 0?
+ Thunks[MD] = std::make_pair(0, -((idx+extra+2)*LLVMPointerWidth/8));
return true;
}
+#if 0
+ // FIXME: finish off
+ int64_t O = VCallOffset[OMD] - Offset/8;
+ if (O) {
+ Thunks[MD] = std::make_pair(O, 0);
+ }
+#endif
+ return true;
}
}
return false;
}
+ void InstallThunks(Index_t AddressPoint) {
+ for (Thunks_t::iterator i = Thunks.begin(), e = Thunks.end();
+ i != e; ++i) {
+ const CXXMethodDecl *MD = i->first;
+ Index_t idx = Index[MD];
+ Index_t nv_O = i->second.first;
+ Index_t v_O = i->second.second;
+ methods[AddressPoint + idx] = CGM.BuildThunk(MD, Extern, nv_O, v_O);
+ }
+ Thunks.clear();
+ }
+
void OverrideMethods(const CXXRecordDecl *RD, Index_t AddressPoint,
bool MorallyVirtual, Index_t Offset) {
for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
@@ -961,19 +989,18 @@
void AddMethod(const CXXMethodDecl *MD, Index_t AddressPoint,
bool MorallyVirtual, Index_t Offset) {
llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty));
+ // If we can find a previously allocated slot for this, reuse it.
if (OverrideMethod(MD, m, MorallyVirtual, Offset, submethods, 0))
return;
// else allocate a new slot.
Index[MD] = submethods.size();
- // VCall[MD] = Offset;
if (MorallyVirtual) {
VCallOffset[MD] = Offset/8;
Index_t &idx = VCall[MD];
// Allocate the first one, after that, we reuse the previous one.
if (idx == 0) {
idx = VCalls.size()+1;
- VCallOffset[MD] = Offset/8;
VCalls.push_back(0);
}
}
@@ -988,6 +1015,27 @@
AddMethod(*mi, AddressPoint, MorallyVirtual, Offset);
}
+ void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout,
+ const CXXRecordDecl *PrimaryBase,
+ bool PrimaryBaseWasVirtual, bool MorallyVirtual,
+ int64_t Offset) {
+ for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
+ e = RD->bases_end(); i != e; ++i) {
+ if (i->isVirtual())
+ continue;
+ const CXXRecordDecl *Base =
+ cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+ if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
+ uint64_t o = Offset + Layout.getBaseClassOffset(Base);
+ StartNewTable();
+ Index_t AP;
+ AP = GenerateVtableForBase(Base, true, true, MorallyVirtual, o, false);
+ OverrideMethods(RD, AP, MorallyVirtual, o);
+ InstallThunks(AP);
+ }
+ }
+ }
+
int64_t GenerateVtableForBase(const CXXRecordDecl *RD, bool forPrimary,
bool Bottom, bool MorallyVirtual,
int64_t Offset, bool ForVirtualBase) {
@@ -1004,8 +1052,12 @@
std::vector<llvm::Constant *> offsets;
// FIXME: Audit, is this right?
if (Bottom && (PrimaryBase == 0 || forPrimary || !PrimaryBaseWasVirtual
- || Bottom))
+ || Bottom)) {
+ extra = 0;
GenerateVBaseOffsets(offsets, RD, Offset);
+ if (ForVirtualBase)
+ extra = offsets.size();
+ }
bool Top = true;
@@ -1026,6 +1078,7 @@
return AddressPoint;
StartNewTable();
+ extra = 0;
// FIXME: Cleanup.
if (!ForVirtualBase) {
// then virtual base offsets...
@@ -1054,22 +1107,11 @@
methods.insert(methods.end(), submethods.begin(), submethods.end());
submethods.clear();
+ InstallThunks(AddressPoint);
// and then the non-virtual bases.
- for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
- e = RD->bases_end(); i != e; ++i) {
- if (i->isVirtual())
- continue;
- const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
- if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
- uint64_t o = Offset + Layout.getBaseClassOffset(Base);
- StartNewTable();
- Index_t AP;
- AP = GenerateVtableForBase(Base, true, true, MorallyVirtual, o, false);
- OverrideMethods(RD, AP, MorallyVirtual, o);
- }
- }
+ NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual, MorallyVirtual,
+ Offset);
return AddressPoint;
}
@@ -1087,6 +1129,7 @@
Index_t AP;
AP = GenerateVtableForBase(Base, false, true, true, BaseOffset, true);
OverrideMethods(RD, AP, true, BaseOffset);
+ InstallThunks(AP);
}
if (Base->getNumVBases())
GenerateVtableForVBases(Base, Class);
@@ -1168,8 +1211,8 @@
llvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn,
const CXXMethodDecl *MD,
- bool Extern, bool Virtual,
- int64_t nv, int64_t v) {
+ bool Extern, int64_t nv,
+ int64_t v) {
QualType R = MD->getType()->getAsFunctionType()->getResultType();
FunctionArgList Args;
@@ -1198,12 +1241,11 @@
return Fn;
}
-llvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD,
- bool Extern, bool Virtual, int64_t nv,
- int64_t v) {
+llvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern,
+ int64_t nv, int64_t v) {
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
- mangleThunk(MD, Virtual, nv, v, getContext(), Out);
+ mangleThunk(MD, nv, v, getContext(), Out);
llvm::GlobalVariable::LinkageTypes linktype;
linktype = llvm::GlobalValue::WeakAnyLinkage;
if (!Extern)
@@ -1216,7 +1258,7 @@
llvm::Function *Fn = llvm::Function::Create(FTy, linktype, Out.str(),
&getModule());
- CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, Virtual, nv, v);
+ CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, nv, v);
// Fn = Builder.CreateBitCast(Fn, Ptr8Ty);
llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
return m;
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=81067&r1=81066&r2=81067&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sat Sep 5 02:20:32 2009
@@ -366,8 +366,7 @@
/// GenerateThunk - Generate a thunk for the given method
llvm::Constant *GenerateThunk(llvm::Function *Fn, const CXXMethodDecl *MD,
- bool Extern, bool Virtual, int64_t nv,
- int64_t v);
+ bool Extern, int64_t nv, int64_t v);
void EmitCtorPrologue(const CXXConstructorDecl *CD);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=81067&r1=81066&r2=81067&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Sat Sep 5 02:20:32 2009
@@ -236,8 +236,8 @@
llvm::Constant *GenerateRtti(const CXXRecordDecl *RD);
/// BuildThunk - Build a thunk for the given method
- llvm::Constant *BuildThunk(const CXXMethodDecl *MD, bool Extern, bool Virtual,
- int64_t nv, int64_t v);
+ llvm::Constant *BuildThunk(const CXXMethodDecl *MD, bool Extern, int64_t nv,
+ int64_t v);
/// GetStringForStringLiteral - Return the appropriate bytes for a string
/// literal, properly padded to match the literal type. If only the address of
Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=81067&r1=81066&r2=81067&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Sat Sep 5 02:20:32 2009
@@ -39,10 +39,10 @@
: Context(C), Out(os), Structor(0), StructorType(0) { }
bool mangle(const NamedDecl *D);
- void mangleCalloffset(bool Virtual, int64_t nv, int64_t v);
- void mangleThunk(const NamedDecl *ND, bool Virtual, int64_t nv, int64_t v);
- void mangleCovariantThunk(const NamedDecl *ND, bool VirtualThis,
- int64_t nv_t, int64_t v_t, bool VirtualResult,
+ void mangleCalloffset(int64_t nv, int64_t v);
+ void mangleThunk(const NamedDecl *ND, int64_t nv, int64_t v);
+ void mangleCovariantThunk(const NamedDecl *ND,
+ int64_t nv_t, int64_t v_t,
int64_t nv_r, int64_t v_r);
void mangleGuardVariable(const VarDecl *D);
@@ -241,14 +241,13 @@
mangleNestedName(ND);
}
-void CXXNameMangler::mangleCalloffset(bool Virtual, int64_t nv,
- int64_t v) {
+void CXXNameMangler::mangleCalloffset(int64_t nv, int64_t v) {
// <call-offset> ::= h <nv-offset> _
// ::= v <v-offset> _
// <nv-offset> ::= <offset number> # non-virtual base override
// <v-offset> ::= <offset nubmer> _ <virtual offset number>
// # virtual base override, with vcall offset
- if (!Virtual) {
+ if (v == 0) {
Out << "h";
if (nv < 0) {
Out << "n";
@@ -272,26 +271,24 @@
Out << "_";
}
-void CXXNameMangler::mangleThunk(const NamedDecl *D, bool Virtual, int64_t nv,
- int64_t v) {
+void CXXNameMangler::mangleThunk(const NamedDecl *D, int64_t nv, int64_t v) {
// <special-name> ::= T <call-offset> <base encoding>
// # base is the nominal target function of thunk
Out << "_T";
- mangleCalloffset(Virtual, nv, v);
+ mangleCalloffset(nv, v);
mangleName(D);
}
void CXXNameMangler::mangleCovariantThunk(const NamedDecl *D,
- bool VirtualThis, int64_t nv_t,
- int64_t v_t, bool VirtualResult,
+ int64_t nv_t, int64_t v_t,
int64_t nv_r, int64_t v_r) {
// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
// # base is the nominal target function of thunk
// # first call-offset is 'this' adjustment
// # second call-offset is result adjustment
Out << "_Tc";
- mangleCalloffset(VirtualThis, nv_t, v_t);
- mangleCalloffset(VirtualResult, nv_r, v_r);
+ mangleCalloffset(nv_t, v_t);
+ mangleCalloffset(nv_r, v_r);
mangleName(D);
}
@@ -859,7 +856,7 @@
/// \brief Mangles the a thunk with the offset n for the declaration D and
/// emits that name to the given output stream.
- void mangleThunk(const NamedDecl *D, bool Virtual, int64_t nv, int64_t v,
+ void mangleThunk(const NamedDecl *D, int64_t nv, int64_t v,
ASTContext &Context, llvm::raw_ostream &os) {
// FIXME: Hum, we might have to thunk these, fix.
assert(!isa<CXXConstructorDecl>(D) &&
@@ -868,15 +865,14 @@
"Use mangleCXXDtor for destructor decls!");
CXXNameMangler Mangler(Context, os);
- Mangler.mangleThunk(D, Virtual, nv, v);
+ Mangler.mangleThunk(D, nv, v);
os.flush();
}
/// \brief Mangles the a covariant thunk for the declaration D and emits that
/// name to the given output stream.
- void mangleCovariantThunk(const NamedDecl *D, bool VirtualThis, int64_t nv_t,
- int64_t v_t, bool VirtualResult, int64_t nv_r,
- int64_t v_r, ASTContext &Context,
+ void mangleCovariantThunk(const NamedDecl *D, int64_t nv_t, int64_t v_t,
+ int64_t nv_r, int64_t v_r, ASTContext &Context,
llvm::raw_ostream &os) {
// FIXME: Hum, we might have to thunk these, fix.
assert(!isa<CXXConstructorDecl>(D) &&
@@ -885,8 +881,7 @@
"Use mangleCXXDtor for destructor decls!");
CXXNameMangler Mangler(Context, os);
- Mangler.mangleCovariantThunk(D, VirtualThis, nv_t, v_t, VirtualResult,
- nv_r, v_r);
+ Mangler.mangleCovariantThunk(D, nv_t, v_t, nv_r, v_r);
os.flush();
}
Modified: cfe/trunk/lib/CodeGen/Mangle.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.h?rev=81067&r1=81066&r2=81067&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.h (original)
+++ cfe/trunk/lib/CodeGen/Mangle.h Sat Sep 5 02:20:32 2009
@@ -34,7 +34,7 @@
bool mangleName(const NamedDecl *D, ASTContext &Context,
llvm::raw_ostream &os);
- void mangleThunk(const NamedDecl *D, bool Virtual, int64_t n, int64_t vn,
+ void mangleThunk(const NamedDecl *D, int64_t n, int64_t vn,
ASTContext &Context, llvm::raw_ostream &os);
void mangleCovariantThunk(const NamedDecl *D, bool VirtualThis, int64_t nv_t,
int64_t v_t, bool VirtualResult, int64_t nv_r,
More information about the cfe-commits
mailing list