Patch to move RequiresGCollection bit to
AggValueSlot slot. llvm-svn: 114045
This commit is contained in:
parent
853734e558
commit
b60e70f963
|
@ -34,13 +34,12 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
|
|||
CGBuilderTy &Builder;
|
||||
AggValueSlot Dest;
|
||||
bool IgnoreResult;
|
||||
bool RequiresGCollection;
|
||||
|
||||
ReturnValueSlot getReturnValueSlot() const {
|
||||
// If the destination slot requires garbage collection, we can't
|
||||
// use the real return value slot, because we have to use the GC
|
||||
// API.
|
||||
if (RequiresGCollection) return ReturnValueSlot();
|
||||
if (Dest.isRequiresGCollection()) return ReturnValueSlot();
|
||||
|
||||
return ReturnValueSlot(Dest.getAddr(), Dest.isVolatile());
|
||||
}
|
||||
|
@ -52,9 +51,9 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
|
|||
|
||||
public:
|
||||
AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest,
|
||||
bool ignore, bool requiresGCollection)
|
||||
bool ignore)
|
||||
: CGF(cgf), Builder(CGF.Builder), Dest(Dest),
|
||||
IgnoreResult(ignore), RequiresGCollection(requiresGCollection) {
|
||||
IgnoreResult(ignore) {
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -178,7 +177,7 @@ bool AggExprEmitter::TypeRequiresGCollection(QualType T) {
|
|||
/// directly into the return value slot. If GC does interfere, a final
|
||||
/// move will be performed.
|
||||
void AggExprEmitter::EmitGCMove(const Expr *E, RValue Src) {
|
||||
if (RequiresGCollection) {
|
||||
if (Dest.isRequiresGCollection()) {
|
||||
std::pair<uint64_t, unsigned> TypeInfo =
|
||||
CGF.getContext().getTypeInfo(E->getType());
|
||||
unsigned long size = TypeInfo.first/8;
|
||||
|
@ -211,7 +210,7 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
|
|||
Dest = CGF.CreateAggTemp(E->getType(), "agg.tmp");
|
||||
}
|
||||
|
||||
if (RequiresGCollection) {
|
||||
if (Dest.isRequiresGCollection()) {
|
||||
std::pair<uint64_t, unsigned> TypeInfo =
|
||||
CGF.getContext().getTypeInfo(E->getType());
|
||||
unsigned long size = TypeInfo.first/8;
|
||||
|
@ -370,13 +369,14 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
|
|||
CGF.EmitAggExpr(E->getRHS(), Slot);
|
||||
CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), Slot.asRValue());
|
||||
} else {
|
||||
bool RequiresGCollection = false;
|
||||
bool GCollection = false;
|
||||
if (CGF.getContext().getLangOptions().getGCMode())
|
||||
RequiresGCollection = TypeRequiresGCollection(E->getLHS()->getType());
|
||||
GCollection = TypeRequiresGCollection(E->getLHS()->getType());
|
||||
|
||||
// Codegen the RHS so that it stores directly into the LHS.
|
||||
AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true);
|
||||
CGF.EmitAggExpr(E->getRHS(), LHSSlot, false, RequiresGCollection);
|
||||
AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true,
|
||||
GCollection);
|
||||
CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
|
||||
EmitFinalDestCopy(E, LHS, true);
|
||||
}
|
||||
}
|
||||
|
@ -646,14 +646,13 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
|
|||
//
|
||||
// FIXME: Take Qualifiers object.
|
||||
void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot,
|
||||
bool IgnoreResult,
|
||||
bool RequiresGCollection) {
|
||||
bool IgnoreResult) {
|
||||
assert(E && hasAggregateLLVMType(E->getType()) &&
|
||||
"Invalid aggregate expression to emit");
|
||||
assert((Slot.getAddr() != 0 || Slot.isIgnored())
|
||||
&& "slot has bits but no address");
|
||||
|
||||
AggExprEmitter(*this, Slot, IgnoreResult, RequiresGCollection)
|
||||
AggExprEmitter(*this, Slot, IgnoreResult)
|
||||
.Visit(const_cast<Expr*>(E));
|
||||
}
|
||||
|
||||
|
|
|
@ -323,12 +323,13 @@ public:
|
|||
|
||||
/// An aggregate value slot.
|
||||
class AggValueSlot {
|
||||
/// The address and associated flags.
|
||||
/// The address.
|
||||
uintptr_t AddrAndFlags;
|
||||
|
||||
static const uintptr_t VolatileFlag = 0x1;
|
||||
static const uintptr_t LifetimeFlag = 0x2;
|
||||
static const uintptr_t AddrMask = ~(VolatileFlag | LifetimeFlag);
|
||||
|
||||
// Associated flags.
|
||||
bool VolatileFlag : 1;
|
||||
bool LifetimeFlag : 1;
|
||||
bool RequiresGCollection : 1;
|
||||
|
||||
public:
|
||||
/// ignored - Returns an aggregate value slot indicating that the
|
||||
|
@ -336,6 +337,7 @@ public:
|
|||
static AggValueSlot ignored() {
|
||||
AggValueSlot AV;
|
||||
AV.AddrAndFlags = 0;
|
||||
AV.VolatileFlag = AV.LifetimeFlag = AV.RequiresGCollection = 0;
|
||||
return AV;
|
||||
}
|
||||
|
||||
|
@ -346,32 +348,42 @@ public:
|
|||
/// is being externally managed; false if a destructor should be
|
||||
/// registered for any temporaries evaluated into the slot
|
||||
static AggValueSlot forAddr(llvm::Value *Addr, bool Volatile,
|
||||
bool LifetimeExternallyManaged) {
|
||||
bool LifetimeExternallyManaged,
|
||||
bool RequiresGCollection=false) {
|
||||
AggValueSlot AV;
|
||||
AV.AddrAndFlags = reinterpret_cast<uintptr_t>(Addr);
|
||||
if (Volatile) AV.AddrAndFlags |= VolatileFlag;
|
||||
if (LifetimeExternallyManaged) AV.AddrAndFlags |= LifetimeFlag;
|
||||
if (Volatile) AV.VolatileFlag = 1;
|
||||
if (LifetimeExternallyManaged) AV.LifetimeFlag = 1;
|
||||
if (RequiresGCollection) AV.RequiresGCollection = 1;
|
||||
return AV;
|
||||
}
|
||||
|
||||
static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged) {
|
||||
static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged,
|
||||
bool RequiresGCollection=false) {
|
||||
return forAddr(LV.getAddress(), LV.isVolatileQualified(),
|
||||
LifetimeExternallyManaged);
|
||||
LifetimeExternallyManaged, RequiresGCollection);
|
||||
}
|
||||
|
||||
bool isLifetimeExternallyManaged() const {
|
||||
return AddrAndFlags & LifetimeFlag;
|
||||
return LifetimeFlag;
|
||||
}
|
||||
void setLifetimeExternallyManaged() {
|
||||
AddrAndFlags |= LifetimeFlag;
|
||||
LifetimeFlag = 1;
|
||||
}
|
||||
|
||||
bool isVolatile() const {
|
||||
return AddrAndFlags & VolatileFlag;
|
||||
return VolatileFlag;
|
||||
}
|
||||
|
||||
bool isRequiresGCollection() const {
|
||||
return RequiresGCollection;
|
||||
}
|
||||
void setRequiresGCollection() {
|
||||
RequiresGCollection = 1;
|
||||
}
|
||||
|
||||
llvm::Value *getAddr() const {
|
||||
return reinterpret_cast<llvm::Value*>(AddrAndFlags & AddrMask);
|
||||
return reinterpret_cast<llvm::Value*>(AddrAndFlags);
|
||||
}
|
||||
|
||||
bool isIgnored() const {
|
||||
|
|
|
@ -1551,8 +1551,7 @@ public:
|
|||
/// EmitAggExpr - Emit the computation of the specified expression
|
||||
/// of aggregate type. The result is computed into the given slot,
|
||||
/// which may be null to indicate that the value is not needed.
|
||||
void EmitAggExpr(const Expr *E, AggValueSlot AS, bool IgnoreResult = false,
|
||||
bool RequiresGCollection = false);
|
||||
void EmitAggExpr(const Expr *E, AggValueSlot AS, bool IgnoreResult = false);
|
||||
|
||||
/// EmitAggExprToLValue - Emit the computation of the specified expression of
|
||||
/// aggregate type into a temporary LValue.
|
||||
|
|
Loading…
Reference in New Issue