From cd215f00eee0378d021ce1a7a73edaefe391776a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 29 Jun 2007 16:52:55 +0000 Subject: [PATCH] refactor some code, implement -= llvm-svn: 39711 --- clang/CodeGen/CGExpr.cpp | 131 ++++++++++++++++++-------------- clang/CodeGen/CodeGenFunction.h | 12 ++- 2 files changed, 83 insertions(+), 60 deletions(-) diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index c37b3f933e92..67179d361858 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -705,8 +705,51 @@ EmitUsualArithmeticConversions(const BinaryOperator *E, RValue &LHS, return ResTy; } +/// EmitCompoundAssignmentOperands - Compound assignment operations (like +=) +/// are strange in that the result of the operation is not the same type as the +/// intermediate computation. This function emits the LHS and RHS operands of +/// the compound assignment, promoting them to their common computation type. +/// +/// Since the LHS is an lvalue, and the result is stored back through it, we +/// return the lvalue as well as the LHS/RHS rvalues. On return, the LHS and +/// RHS values are both in the computation type for the operator. +void CodeGenFunction:: +EmitCompoundAssignmentOperands(const CompoundAssignOperator *E, + LValue &LHSLV, RValue &LHS, RValue &RHS) { + LHSLV = EmitLValue(E->getLHS()); + + // Load the LHS and RHS operands. + QualType LHSTy = E->getLHS()->getType(); + LHS = EmitLoadOfLValue(LHSLV, LHSTy); + QualType RHSTy; + RHS = EmitExprWithUsualUnaryConversions(E->getRHS(), RHSTy); + + // Convert the LHS and RHS to the common evaluation type. + LHS = EmitConversion(LHS, LHSTy, E->getComputationType()); + RHS = EmitConversion(RHS, RHSTy, E->getComputationType()); +} + +/// EmitCompoundAssignmentResult - Given a result value in the computation type, +/// truncate it down to the actual result type, store it through the LHS lvalue, +/// and return it. +RValue CodeGenFunction:: +EmitCompoundAssignmentResult(const CompoundAssignOperator *E, + LValue LHSLV, RValue ResV) { + + // Truncate back to the destination type. + if (E->getComputationType() != E->getType()) + ResV = EmitConversion(ResV, E->getComputationType(), E->getType()); + + // Store the result value into the LHS. + EmitStoreThroughLValue(ResV, LHSLV, E->getType()); + + // Return the result. + return ResV; +} + RValue CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) { + RValue LHS, RHS; switch (E->getOpcode()) { default: fprintf(stderr, "Unimplemented expr!\n"); @@ -715,8 +758,14 @@ RValue CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) { case BinaryOperator::Mul: return EmitBinaryMul(E); case BinaryOperator::Div: return EmitBinaryDiv(E); case BinaryOperator::Rem: return EmitBinaryRem(E); - case BinaryOperator::Add: return EmitBinaryAdd(E); - case BinaryOperator::Sub: return EmitBinarySub(E); + case BinaryOperator::Add: + // FIXME: This doesn't handle ptr+int etc yet. + EmitUsualArithmeticConversions(E, LHS, RHS); + return EmitAdd(LHS, RHS, E->getType()); + case BinaryOperator::Sub: + // FIXME: This doesn't handle ptr-int etc yet. + EmitUsualArithmeticConversions(E, LHS, RHS); + return EmitSub(LHS, RHS, E->getType()); case BinaryOperator::Shl: return EmitBinaryShl(E); case BinaryOperator::Shr: return EmitBinaryShr(E); case BinaryOperator::And: return EmitBinaryAnd(E); @@ -748,9 +797,24 @@ RValue CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) { return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_NE, llvm::ICmpInst::ICMP_NE, llvm::FCmpInst::FCMP_UNE); - case BinaryOperator::Assign: return EmitBinaryAssign(E); - case BinaryOperator::AddAssign: - return EmitBinaryAddAssign(cast(E)); + case BinaryOperator::Assign: + return EmitBinaryAssign(E); + + case BinaryOperator::AddAssign: { + const CompoundAssignOperator *CAO = cast(E); + LValue LHSLV; + EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS); + LHS = EmitAdd(LHS, RHS, CAO->getComputationType()); + return EmitCompoundAssignmentResult(CAO, LHSLV, LHS); + } + case BinaryOperator::SubAssign: { + const CompoundAssignOperator *CAO = cast(E); + LValue LHSLV; + EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS); + LHS = EmitSub(LHS, RHS, CAO->getComputationType()); + return EmitCompoundAssignmentResult(CAO, LHSLV, LHS); + } + // FIXME: Assignment. case BinaryOperator::Comma: return EmitBinaryComma(E); } @@ -800,15 +864,10 @@ RValue CodeGenFunction::EmitBinaryRem(const BinaryOperator *E) { assert(0 && "FIXME: This doesn't handle complex operands yet"); } -RValue CodeGenFunction::EmitBinaryAdd(const BinaryOperator *E) { - RValue LHS, RHS; - EmitUsualArithmeticConversions(E, LHS, RHS); - - // FIXME: This doesn't handle ptr+int etc yet. - +RValue CodeGenFunction::EmitAdd(RValue LHS, RValue RHS, QualType ResTy) { if (LHS.isScalar()) return RValue::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "add")); - + // Otherwise, this must be a complex number. llvm::Value *LHSR, *LHSI, *RHSR, *RHSI; @@ -818,24 +877,19 @@ RValue CodeGenFunction::EmitBinaryAdd(const BinaryOperator *E) { llvm::Value *ResR = Builder.CreateAdd(LHSR, RHSR, "add.r"); llvm::Value *ResI = Builder.CreateAdd(LHSI, RHSI, "add.i"); - llvm::Value *Res = CreateTempAlloca(ConvertType(E->getType())); + llvm::Value *Res = CreateTempAlloca(ConvertType(ResTy)); EmitStoreOfComplex(ResR, ResI, Res); return RValue::getAggregate(Res); } -RValue CodeGenFunction::EmitBinarySub(const BinaryOperator *E) { - RValue LHS, RHS; - EmitUsualArithmeticConversions(E, LHS, RHS); - - // FIXME: This doesn't handle ptr-int or ptr-ptr, etc yet. - +RValue CodeGenFunction::EmitSub(RValue LHS, RValue RHS, QualType ResTy) { if (LHS.isScalar()) return RValue::get(Builder.CreateSub(LHS.getVal(), RHS.getVal(), "sub")); assert(0 && "FIXME: This doesn't handle complex operands yet"); - } + RValue CodeGenFunction::EmitBinaryShl(const BinaryOperator *E) { // For shifts, integer promotions are performed, but the usual arithmetic // conversions are not. The LHS and RHS need not have the same type. @@ -1005,43 +1059,6 @@ RValue CodeGenFunction::EmitBinaryAssign(const BinaryOperator *E) { return RHS; } -/// Compound assignment operations have different promotion rules than the other -/// binary operators. In particular, the LHS and RHS are promoted to a new type -/// (specified by E->getComputationType()), the binary operator is evaluated, -/// the result is truncated to the type of LHS, then the result is stored back -/// through the LHS. -/// -RValue CodeGenFunction::EmitBinaryAddAssign(const CompoundAssignOperator *E) { - LValue LHSLV = EmitLValue(E->getLHS()); - - // Load the LHS and RHS operands. - QualType LHSTy = E->getLHS()->getType(); - RValue LHS = EmitLoadOfLValue(LHSLV, LHSTy); - QualType RHSTy; - RValue RHS = EmitExprWithUsualUnaryConversions(E->getRHS(), RHSTy); - - // Convert the LHS and RHS to the common evaluation type. - LHS = EmitConversion(LHS, LHSTy, E->getComputationType()); - RHS = EmitConversion(RHS, RHSTy, E->getComputationType()); - - // Emit the operation itself. - RValue Res; - if (LHS.isScalar()) { - Res = RValue::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "add")); - } else { - assert(0 && "FIXME: Complex add unimp!"); - } - - // Truncate back to the destination type. - if (E->getComputationType() != E->getType()) - Res = EmitConversion(Res, E->getComputationType(), E->getType()); - - // Store the result value into the LHS. - EmitStoreThroughLValue(Res, LHSLV, E->getType()); - - // Return the result. - return Res; -} RValue CodeGenFunction::EmitBinaryComma(const BinaryOperator *E) { EmitExpr(E->getLHS()); diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index cda8c55b73f8..1f4b443d9858 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -271,6 +271,12 @@ public: QualType EmitUsualArithmeticConversions(const BinaryOperator *E, RValue &LHS, RValue &RHS); + void EmitCompoundAssignmentOperands(const CompoundAssignOperator *CAO, + LValue &LHSLV, RValue &LHS, RValue &RHS); + RValue EmitCompoundAssignmentResult(const CompoundAssignOperator *E, + LValue LHSLV, RValue ResV); + + RValue EmitExpr(const Expr *E); RValue EmitIntegerLiteral(const IntegerLiteral *E); @@ -293,8 +299,8 @@ public: RValue EmitBinaryMul(const BinaryOperator *E); RValue EmitBinaryDiv(const BinaryOperator *E); RValue EmitBinaryRem(const BinaryOperator *E); - RValue EmitBinaryAdd(const BinaryOperator *E); - RValue EmitBinarySub(const BinaryOperator *E); + RValue EmitAdd(RValue LHS, RValue RHS, QualType EltTy); + RValue EmitSub(RValue LHS, RValue RHS, QualType EltTy); RValue EmitBinaryShl(const BinaryOperator *E); RValue EmitBinaryShr(const BinaryOperator *E); RValue EmitBinaryCompare(const BinaryOperator *E, unsigned UICmpOpc, @@ -306,7 +312,7 @@ public: RValue EmitBinaryLOr(const BinaryOperator *E); RValue EmitBinaryAssign(const BinaryOperator *E); - RValue EmitBinaryAddAssign(const CompoundAssignOperator *E); + // FIXME: Assignment. RValue EmitBinaryComma(const BinaryOperator *E);