X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FiOperators.cpp;h=c33d79739142d5890d20f20f56c2870b9ba5dcdf;hb=8b29776d680f1b80b7471291b7d41df753d28511;hp=20e60cf8741bafbaf0659b459e99e3d28ba58b29;hpb=9a66d5109e5b7efa7faf0f042bd9812c564f6139;p=oota-llvm.git diff --git a/lib/VMCore/iOperators.cpp b/lib/VMCore/iOperators.cpp index 20e60cf8741..c33d7973914 100644 --- a/lib/VMCore/iOperators.cpp +++ b/lib/VMCore/iOperators.cpp @@ -1,4 +1,11 @@ //===-- iOperators.cpp - Implement binary Operators ------------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file implements the nontrivial binary operator instructions. // @@ -8,16 +15,14 @@ #include "llvm/Type.h" #include "llvm/Constants.h" #include "llvm/BasicBlock.h" +using namespace llvm; //===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// -BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, - const Type *Ty, const std::string &Name, - Instruction *InsertBefore) - : Instruction(Ty, iType, Name, InsertBefore) { - +void BinaryOperator::init(BinaryOps iType, Value *S1, Value *S2) +{ Operands.reserve(2); Operands.push_back(Use(S1, this)); Operands.push_back(Use(S2, this)); @@ -28,30 +33,27 @@ BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, case Add: case Sub: case Mul: case Div: case Rem: - assert(Ty == S1->getType() && + assert(getType() == S1->getType() && "Arithmetic operation should return same type as operands!"); - assert((Ty->isInteger() || Ty->isFloatingPoint()) && + assert((getType()->isInteger() || getType()->isFloatingPoint()) && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; case And: case Or: case Xor: - assert(Ty == S1->getType() && + assert(getType() == S1->getType() && "Logical operation should return same type as operands!"); - assert(Ty->isIntegral() && + assert(getType()->isIntegral() && "Tried to create an logical operation on a non-integral type!"); break; case SetLT: case SetGT: case SetLE: case SetGE: case SetEQ: case SetNE: - assert(Ty == Type::BoolTy && "Setcc must return bool!"); + assert(getType() == Type::BoolTy && "Setcc must return bool!"); default: break; } #endif } - - - BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, const std::string &Name, Instruction *InsertBefore) { @@ -68,11 +70,36 @@ BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, } } +BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, + const std::string &Name, + BasicBlock *InsertAtEnd) { + BinaryOperator *Res = create(Op, S1, S2, Name); + InsertAtEnd->getInstList().push_back(Res); + return Res; +} + BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name, Instruction *InsertBefore) { - return new BinaryOperator(Instruction::Sub, - Constant::getNullValue(Op->getType()), Op, - Op->getType(), Name, InsertBefore); + if (!Op->getType()->isFloatingPoint()) + return new BinaryOperator(Instruction::Sub, + Constant::getNullValue(Op->getType()), Op, + Op->getType(), Name, InsertBefore); + else + return new BinaryOperator(Instruction::Sub, + ConstantFP::get(Op->getType(), -0.0), Op, + Op->getType(), Name, InsertBefore); +} + +BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name, + BasicBlock *InsertAtEnd) { + if (!Op->getType()->isFloatingPoint()) + return new BinaryOperator(Instruction::Sub, + Constant::getNullValue(Op->getType()), Op, + Op->getType(), Name, InsertAtEnd); + else + return new BinaryOperator(Instruction::Sub, + ConstantFP::get(Op->getType(), -0.0), Op, + Op->getType(), Name, InsertAtEnd); } BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name, @@ -82,6 +109,13 @@ BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name, Op->getType(), Name, InsertBefore); } +BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name, + BasicBlock *InsertAtEnd) { + return new BinaryOperator(Instruction::Xor, Op, + ConstantIntegral::getAllOnesValue(Op->getType()), + Op->getType(), Name, InsertAtEnd); +} + // isConstantAllOnes - Helper function for several functions below static inline bool isConstantAllOnes(const Value *V) { @@ -90,8 +124,11 @@ static inline bool isConstantAllOnes(const Value *V) { bool BinaryOperator::isNeg(const Value *V) { if (const BinaryOperator *Bop = dyn_cast(V)) - return Bop->getOpcode() == Instruction::Sub && - isa(Bop->getOperand(0)) && cast(V)->isNullValue(); + if (Bop->getOpcode() == Instruction::Sub) + if (!V->getType()->isFloatingPoint()) + return Bop->getOperand(0) == Constant::getNullValue(Bop->getType()); + else + return Bop->getOperand(0) == ConstantFP::get(Bop->getType(), -0.0); return false; } @@ -130,24 +167,17 @@ const Value *BinaryOperator::getNotArgument(const BinaryOperator *Bop) { // swapOperands - Exchange the two operands to this instruction. This // instruction is safe to use on any binary instruction and does not // modify the semantics of the instruction. If the instruction is -// order dependant (SetLT f.e.) the opcode is changed. +// order dependent (SetLT f.e.) the opcode is changed. // bool BinaryOperator::swapOperands() { - if (SetCondInst *SCI = dyn_cast(this)) { - iType = SCI->getSwappedCondition(); - std::swap(Operands[0], Operands[1]); - return false; - } + if (isCommutative()) + ; // If the instruction is commutative, it is safe to swap the operands + else if (SetCondInst *SCI = dyn_cast(this)) + /// FIXME: SetCC instructions shouldn't all have different opcodes. + setOpcode(SCI->getSwappedCondition()); + else + return true; // Can't commute operands - switch (getOpcode()) { - // Instructions that don't need opcode modification - case Add: case Mul: - case And: case Xor: - case Or: - // Error on the side of caution - default: - return true; - } std::swap(Operands[0], Operands[1]); return false; } @@ -165,6 +195,14 @@ SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, assert(getInverseCondition(Opcode)); } +SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, + const std::string &Name, BasicBlock *InsertAtEnd) + : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertAtEnd) { + + // Make sure it's a valid type... getInverseCondition will assert out if not. + assert(getInverseCondition(Opcode)); +} + // getInverseCondition - Return the inverse of the current condition opcode. // For example seteq -> setne, setgt -> setle, setlt -> setge, etc... //