diff options
| author | Reid Spencer <rspencer@reidspencer.com> | 2006-11-20 01:22:35 +0000 |
|---|---|---|
| committer | Reid Spencer <rspencer@reidspencer.com> | 2006-11-20 01:22:35 +0000 |
| commit | d9436b6837e27d93a2ac82ef7dfc2c742be0fe69 (patch) | |
| tree | 085e61911bc5ecbd81c027bd5a5f163810088c47 /llvm/lib | |
| parent | 9f4448a26ef8f7e8be847bf7bce4b6e525743af1 (diff) | |
| download | bcm5719-llvm-d9436b6837e27d93a2ac82ef7dfc2c742be0fe69.tar.gz bcm5719-llvm-d9436b6837e27d93a2ac82ef7dfc2c742be0fe69.zip | |
For PR950:
First in a series of patches to convert SetCondInst into ICmpInst and
FCmpInst using only two opcodes and having the instructions contain their
predicate value. Nothing uses these classes yet. More patches to follow.
llvm-svn: 31867
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Analysis/ValueNumbering.cpp | 23 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 56 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Instruction.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Instructions.cpp | 196 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Verifier.cpp | 29 |
5 files changed, 305 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ValueNumbering.cpp b/llvm/lib/Analysis/ValueNumbering.cpp index 0224a0132fd..03b9f6b3eae 100644 --- a/llvm/lib/Analysis/ValueNumbering.cpp +++ b/llvm/lib/Analysis/ValueNumbering.cpp @@ -75,6 +75,7 @@ namespace { void visitCastInst(CastInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); + void visitCmpInst(CmpInst &I); void handleBinaryInst(Instruction &I); void visitBinaryOperator(Instruction &I) { handleBinaryInst(I); } @@ -124,6 +125,28 @@ void BVNImpl::visitCastInst(CastInst &CI) { } } +void BVNImpl::visitCmpInst(CmpInst &CI1) { + Value *LHS = CI1.getOperand(0); + for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end(); + UI != UE; ++UI) + if (CmpInst *CI2 = dyn_cast<CmpInst>(*UI)) + // Check to see if this compare instruction is not CI, but same opcode, + // same predicate, and in the same function. + if (CI2 != &CI1 && CI2->getOpcode() == CI1.getOpcode() && + CI2->getPredicate() == CI1.getPredicate() && + CI2->getParent()->getParent() == CI1.getParent()->getParent()) + // If the operands are the same + if ((CI2->getOperand(0) == CI1.getOperand(0) && + CI2->getOperand(1) == CI1.getOperand(1)) || + // Or the compare is commutative and the operands are reversed + (CI1.isCommutative() && + CI2->getOperand(0) == CI1.getOperand(1) && + CI2->getOperand(1) == CI1.getOperand(0))) + // Then the instructiosn are identical, add to list. + RetVals.push_back(CI2); +} + + // isIdenticalBinaryInst - Return true if the two binary instructions are // identical. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 11347f9e584..8b9fa863296 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -541,6 +541,8 @@ public: void visitShl(User &I) { visitShift(I, ISD::SHL); } void visitLShr(User &I) { visitShift(I, ISD::SRL); } void visitAShr(User &I) { visitShift(I, ISD::SRA); } + void visitICmp(User &I); + void visitFCmp(User &I); void visitSetCC(User &I, ISD::CondCode SignedOpc, ISD::CondCode UnsignedOpc, ISD::CondCode FPOpc); void visitSetEQ(User &I) { visitSetCC(I, ISD::SETEQ, ISD::SETEQ, @@ -1442,6 +1444,60 @@ void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) { setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2)); } +void SelectionDAGLowering::visitICmp(User &I) { + ICmpInst *IC = cast<ICmpInst>(&I); + SDOperand Op1 = getValue(IC->getOperand(0)); + SDOperand Op2 = getValue(IC->getOperand(1)); + ISD::CondCode Opcode; + switch (IC->getPredicate()) { + case ICmpInst::ICMP_EQ : Opcode = ISD::SETEQ; break; + case ICmpInst::ICMP_NE : Opcode = ISD::SETNE; break; + case ICmpInst::ICMP_UGT : Opcode = ISD::SETUGT; break; + case ICmpInst::ICMP_UGE : Opcode = ISD::SETUGE; break; + case ICmpInst::ICMP_ULT : Opcode = ISD::SETULT; break; + case ICmpInst::ICMP_ULE : Opcode = ISD::SETULE; break; + case ICmpInst::ICMP_SGT : Opcode = ISD::SETGT; break; + case ICmpInst::ICMP_SGE : Opcode = ISD::SETGE; break; + case ICmpInst::ICMP_SLT : Opcode = ISD::SETLT; break; + case ICmpInst::ICMP_SLE : Opcode = ISD::SETLE; break; + default: + assert(!"Invalid ICmp predicate value"); + Opcode = ISD::SETEQ; + break; + } + setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode)); +} + +void SelectionDAGLowering::visitFCmp(User &I) { + FCmpInst *FC = cast<FCmpInst>(&I); + SDOperand Op1 = getValue(FC->getOperand(0)); + SDOperand Op2 = getValue(FC->getOperand(1)); + ISD::CondCode Opcode; + switch (FC->getPredicate()) { + case FCmpInst::FCMP_FALSE : Opcode = ISD::SETFALSE; + case FCmpInst::FCMP_OEQ : Opcode = ISD::SETOEQ; + case FCmpInst::FCMP_OGT : Opcode = ISD::SETOGT; + case FCmpInst::FCMP_OGE : Opcode = ISD::SETOGE; + case FCmpInst::FCMP_OLT : Opcode = ISD::SETOLT; + case FCmpInst::FCMP_OLE : Opcode = ISD::SETOLE; + case FCmpInst::FCMP_ONE : Opcode = ISD::SETONE; + case FCmpInst::FCMP_ORD : Opcode = ISD::SETO; + case FCmpInst::FCMP_UNO : Opcode = ISD::SETUO; + case FCmpInst::FCMP_UEQ : Opcode = ISD::SETUEQ; + case FCmpInst::FCMP_UGT : Opcode = ISD::SETUGT; + case FCmpInst::FCMP_UGE : Opcode = ISD::SETUGE; + case FCmpInst::FCMP_ULT : Opcode = ISD::SETULT; + case FCmpInst::FCMP_ULE : Opcode = ISD::SETULE; + case FCmpInst::FCMP_UNE : Opcode = ISD::SETUNE; + case FCmpInst::FCMP_TRUE : Opcode = ISD::SETTRUE; + default: + assert(!"Invalid FCmp predicate value"); + Opcode = ISD::SETFALSE; + break; + } + setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode)); +} + void SelectionDAGLowering::visitSetCC(User &I,ISD::CondCode SignedOpcode, ISD::CondCode UnsignedOpcode, ISD::CondCode FPOpcode) { diff --git a/llvm/lib/VMCore/Instruction.cpp b/llvm/lib/VMCore/Instruction.cpp index 70b375902dc..64a9e12f82d 100644 --- a/llvm/lib/VMCore/Instruction.cpp +++ b/llvm/lib/VMCore/Instruction.cpp @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Type.h" #include "llvm/Instructions.h" #include "llvm/Function.h" #include "llvm/SymbolTable.h" -#include "llvm/Type.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; diff --git a/llvm/lib/VMCore/Instructions.cpp b/llvm/lib/VMCore/Instructions.cpp index 5ed07cfb7f7..f559c6324e4 100644 --- a/llvm/lib/VMCore/Instructions.cpp +++ b/llvm/lib/VMCore/Instructions.cpp @@ -1290,6 +1290,197 @@ Instruction::BinaryOps SetCondInst::getSwappedCondition(BinaryOps Opcode) { } } + +//===----------------------------------------------------------------------===// +// CmpInst Classes +//===----------------------------------------------------------------------===// + +CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS, + const std::string &Name, Instruction *InsertBefore) + : Instruction(Type::BoolTy, op, Ops, 2, Name, InsertBefore) { + Ops[0].init(LHS, this); + Ops[1].init(RHS, this); + SubclassData = predicate; + if (op == Instruction::ICmp) { + assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE && + predicate <= ICmpInst::LAST_ICMP_PREDICATE && + "Invalid ICmp predicate value"); + const Type* Op0Ty = getOperand(0)->getType(); + const Type* Op1Ty = getOperand(1)->getType(); + assert(Op0Ty == Op1Ty && + "Both operands to ICmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID || + (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isIntegral()) && + "Invalid operand types for ICmp instruction"); + return; + } + assert(op == Instruction::FCmp && "Invalid CmpInst opcode"); + assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE && + "Invalid FCmp predicate value"); + const Type* Op0Ty = getOperand(0)->getType(); + const Type* Op1Ty = getOperand(1)->getType(); + assert(Op0Ty == Op1Ty && + "Both operands to FCmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(Op0Ty->isFloatingPoint() || (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isFloatingPoint()) && + "Invalid operand types for FCmp instruction"); +} + +CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS, + const std::string &Name, BasicBlock *InsertAtEnd) + : Instruction(Type::BoolTy, op, Ops, 2, Name, InsertAtEnd) { + Ops[0].init(LHS, this); + Ops[1].init(RHS, this); + SubclassData = predicate; + if (op == Instruction::ICmp) { + assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE && + predicate <= ICmpInst::LAST_ICMP_PREDICATE && + "Invalid ICmp predicate value"); + + const Type* Op0Ty = getOperand(0)->getType(); + const Type* Op1Ty = getOperand(1)->getType(); + assert(Op0Ty == Op1Ty && + "Both operands to ICmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID || + (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isIntegral()) && + "Invalid operand types for ICmp instruction"); + return; + } + assert(op == Instruction::FCmp && "Invalid CmpInst opcode"); + assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE && + "Invalid FCmp predicate value"); + const Type* Op0Ty = getOperand(0)->getType(); + const Type* Op1Ty = getOperand(1)->getType(); + assert(Op0Ty == Op1Ty && + "Both operands to FCmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(Op0Ty->isFloatingPoint() || (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isFloatingPoint()) && + "Invalid operand types for FCmp instruction"); +} + +CmpInst * +CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, + const std::string &Name, Instruction *InsertBefore) { + if (Op == Instruction::ICmp) { + return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name, + InsertBefore); + } + return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name, + InsertBefore); +} + +CmpInst * +CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, + const std::string &Name, BasicBlock *InsertAtEnd) { + if (Op == Instruction::ICmp) { + return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name, + InsertAtEnd); + } + return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name, + InsertAtEnd); +} + +void CmpInst::swapOperands() { + if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) + IC->swapOperands(); + else + cast<FCmpInst>(this)->swapOperands(); +} + +bool CmpInst::isCommutative() { + if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) + return IC->isCommutative(); + return cast<FCmpInst>(this)->isCommutative(); +} + +bool CmpInst::isEquality() { + if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) + return IC->isEquality(); + return cast<FCmpInst>(this)->isEquality(); +} + + +ICmpInst::Predicate ICmpInst::getInversePredicate(Predicate pred) { + switch (pred) { + default: + assert(!"Unknown icmp predicate!"); + case ICMP_EQ: return ICMP_NE; + case ICMP_NE: return ICMP_EQ; + case ICMP_UGT: return ICMP_ULE; + case ICMP_ULT: return ICMP_UGE; + case ICMP_UGE: return ICMP_ULT; + case ICMP_ULE: return ICMP_UGT; + case ICMP_SGT: return ICMP_SLE; + case ICMP_SLT: return ICMP_SGE; + case ICMP_SGE: return ICMP_SLT; + case ICMP_SLE: return ICMP_SGT; + } +} + +ICmpInst::Predicate ICmpInst::getSwappedPredicate(Predicate pred) { + switch (pred) { + default: assert(! "Unknown setcc instruction!"); + case ICMP_EQ: case ICMP_NE: + return pred; + case ICMP_SGT: return ICMP_SLT; + case ICMP_SLT: return ICMP_SGT; + case ICMP_SGE: return ICMP_SLE; + case ICMP_SLE: return ICMP_SGE; + case ICMP_UGT: return ICMP_ULT; + case ICMP_ULT: return ICMP_UGT; + case ICMP_UGE: return ICMP_ULE; + case ICMP_ULE: return ICMP_UGE; + } +} + +FCmpInst::Predicate FCmpInst::getInversePredicate(Predicate pred) { + switch (pred) { + default: + assert(!"Unknown icmp predicate!"); + case FCMP_OEQ: return FCMP_UNE; + case FCMP_ONE: return FCMP_UEQ; + case FCMP_OGT: return FCMP_ULE; + case FCMP_OLT: return FCMP_UGE; + case FCMP_OGE: return FCMP_ULT; + case FCMP_OLE: return FCMP_UGT; + case FCMP_UEQ: return FCMP_ONE; + case FCMP_UNE: return FCMP_OEQ; + case FCMP_UGT: return FCMP_OLE; + case FCMP_ULT: return FCMP_OGE; + case FCMP_UGE: return FCMP_OLT; + case FCMP_ULE: return FCMP_OGT; + case FCMP_ORD: return FCMP_UNO; + case FCMP_UNO: return FCMP_ORD; + case FCMP_TRUE: return FCMP_FALSE; + case FCMP_FALSE: return FCMP_TRUE; + } +} + +FCmpInst::Predicate FCmpInst::getSwappedPredicate(Predicate pred) { + switch (pred) { + default: assert(!"Unknown setcc instruction!"); + case FCMP_FALSE: case FCMP_TRUE: + case FCMP_OEQ: case FCMP_ONE: + case FCMP_UEQ: case FCMP_UNE: + case FCMP_ORD: case FCMP_UNO: + return pred; + case FCMP_OGT: return FCMP_OLT; + case FCMP_OLT: return FCMP_OGT; + case FCMP_OGE: return FCMP_OLE; + case FCMP_OLE: return FCMP_OGE; + case FCMP_UGT: return FCMP_ULT; + case FCMP_ULT: return FCMP_UGT; + case FCMP_UGE: return FCMP_ULE; + case FCMP_ULE: return FCMP_UGE; + } +} + //===----------------------------------------------------------------------===// // SwitchInst Implementation //===----------------------------------------------------------------------===// @@ -1412,6 +1603,11 @@ BinaryOperator *BinaryOperator::clone() const { return create(getOpcode(), Ops[0], Ops[1]); } +CmpInst* CmpInst::clone() const { + return create(Instruction::OtherOps(getOpcode()), getPredicate(), + Ops[0], Ops[1]); +} + MallocInst *MallocInst::clone() const { return new MallocInst(*this); } AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); } FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); } diff --git a/llvm/lib/VMCore/Verifier.cpp b/llvm/lib/VMCore/Verifier.cpp index 868fc67d51f..065ac3b7750 100644 --- a/llvm/lib/VMCore/Verifier.cpp +++ b/llvm/lib/VMCore/Verifier.cpp @@ -179,6 +179,8 @@ namespace { // Anonymous namespace for class void visitBasicBlock(BasicBlock &BB); void visitPHINode(PHINode &PN); void visitBinaryOperator(BinaryOperator &B); + void visitICmpInst(ICmpInst &IC); + void visitFCmpInst(FCmpInst &FC); void visitShiftInst(ShiftInst &SI); void visitExtractElementInst(ExtractElementInst &EI); void visitInsertElementInst(InsertElementInst &EI); @@ -551,6 +553,33 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) { visitInstruction(B); } +void Verifier::visitICmpInst(ICmpInst& IC) { + // Check that the operands are the same type + const Type* Op0Ty = IC.getOperand(0)->getType(); + const Type* Op1Ty = IC.getOperand(1)->getType(); + Assert1(Op0Ty == Op1Ty, + "Both operands to ICmp instruction are not of the same type!", &IC); + // Check that the operands are the right type + Assert1(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID || + (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isIntegral()), + "Invalid operand types for ICmp instruction", &IC); + visitInstruction(IC); +} + +void Verifier::visitFCmpInst(FCmpInst& FC) { + // Check that the operands are the same type + const Type* Op0Ty = FC.getOperand(0)->getType(); + const Type* Op1Ty = FC.getOperand(1)->getType(); + Assert1(Op0Ty == Op1Ty, + "Both operands to FCmp instruction are not of the same type!", &FC); + // Check that the operands are the right type + Assert1(Op0Ty->isFloatingPoint() || (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isFloatingPoint()), + "Invalid operand types for FCmp instruction", &FC); + visitInstruction(FC); +} + void Verifier::visitShiftInst(ShiftInst &SI) { Assert1(SI.getType()->isInteger(), "Shift must return an integer result!", &SI); |

