Revert "Generating assumption loads of vptr after ctor call (fixed)"

Reverting because of 245721

This reverts commit 552658e2b60543c928030b09cc9b5dfcb40c3f28.

llvm-svn: 245727
This commit is contained in:
Piotr Padlewski
2015-08-21 19:49:41 +00:00
parent 705ffc1794
commit fa0e11efdd
13 changed files with 128 additions and 425 deletions

View File

@@ -1806,14 +1806,12 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
bool ForVirtualBase,
bool Delegating, llvm::Value *This,
const CXXConstructExpr *E) {
const CXXRecordDecl *ClassDecl = D->getParent();
// C++11 [class.mfct.non-static]p2:
// If a non-static member function of a class X is called for an object that
// is not of type X, or of a type derived from X, the behavior is undefined.
// FIXME: Provide a source location here.
EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, SourceLocation(), This,
getContext().getRecordType(ClassDecl));
getContext().getRecordType(D->getParent()));
if (D->isTrivial() && D->isDefaultConstructor()) {
assert(E->getNumArgs() == 0 && "trivial default ctor with args");
@@ -1829,7 +1827,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
const Expr *Arg = E->getArg(0);
QualType SrcTy = Arg->getType();
llvm::Value *Src = EmitLValue(Arg).getAddress();
QualType DestTy = getContext().getTypeDeclType(ClassDecl);
QualType DestTy = getContext().getTypeDeclType(D->getParent());
EmitAggregateCopyCtor(This, Src, DestTy, SrcTy);
return;
}
@@ -1852,41 +1850,6 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
const CGFunctionInfo &Info =
CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs);
EmitCall(Info, Callee, ReturnValueSlot(), Args, D);
// Generate vtable assumptions if we're constructing a complete object
// with a vtable. We don't do this for base subobjects for two reasons:
// first, it's incorrect for classes with virtual bases, and second, we're
// about to overwrite the vptrs anyway.
if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
ClassDecl->isDynamicClass() && Type != Ctor_Base)
EmitVTableAssumptionLoads(ClassDecl, This);
}
void CodeGenFunction::EmitVTableAssumptionLoad(const VPtr &Vptr,
llvm::Value *This) {
llvm::Value *VTableGlobal =
CGM.getCXXABI().getVTableAddressPoint(Vptr.Base, Vptr.VTableClass);
if (!VTableGlobal)
return;
// We can just use the base offset in the complete class.
CharUnits NonVirtualOffset = Vptr.Base.getBaseOffset();
if (!NonVirtualOffset.isZero())
This =
ApplyNonVirtualAndVirtualOffset(*this, This, NonVirtualOffset, nullptr);
llvm::Value *VPtrValue = GetVTablePtr(This, VTableGlobal->getType());
llvm::Value *Cmp =
Builder.CreateICmpEQ(VPtrValue, VTableGlobal, "cmp.vtables");
Builder.CreateAssumption(Cmp);
}
void CodeGenFunction::EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl,
llvm::Value *This) {
if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))
for (const VPtr &Vptr : getVTablePointers(ClassDecl))
EmitVTableAssumptionLoad(Vptr, This);
}
void
@@ -2054,12 +2017,24 @@ void CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) {
PushDestructorCleanup(D, Addr);
}
void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {
void
CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,
const CXXRecordDecl *NearestVBase,
CharUnits OffsetFromNearestVBase,
const CXXRecordDecl *VTableClass) {
const CXXRecordDecl *RD = Base.getBase();
// Don't initialize the vtable pointer if the class is marked with the
// 'novtable' attribute.
if ((RD == VTableClass || RD == NearestVBase) &&
VTableClass->hasAttr<MSNoVTableAttr>())
return;
// Compute the address point.
bool NeedsVirtualOffset;
llvm::Value *VTableAddressPoint =
CGM.getCXXABI().getVTableAddressPointInStructor(
*this, Vptr.VTableClass, Vptr.Base, Vptr.NearestVBase);
*this, VTableClass, Base, NearestVBase, NeedsVirtualOffset);
if (!VTableAddressPoint)
return;
@@ -2067,15 +2042,17 @@ void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {
llvm::Value *VirtualOffset = nullptr;
CharUnits NonVirtualOffset = CharUnits::Zero();
if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*this, Vptr)) {
if (NeedsVirtualOffset) {
// We need to use the virtual base offset offset because the virtual base
// might have a different offset in the most derived class.
VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(
*this, LoadCXXThis(), Vptr.VTableClass, Vptr.NearestVBase);
NonVirtualOffset = Vptr.OffsetFromNearestVBase;
VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this,
LoadCXXThis(),
VTableClass,
NearestVBase);
NonVirtualOffset = OffsetFromNearestVBase;
} else {
// We can just use the base offset in the complete class.
NonVirtualOffset = Vptr.Base.getBaseOffset();
NonVirtualOffset = Base.getBaseOffset();
}
// Apply the offsets.
@@ -2094,36 +2071,23 @@ void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {
->getPointerTo();
VTableField = Builder.CreateBitCast(VTableField, VTablePtrTy->getPointerTo());
VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy);
llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField);
CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr());
}
CodeGenFunction::VPtrsVector
CodeGenFunction::getVTablePointers(const CXXRecordDecl *VTableClass) {
CodeGenFunction::VPtrsVector VPtrsResult;
VisitedVirtualBasesSetTy VBases;
getVTablePointers(BaseSubobject(VTableClass, CharUnits::Zero()),
/*NearestVBase=*/nullptr,
/*OffsetFromNearestVBase=*/CharUnits::Zero(),
/*BaseIsNonVirtualPrimaryBase=*/false, VTableClass, VBases,
VPtrsResult);
return VPtrsResult;
}
void CodeGenFunction::getVTablePointers(BaseSubobject Base,
const CXXRecordDecl *NearestVBase,
CharUnits OffsetFromNearestVBase,
bool BaseIsNonVirtualPrimaryBase,
const CXXRecordDecl *VTableClass,
VisitedVirtualBasesSetTy &VBases,
VPtrsVector &Vptrs) {
void
CodeGenFunction::InitializeVTablePointers(BaseSubobject Base,
const CXXRecordDecl *NearestVBase,
CharUnits OffsetFromNearestVBase,
bool BaseIsNonVirtualPrimaryBase,
const CXXRecordDecl *VTableClass,
VisitedVirtualBasesSetTy& VBases) {
// If this base is a non-virtual primary base the address point has already
// been set.
if (!BaseIsNonVirtualPrimaryBase) {
// Initialize the vtable pointer for this base.
VPtr Vptr = {Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
Vptrs.push_back(Vptr);
InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase,
VTableClass);
}
const CXXRecordDecl *RD = Base.getBase();
@@ -2161,10 +2125,11 @@ void CodeGenFunction::getVTablePointers(BaseSubobject Base,
BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl;
}
getVTablePointers(
BaseSubobject(BaseDecl, BaseOffset),
I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset),
I.isVirtual() ? BaseDecl : NearestVBase,
BaseOffsetFromNearestVBase,
BaseDeclIsNonVirtualPrimaryBase,
VTableClass, VBases);
}
}
@@ -2174,9 +2139,11 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) {
return;
// Initialize the vtable pointers for this class and all of its bases.
if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD))
for (const VPtr &Vptr : getVTablePointers(RD))
InitializeVTablePointer(Vptr);
VisitedVirtualBasesSetTy VBases;
InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()),
/*NearestVBase=*/nullptr,
/*OffsetFromNearestVBase=*/CharUnits::Zero(),
/*BaseIsNonVirtualPrimaryBase=*/false, RD, VBases);
if (RD->getNumVBases())
CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD);