Refine vcalls a little.

llvm-svn: 79400
This commit is contained in:
Mike Stump 2009-08-19 02:06:38 +00:00
parent cc06621280
commit 583ef62149
2 changed files with 54 additions and 42 deletions

View File

@ -707,6 +707,7 @@ class ABIBuilder {
std::vector<llvm::Constant *> &methods;
llvm::Type *Ptr8Ty;
const CXXRecordDecl *Class;
const ASTRecordLayout &BLayout;
llvm::Constant *rtti;
llvm::LLVMContext &VMContext;
CodeGenModule &CGM; // Per-module state.
@ -716,21 +717,34 @@ public:
ABIBuilder(std::vector<llvm::Constant *> &meth,
const CXXRecordDecl *c,
CodeGenModule &cgm)
: methods(meth), Class(c), rtti(cgm.GenerateRtti(c)),
VMContext(cgm.getModule().getContext()), CGM(cgm) {
: methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
CGM(cgm) {
Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
}
void GenerateVcalls(const CXXRecordDecl *RD) {
llvm::Constant *GenerateVcall(const CXXMethodDecl *MD,
const CXXRecordDecl *RD,
bool VBoundary,
bool SecondaryVirtual) {
llvm::Constant *m = 0;
// FIXME: vcall: offset for virtual base for this function
if (SecondaryVirtual || VBoundary)
m = llvm::Constant::getNullValue(Ptr8Ty);
return m;
}
void GenerateVcalls(const CXXRecordDecl *RD, bool VBoundary,
bool SecondaryVirtual) {
llvm::Constant *m;
// FIXME: audit order
for (method_iter mi = RD->method_begin(),
me = RD->method_end(); mi != me; ++mi) {
if (mi->isVirtual()) {
// FIXME: vcall: offset for virtual base for this function
m = llvm::Constant::getNullValue(Ptr8Ty);
methods.push_back(m);
m = GenerateVcall(*mi, RD, VBoundary, SecondaryVirtual);
if (m)
methods.push_back(m);
}
}
}
@ -750,8 +764,8 @@ public:
void GenerateVtableForBase(const CXXRecordDecl *RD,
bool forPrimary,
bool VBoundary,
int64_t Offset,
const CXXRecordDecl *Class,
bool ForVirtualBase,
llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary) {
llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty);
@ -763,6 +777,11 @@ public:
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
if (VBoundary || forPrimary || ForVirtualBase) {
// then comes the the vcall offsets for all our functions...
GenerateVcalls(RD, VBoundary, !forPrimary && ForVirtualBase);
}
// The virtual base offsets come first...
// FIXME: Audit, is this right?
if (forPrimary || !PrimaryBaseWasVirtual) {
@ -774,11 +793,6 @@ public:
methods.push_back(*i);
}
if (forPrimary || ForVirtualBase) {
// then comes the the vcall offsets for all our functions...
GenerateVcalls(RD);
}
bool Top = true;
// vtables are composed from the chain of primaries.
@ -786,15 +800,13 @@ public:
if (PrimaryBaseWasVirtual)
IndirectPrimary.insert(PrimaryBase);
Top = false;
GenerateVtableForBase(PrimaryBase, true, Offset, Class,
PrimaryBaseWasVirtual, IndirectPrimary);
GenerateVtableForBase(PrimaryBase, true, PrimaryBaseWasVirtual|VBoundary,
Offset, PrimaryBaseWasVirtual, IndirectPrimary);
}
if (Top) {
int64_t BaseOffset;
if (ForVirtualBase) {
const ASTRecordLayout &BLayout = CGM.getContext()
.getASTRecordLayout(Class);
BaseOffset = -(BLayout.getVBaseClassOffset(RD) / 8);
} else
BaseOffset = -Offset/8;
@ -816,7 +828,7 @@ public:
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
uint64_t o = Offset + Layout.getBaseClassOffset(Base);
GenerateVtableForBase(Base, true, o, Class, false, IndirectPrimary);
GenerateVtableForBase(Base, true, false, o, false, IndirectPrimary);
}
}
}
@ -831,7 +843,7 @@ public:
if (i->isVirtual() && !IndirectPrimary.count(Base)) {
// Mark it so we don't output it twice.
IndirectPrimary.insert(Base);
GenerateVtableForBase(Base, true, 0, Class, true, IndirectPrimary);
GenerateVtableForBase(Base, false, true, 0, true, IndirectPrimary);
}
if (Base->getNumVBases())
GenerateVtableForVBases(Base, Class, IndirectPrimary);
@ -880,7 +892,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
ABIBuilder b(methods, RD, CGM);
// First comes the vtables for all the non-virtual bases...
b.GenerateVtableForBase(RD, true, 0, RD, false, IndirectPrimary);
b.GenerateVtableForBase(RD, true, false, 0, false, IndirectPrimary);
// then the vtables for all the virtual bases.
b.GenerateVtableForVBases(RD, RD, IndirectPrimary);

View File

