refactor some code, implement -=

llvm-svn: 39711
This commit is contained in:
Chris Lattner 2007-06-29 16:52:55 +00:00
parent 9369a563b4
commit cd215f00ee
2 changed files with 83 additions and 60 deletions

View File

@ -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<CompoundAssignOperator>(E));
case BinaryOperator::Assign:
return EmitBinaryAssign(E);
case BinaryOperator::AddAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(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<CompoundAssignOperator>(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());

View File

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