Patch to move RequiresGCollection bit to

AggValueSlot slot.

llvm-svn: 114045
This commit is contained in:
Fariborz Jahanian 2010-09-16 00:20:07 +00:00
parent 853734e558
commit b60e70f963
3 changed files with 39 additions and 29 deletions

View File

@ -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));
}

View File

@ -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 {

View File

@ -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.