@ -228,16 +228,16 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT .space 4 FIXME
// CHECK-LP32: .long 4294967292
// CHECK-LP32-NEXT: .long __ZTI7test5_D
// CHECK-LP32-NEXT: .long __ZN9test5_B237funcB23Ev
// CHECK-LP32-NEXT: .long __ZN9test5_B227funcB22Ev
// CHECK-LP32-NEXT: .long __ZN9test5_B217funcB21Ev
// CHECK-LP32 .space 4
// CHECK-LP32: .long 8
// CHECK-LP32 .long 8 FIXME
// CHECK-LP32: .space 4
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT .space 4 FIXME
// CHECK-LP32: .long 4
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .space 4
@ -280,16 +280,16 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT .space 8 FIXME
// CHECK-LP64: .quad 18446744073709551608
// CHECK-LP64-NEXT: .quad __ZTI7test5_D
// CHECK-LP64-NEXT: .quad __ZN9test5_B237funcB23Ev
// CHECK-LP64-NEXT: .quad __ZN9test5_B227funcB22Ev
// CHECK-LP64-NEXT: .quad __ZN9test5_B217funcB21Ev
// CHECK-LP64 .space 8
// CHECK-LP64: .quad 16
// CHECK-LP64 .quad 16 FIXME
// CHECK-LP64: .space 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT .space 8 FIXME
// CHECK-LP64: .quad 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
@ -337,7 +337,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP32-NEXT: .long 24
// CHECK-LP32-NEXT: .long 16
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32: .long __ZTI7test8_D
// CHECK-LP32-NEXT: .long __ZTI7test8_D
// CHECK-LP32-NEXT: .long __ZN8test8_B19ftest8_B1Ev
// CHECK-LP32-NEXT: .long 20
// CHECK-LP32-NEXT: .long 12
@ -345,10 +345,10 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP32-NEXT: .long __ZTI7test8_D
// CHECK-LP32-NEXT: .long __ZN9test8_B2a10ftest8_B2aEv
// CHECK-LP32-NEXT: .long __ZN8test8_B29ftest8_B2Ev
// CHECK-LP32: .long 4294967288
// CHECK-LP32-NEXT: .long 4294967288
// CHECK-LP32-NEXT: .long __ZTI7test8_D
// CHECK-LP32-NEXT: .long __ZN9test8_B2b10ftest8_B2bEv
// CHECK-LP32: .long 4294967284
// CHECK-LP32-NEXT: .long 4294967284
// CHECK-LP32-NEXT: .long __ZTI7test8_D
// CHECK-LP32-NEXT: .long __ZN8test8_B39ftest8_B3Ev
// CHECK-LP32-NEXT: .space 4
@ -364,7 +364,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP64-NEXT: .quad 48
// CHECK-LP64-NEXT: .quad 32
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64: .quad __ZTI7test8_D
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
// CHECK-LP64-NEXT: .quad __ZN8test8_B19ftest8_B1Ev
// CHECK-LP64-NEXT: .quad 40
// CHECK-LP64-NEXT: .quad 24
@ -372,10 +372,10 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
// CHECK-LP64-NEXT: .quad __ZN9test8_B2a10ftest8_B2aEv
// CHECK-LP64-NEXT: .quad __ZN8test8_B29ftest8_B2Ev
// CHECK-LP64: .quad 18446744073709551600
// CHECK-LP64-NEXT: .quad 18446744073709551600
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
// CHECK-LP64-NEXT: .quad __ZN9test8_B2b10ftest8_B2bEv
// CHECK-LP64: .quad 18446744073709551592
// CHECK-LP64-NEXT: .quad 18446744073709551592
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
// CHECK-LP64-NEXT: .quad __ZN8test8_B39ftest8_B3Ev
// CHECK-LP64-NEXT: .space 8
@ -390,37 +390,37 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP64: __ZTV1B:
// CHECK-LP64: .space 8
// CHECK-LP64: .quad __ZTI1B
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .quad __ZTI1B
// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
// CHECK-LP32: __ZTV1B:
// CHECK-LP32: .space 4
// CHECK-LP32: .long __ZTI1B
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .long __ZTI1B
// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
// CHECK-LP64: __ZTV1A:
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64: .quad __ZTI1A
// CHECK-LP64-NEXT: .quad __ZTI1A
// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
// CHECK-LP64-NEXT: .quad __ZN1A4foo1Ev
// CHECK-LP64-NEXT: .quad __ZN1A4foo2Ev
// CHECK-LP64: .quad 18446744073709551600
// CHECK-LP64-NEXT: .quad 18446744073709551600
// CHECK-LP64-NEXT: .quad __ZTI1A
// CHECK-LP64-NEXT: .quad __ZN1C4bee1Ev
// CHECK-LP64-NEXT: .quad __ZN1C4bee2Ev
// CHECK-LP32: __ZTV1A:
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32: .long __ZTI1A
// CHECK-LP32-NEXT: .long __ZTI1A
// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
// CHECK-LP32-NEXT: .long __ZN1A4foo1Ev
// CHECK-LP32-NEXT: .long __ZN1A4foo2Ev
// CHECK-LP32: .long 4294967284
// CHECK-LP32-NEXT: .long 4294967284
// CHECK-LP32-NEXT: .long __ZTI1A
// CHECK-LP32-NEXT: .long __ZN1C4bee1Ev
// CHECK-LP32-NEXT: .long __ZN1C4bee2Ev
@ -430,7 +430,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP32-NEXT: .long 8
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32: .long __ZTI1F
// CHECK-LP32-NEXT: .long __ZTI1F
// CHECK-LP32-NEXT: .long __ZN1D3booEv
// CHECK-LP32-NEXT: .long __ZN1F3fooEv
// CHECK-LP32-NEXT: .space 4
@ -451,7 +451,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP64-NEXT: .quad 16
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64: .quad __ZTI1F
// CHECK-LP64-NEXT: .quad __ZTI1F
// CHECK-LP64-NEXT: .quad __ZN1D3booEv
// CHECK-LP64-NEXT: .quad __ZN1F3fooEv
// CHECK-LP64-NEXT: .space 8