Use stronger typing for the flags on AggValueSlot and require
creators to tell us whether something needs GC barriers. No functionality change. llvm-svn: 138581
This commit is contained in:
parent
7aecbc7661
commit
8d6fc9583d
|
@ -398,8 +398,10 @@ static void EmitBaseInitializer(CodeGenFunction &CGF,
|
|||
BaseClassDecl,
|
||||
isBaseVirtual);
|
||||
|
||||
AggValueSlot AggSlot = AggValueSlot::forAddr(V, Qualifiers(),
|
||||
/*Lifetime*/ true);
|
||||
AggValueSlot AggSlot =
|
||||
AggValueSlot::forAddr(V, Qualifiers(),
|
||||
AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers);
|
||||
|
||||
CGF.EmitAggExpr(BaseInit->getInit(), AggSlot);
|
||||
|
||||
|
@ -436,8 +438,10 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF,
|
|||
CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), Dest,
|
||||
LHS.isVolatileQualified());
|
||||
} else {
|
||||
AggValueSlot Slot = AggValueSlot::forAddr(Dest, LHS.getQuals(),
|
||||
/*Lifetime*/ true);
|
||||
AggValueSlot Slot =
|
||||
AggValueSlot::forAddr(Dest, LHS.getQuals(),
|
||||
AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers);
|
||||
|
||||
CGF.EmitAggExpr(MemberInit->getInit(), Slot);
|
||||
}
|
||||
|
@ -1324,7 +1328,9 @@ CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor
|
|||
llvm::Value *ThisPtr = LoadCXXThis();
|
||||
|
||||
AggValueSlot AggSlot =
|
||||
AggValueSlot::forAddr(ThisPtr, Qualifiers(), /*Lifetime*/ true);
|
||||
AggValueSlot::forAddr(ThisPtr, Qualifiers(),
|
||||
AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers);
|
||||
|
||||
EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot);
|
||||
|
||||
|
|
|
@ -1044,7 +1044,9 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init,
|
|||
StoreComplexToAddr(complex, lvalue.getAddress(), lvalue.isVolatile());
|
||||
} else {
|
||||
// TODO: how can we delay here if D is captured by its initializer?
|
||||
EmitAggExpr(init, AggValueSlot::forLValue(lvalue, true, false));
|
||||
EmitAggExpr(init, AggValueSlot::forLValue(lvalue,
|
||||
AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,8 @@ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
|
|||
} else if (type->isAnyComplexType()) {
|
||||
CGF.EmitComplexExprIntoAddr(Init, DeclPtr, lv.isVolatile());
|
||||
} else {
|
||||
CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv, true));
|
||||
CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1033,7 +1033,8 @@ static void InitCatchParam(CodeGenFunction &CGF,
|
|||
|
||||
// Perform the copy construction.
|
||||
CGF.EmitAggExpr(copyExpr, AggValueSlot::forAddr(ParamAddr, Qualifiers(),
|
||||
false));
|
||||
AggValueSlot::IsNotDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers));
|
||||
|
||||
// Leave the terminate scope.
|
||||
CGF.EHStack.popTerminate();
|
||||
|
|
|
@ -136,7 +136,9 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
|
|||
if (E->getType()->isAnyComplexType())
|
||||
EmitComplexExprIntoAddr(E, Location, Quals.hasVolatile());
|
||||
else if (hasAggregateLLVMType(E->getType()))
|
||||
EmitAggExpr(E, AggValueSlot::forAddr(Location, Quals, IsInit));
|
||||
EmitAggExpr(E, AggValueSlot::forAddr(Location, Quals,
|
||||
AggValueSlot::IsDestructed_t(IsInit),
|
||||
AggValueSlot::DoesNotNeedGCBarriers));
|
||||
else {
|
||||
RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false));
|
||||
LValue LV = MakeAddrLValue(Location, E->getType());
|
||||
|
@ -354,8 +356,11 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
|
|||
!E->getType()->isAnyComplexType()) {
|
||||
ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(),
|
||||
InitializedDecl);
|
||||
AggValueSlot::IsDestructed_t isDestructed
|
||||
= AggValueSlot::IsDestructed_t(InitializedDecl != 0);
|
||||
AggSlot = AggValueSlot::forAddr(ReferenceTemporary, Qualifiers(),
|
||||
InitializedDecl != 0);
|
||||
isDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers);
|
||||
}
|
||||
|
||||
if (InitializedDecl) {
|
||||
|
|
|
@ -71,6 +71,12 @@ public:
|
|||
|
||||
void EmitGCMove(const Expr *E, RValue Src);
|
||||
|
||||
AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
|
||||
if (CGF.getLangOptions().getGCMode() && TypeRequiresGCollection(T))
|
||||
return AggValueSlot::NeedsGCBarriers;
|
||||
return AggValueSlot::DoesNotNeedGCBarriers;
|
||||
}
|
||||
|
||||
bool TypeRequiresGCollection(QualType T);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -426,10 +432,8 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
|
|||
// as it may change the 'forwarding' field via call to Block_copy.
|
||||
LValue RHS = CGF.EmitLValue(E->getRHS());
|
||||
LValue LHS = CGF.EmitLValue(E->getLHS());
|
||||
bool GCollection = false;
|
||||
if (CGF.getContext().getLangOptions().getGCMode())
|
||||
GCollection = TypeRequiresGCollection(E->getLHS()->getType());
|
||||
Dest = AggValueSlot::forLValue(LHS, true, GCollection);
|
||||
Dest = AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
|
||||
needsGC(E->getLHS()->getType()));
|
||||
EmitFinalDestCopy(E, RHS, true);
|
||||
return;
|
||||
}
|
||||
|
@ -451,13 +455,10 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
|
|||
}
|
||||
CGF.EmitStoreThroughPropertyRefLValue(Src, LHS);
|
||||
} else {
|
||||
bool GCollection = false;
|
||||
if (CGF.getContext().getLangOptions().getGCMode())
|
||||
GCollection = TypeRequiresGCollection(E->getLHS()->getType());
|
||||
|
||||
// Codegen the RHS so that it stores directly into the LHS.
|
||||
AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true,
|
||||
GCollection);
|
||||
AggValueSlot LHSSlot =
|
||||
AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
|
||||
needsGC(E->getLHS()->getType()));
|
||||
CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
|
||||
EmitFinalDestCopy(E, LHS, true);
|
||||
}
|
||||
|
@ -596,7 +597,9 @@ AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
|
|||
} else if (type->isAnyComplexType()) {
|
||||
CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
|
||||
} else if (CGF.hasAggregateLLVMType(type)) {
|
||||
CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV, true, false,
|
||||
CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV,
|
||||
AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers,
|
||||
Dest.isZeroed()));
|
||||
} else if (LV.isSimple()) {
|
||||
CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false);
|
||||
|
@ -1036,7 +1039,8 @@ LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
|
|||
assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
|
||||
llvm::Value *Temp = CreateMemTemp(E->getType());
|
||||
LValue LV = MakeAddrLValue(Temp, E->getType());
|
||||
EmitAggExpr(E, AggValueSlot::forLValue(LV, false));
|
||||
EmitAggExpr(E, AggValueSlot::forLValue(LV, AggValueSlot::IsNotDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers));
|
||||
return LV;
|
||||
}
|
||||
|
||||
|
|
|
@ -703,7 +703,9 @@ static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const CXXNewExpr *E,
|
|||
AllocType.isVolatileQualified());
|
||||
else {
|
||||
AggValueSlot Slot
|
||||
= AggValueSlot::forAddr(NewPtr, AllocType.getQualifiers(), true);
|
||||
= AggValueSlot::forAddr(NewPtr, AllocType.getQualifiers(),
|
||||
AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers);
|
||||
CGF.EmitAggExpr(Init, Slot);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -818,7 +818,9 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
|
|||
ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field);
|
||||
LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
|
||||
LoadObjCSelf(), Ivar, 0);
|
||||
EmitAggExpr(IvarInit->getInit(), AggValueSlot::forLValue(LV, true));
|
||||
EmitAggExpr(IvarInit->getInit(),
|
||||
AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers));
|
||||
}
|
||||
// constructor returns 'self'.
|
||||
CodeGenTypes &Types = CGM.getTypes();
|
||||
|
|
|
@ -784,7 +784,9 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
|
|||
} else if (RV->getType()->isAnyComplexType()) {
|
||||
EmitComplexExprIntoAddr(RV, ReturnValue, false);
|
||||
} else {
|
||||
EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Qualifiers(), true));
|
||||
EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Qualifiers(),
|
||||
AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers));
|
||||
}
|
||||
|
||||
EmitBranchThroughCleanup(ReturnBlock);
|
||||
|
|
|
@ -342,57 +342,58 @@ class AggValueSlot {
|
|||
bool LifetimeFlag : 1;
|
||||
bool RequiresGCollection : 1;
|
||||
|
||||
/// IsZeroed - This is set to true if the destination is known to be zero
|
||||
/// ZeroedFlag - This is set to true if the destination is known to be zero
|
||||
/// before the assignment into it. This means that zero fields don't need to
|
||||
/// be set.
|
||||
bool IsZeroed : 1;
|
||||
bool ZeroedFlag : 1;
|
||||
|
||||
public:
|
||||
enum IsZeroed_t { IsNotZeroed, IsZeroed };
|
||||
enum IsDestructed_t { IsNotDestructed, IsDestructed };
|
||||
enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };
|
||||
|
||||
/// ignored - Returns an aggregate value slot indicating that the
|
||||
/// aggregate value is being ignored.
|
||||
static AggValueSlot ignored() {
|
||||
AggValueSlot AV;
|
||||
AV.Addr = 0;
|
||||
AV.Quals = Qualifiers();
|
||||
AV.LifetimeFlag = AV.RequiresGCollection = AV.IsZeroed =0;
|
||||
AV.LifetimeFlag = AV.RequiresGCollection = AV.ZeroedFlag = 0;
|
||||
return AV;
|
||||
}
|
||||
|
||||
/// forAddr - Make a slot for an aggregate value.
|
||||
///
|
||||
/// \param Volatile - true if the slot should be volatile-initialized
|
||||
/// \param quals - The qualifiers that dictate how the slot should
|
||||
/// be initialied. Only 'volatile' and the Objective-C lifetime
|
||||
/// qualifiers matter.
|
||||
///
|
||||
/// \param Qualifiers - The qualifiers that dictate how the slot
|
||||
/// should be initialied. Only 'volatile' and the Objective-C
|
||||
/// lifetime qualifiers matter.
|
||||
///
|
||||
/// \param LifetimeExternallyManaged - true if the slot's lifetime
|
||||
/// is being externally managed; false if a destructor should be
|
||||
/// registered for any temporaries evaluated into the slot
|
||||
/// \param RequiresGCollection - true if the slot is located
|
||||
/// \param isDestructed - true if something else is responsible
|
||||
/// for calling destructors on this object
|
||||
/// \param needsGC - true if the slot is potentially located
|
||||
/// somewhere that ObjC GC calls should be emitted for
|
||||
static AggValueSlot forAddr(llvm::Value *Addr, Qualifiers Quals,
|
||||
bool LifetimeExternallyManaged,
|
||||
bool RequiresGCollection = false,
|
||||
bool IsZeroed = false) {
|
||||
static AggValueSlot forAddr(llvm::Value *addr, Qualifiers quals,
|
||||
IsDestructed_t isDestructed,
|
||||
NeedsGCBarriers_t needsGC,
|
||||
IsZeroed_t isZeroed = IsNotZeroed) {
|
||||
AggValueSlot AV;
|
||||
AV.Addr = Addr;
|
||||
AV.Quals = Quals;
|
||||
AV.LifetimeFlag = LifetimeExternallyManaged;
|
||||
AV.RequiresGCollection = RequiresGCollection;
|
||||
AV.IsZeroed = IsZeroed;
|
||||
AV.Addr = addr;
|
||||
AV.Quals = quals;
|
||||
AV.LifetimeFlag = isDestructed;
|
||||
AV.RequiresGCollection = needsGC;
|
||||
AV.ZeroedFlag = isZeroed;
|
||||
return AV;
|
||||
}
|
||||
|
||||
static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged,
|
||||
bool RequiresGCollection = false,
|
||||
bool IsZeroed = false) {
|
||||
static AggValueSlot forLValue(LValue LV, IsDestructed_t isDestructed,
|
||||
NeedsGCBarriers_t needsGC,
|
||||
IsZeroed_t isZeroed = IsNotZeroed) {
|
||||
return forAddr(LV.getAddress(), LV.getQuals(),
|
||||
LifetimeExternallyManaged, RequiresGCollection, IsZeroed);
|
||||
isDestructed, needsGC, isZeroed);
|
||||
}
|
||||
|
||||
bool isLifetimeExternallyManaged() const {
|
||||
return LifetimeFlag;
|
||||
IsDestructed_t isLifetimeExternallyManaged() const {
|
||||
return IsDestructed_t(LifetimeFlag);
|
||||
}
|
||||
void setLifetimeExternallyManaged(bool Managed = true) {
|
||||
LifetimeFlag = Managed;
|
||||
|
@ -408,8 +409,8 @@ public:
|
|||
return Quals.getObjCLifetime();
|
||||
}
|
||||
|
||||
bool requiresGCollection() const {
|
||||
return RequiresGCollection;
|
||||
NeedsGCBarriers_t requiresGCollection() const {
|
||||
return NeedsGCBarriers_t(RequiresGCollection);
|
||||
}
|
||||
|
||||
llvm::Value *getAddr() const {
|
||||
|
@ -424,9 +425,9 @@ public:
|
|||
return RValue::getAggregate(getAddr(), isVolatile());
|
||||
}
|
||||
|
||||
void setZeroed(bool V = true) { IsZeroed = V; }
|
||||
bool isZeroed() const {
|
||||
return IsZeroed;
|
||||
void setZeroed(bool V = true) { ZeroedFlag = V; }
|
||||
IsZeroed_t isZeroed() const {
|
||||
return IsZeroed_t(ZeroedFlag);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1465,7 +1465,8 @@ public:
|
|||
/// aggregate type.
|
||||
AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp") {
|
||||
return AggValueSlot::forAddr(CreateMemTemp(T, Name), T.getQualifiers(),
|
||||
false);
|
||||
AggValueSlot::IsNotDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers);
|
||||
}
|
||||
|
||||
/// Emit a cast to void* in the appropriate address space.
|
||||
|
|
Loading…
Reference in New Issue