IRgen: Assignment to Objective-C properties shouldn't reload the value, for

complex values either. Previously we did this properly for regular assignment,
but not for compound assignment.
 - Also, tidy up assignment code a bit to look more like the scalar path.

llvm-svn: 107217
This commit is contained in:
Daniel Dunbar 2010-06-29 22:44:21 +00:00
parent 466b1419c6
commit 8c94ffe776
2 changed files with 40 additions and 38 deletions

View File

@ -523,20 +523,20 @@ EmitCompoundAssign(const CompoundAssignOperator *E,
OpInfo.Ty = E->getComputationResultType(); OpInfo.Ty = E->getComputationResultType();
OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty); OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty);
LValue LHSLV = CGF.EmitLValue(E->getLHS()); LValue LHS = CGF.EmitLValue(E->getLHS());
// We know the LHS is a complex lvalue. // We know the LHS is a complex lvalue.
ComplexPairTy LHSComplexPair; ComplexPairTy LHSComplexPair;
if (LHSLV.isPropertyRef()) if (LHS.isPropertyRef())
LHSComplexPair = LHSComplexPair =
CGF.EmitObjCPropertyGet(LHSLV.getPropertyRefExpr()).getComplexVal(); CGF.EmitObjCPropertyGet(LHS.getPropertyRefExpr()).getComplexVal();
else if (LHSLV.isKVCRef()) else if (LHS.isKVCRef())
LHSComplexPair = LHSComplexPair =
CGF.EmitObjCPropertyGet(LHSLV.getKVCRefExpr()).getComplexVal(); CGF.EmitObjCPropertyGet(LHS.getKVCRefExpr()).getComplexVal();
else else
LHSComplexPair = EmitLoadOfComplex(LHSLV.getAddress(), LHSComplexPair = EmitLoadOfComplex(LHS.getAddress(),
LHSLV.isVolatileQualified()); LHS.isVolatileQualified());
OpInfo.LHS=EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty); OpInfo.LHS = EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty);
// Expand the binary operator. // Expand the binary operator.
ComplexPairTy Result = (this->*Func)(OpInfo); ComplexPairTy Result = (this->*Func)(OpInfo);
@ -545,23 +545,26 @@ EmitCompoundAssign(const CompoundAssignOperator *E,
Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy); Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
// Store the result value into the LHS lvalue. // Store the result value into the LHS lvalue.
if (LHSLV.isPropertyRef()) if (LHS.isPropertyRef())
CGF.EmitObjCPropertySet(LHSLV.getPropertyRefExpr(), CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
RValue::getComplex(Result)); RValue::getComplex(Result));
else if (LHSLV.isKVCRef()) else if (LHS.isKVCRef())
CGF.EmitObjCPropertySet(LHSLV.getKVCRefExpr(), RValue::getComplex(Result)); CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Result));
else else
EmitStoreOfComplex(Result, LHSLV.getAddress(), LHSLV.isVolatileQualified()); EmitStoreOfComplex(Result, LHS.getAddress(), LHS.isVolatileQualified());
// And now return the LHS
// Restore the Ignore* flags.
IgnoreReal = ignreal; IgnoreReal = ignreal;
IgnoreImag = ignimag; IgnoreImag = ignimag;
IgnoreRealAssign = ignreal; IgnoreRealAssign = ignreal;
IgnoreImagAssign = ignimag; IgnoreImagAssign = ignimag;
if (LHSLV.isPropertyRef())
return CGF.EmitObjCPropertyGet(LHSLV.getPropertyRefExpr()).getComplexVal(); // Objective-C property assignment never reloads the value following a store.
else if (LHSLV.isKVCRef()) if (LHS.isPropertyRef() || LHS.isKVCRef())
return CGF.EmitObjCPropertyGet(LHSLV.getKVCRefExpr()).getComplexVal(); return Result;
return EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified());
// Otherwise, reload the value.
return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
} }
ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
@ -578,31 +581,26 @@ ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
// Compute the address to store into. // Compute the address to store into.
LValue LHS = CGF.EmitLValue(E->getLHS()); LValue LHS = CGF.EmitLValue(E->getLHS());
// Store into it, if simple. // Store the result value into the LHS lvalue.
if (LHS.isSimple()) {
EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
// And now return the LHS
IgnoreReal = ignreal;
IgnoreImag = ignimag;
IgnoreRealAssign = ignreal;
IgnoreImagAssign = ignimag;
return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
}
// Otherwise we must have a property setter (no complex vector/bitfields).
if (LHS.isPropertyRef()) if (LHS.isPropertyRef())
CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val)); CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val));
else else if (LHS.isKVCRef())
CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val)); CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val));
else
EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
// There is no reload after a store through a method, but we need to restore // Restore the Ignore* flags.
// the Ignore* flags.
IgnoreReal = ignreal; IgnoreReal = ignreal;
IgnoreImag = ignimag; IgnoreImag = ignimag;
IgnoreRealAssign = ignreal; IgnoreRealAssign = ignreal;
IgnoreImagAssign = ignimag; IgnoreImagAssign = ignimag;
return Val;
// Objective-C property assignment never reloads the value following a store.
if (LHS.isPropertyRef() || LHS.isKVCRef())
return Val;
// Otherwise, reload the value.
return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
} }
ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {

View File

@ -27,6 +27,10 @@ void f0(C0 *a) {
// CHECK: objc_msgSend // CHECK: objc_msgSend
int l3 = (a.x0 += 1); int l3 = (a.x0 += 1);
// CHECK: objc_msgSend
// CHECK: objc_msgSend
_Complex int l4 = (a.x1 += 1);
// CHECK-NOT: objc_msgSend // CHECK-NOT: objc_msgSend
// CHECK: } // CHECK: }
} }