diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2006-12-23 06:05:41 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2006-12-23 06:05:41 +0000 |
commit | e4d87aa2de6e52952dca73716386db09aad5a8fd (patch) | |
tree | ce8c6e6ddc845de3585020c856118892f4206593 /include/llvm | |
parent | add2bd7f5941537a97a41e037ae2277fbeed0b4f (diff) | |
download | external_llvm-e4d87aa2de6e52952dca73716386db09aad5a8fd.zip external_llvm-e4d87aa2de6e52952dca73716386db09aad5a8fd.tar.gz external_llvm-e4d87aa2de6e52952dca73716386db09aad5a8fd.tar.bz2 |
For PR950:
This patch removes the SetCC instructions and replaces them with the ICmp
and FCmp instructions. The SetCondInst instruction has been removed and
been replaced with ICmpInst and FCmpInst.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32751 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r-- | include/llvm/Analysis/ScalarEvolutionExpressions.h | 6 | ||||
-rw-r--r-- | include/llvm/Constants.h | 13 | ||||
-rw-r--r-- | include/llvm/InstrTypes.h | 14 | ||||
-rw-r--r-- | include/llvm/Instruction.def | 86 | ||||
-rw-r--r-- | include/llvm/Instruction.h | 16 | ||||
-rw-r--r-- | include/llvm/Instructions.h | 99 | ||||
-rw-r--r-- | include/llvm/Pass.h | 2 | ||||
-rw-r--r-- | include/llvm/Support/ConstantRange.h | 26 | ||||
-rw-r--r-- | include/llvm/Support/InstVisitor.h | 1 | ||||
-rw-r--r-- | include/llvm/Support/PatternMatch.h | 46 | ||||
-rw-r--r-- | include/llvm/Transforms/Utils/Local.h | 14 |
11 files changed, 165 insertions, 158 deletions
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index c261dfc..b9bf93b 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -426,8 +426,10 @@ namespace llvm { /// looking at this is that it returns the first iteration number where the /// value is not in the condition, thus computing the exit count. If the /// iteration count can't be computed, an instance of SCEVCouldNotCompute is - /// returned. - SCEVHandle getNumIterationsInRange(ConstantRange Range) const; + /// returned. The isSigned parameter indicates whether the ConstantRange + /// should be treated as signed or unsigned. + SCEVHandle getNumIterationsInRange(ConstantRange Range, + bool isSigned) const; SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, const SCEVHandle &Conc) const; diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 2a0c624..a6050f4 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -496,8 +496,8 @@ protected: // ConstantExprs in intermediate forms. static Constant *getTy(const Type *Ty, unsigned Opcode, Constant *C1, Constant *C2); - static Constant *getCompareTy(unsigned Opcode, unsigned short pred, - Constant *C1, Constant *C2); + static Constant *getCompareTy(unsigned short pred, Constant *C1, + Constant *C2); static Constant *getShiftTy(const Type *Ty, unsigned Opcode, Constant *C1, Constant *C2); static Constant *getSelectTy(const Type *Ty, @@ -604,8 +604,7 @@ public: static Constant *get(unsigned Opcode, Constant *C1, Constant *C2); /// @brief Return an ICmp or FCmp comparison operator constant expression. - static Constant *getCompare(unsigned Opcode, unsigned short pred, - Constant *C1, Constant *C2); + static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2); /// ConstantExpr::get* - Return some common constants without having to /// specify the full Instruction::OPCODE identifier. @@ -624,12 +623,6 @@ public: static Constant *getAnd(Constant *C1, Constant *C2); static Constant *getOr(Constant *C1, Constant *C2); static Constant *getXor(Constant *C1, Constant *C2); - static Constant *getSetEQ(Constant *C1, Constant *C2); - static Constant *getSetNE(Constant *C1, Constant *C2); - static Constant *getSetLT(Constant *C1, Constant *C2); - static Constant *getSetGT(Constant *C1, Constant *C2); - static Constant *getSetLE(Constant *C1, Constant *C2); - static Constant *getSetGE(Constant *C1, Constant *C2); static Constant* getICmp(unsigned short pred, Constant* LHS, Constant* RHS); static Constant* getFCmp(unsigned short pred, Constant* LHS, Constant* RHS); static Constant *getShl(Constant *C1, Constant *C2); diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index b3ec559..152f477 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -543,6 +543,20 @@ public: /// @brief Determine if this is an equals/not equals predicate. bool isEquality(); + /// @returns true if the predicate is unsigned, false otherwise. + /// @brief Determine if the predicate is an unsigned operation. + static bool isUnsigned(unsigned short predicate); + + /// @returns true if the predicate is signed, false otherwise. + /// @brief Determine if the predicate is an signed operation. + static bool isSigned(unsigned short predicate); + + /// @brief Determine if the predicate is an ordered operation. + static bool isOrdered(unsigned short predicate); + + /// @brief Determine if the predicate is an unordered operation. + static bool isUnordered(unsigned short predicate); + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const CmpInst *) { return true; } static inline bool classof(const Instruction *I) { diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def index db41734..c33c448 100644 --- a/include/llvm/Instruction.def +++ b/include/llvm/Instruction.def @@ -118,61 +118,53 @@ HANDLE_BINARY_INST(15, FRem , BinaryOperator) HANDLE_BINARY_INST(16, And , BinaryOperator) HANDLE_BINARY_INST(17, Or , BinaryOperator) HANDLE_BINARY_INST(18, Xor , BinaryOperator) - -// Binary comparison operators... -HANDLE_BINARY_INST(19, SetEQ , SetCondInst) -HANDLE_BINARY_INST(20, SetNE , SetCondInst) -HANDLE_BINARY_INST(21, SetLE , SetCondInst) -HANDLE_BINARY_INST(22, SetGE , SetCondInst) -HANDLE_BINARY_INST(23, SetLT , SetCondInst) -HANDLE_BINARY_INST(24, SetGT , SetCondInst) - LAST_BINARY_INST(24) + LAST_BINARY_INST(18) // Memory operators... - FIRST_MEMORY_INST(25) -HANDLE_MEMORY_INST(25, Malloc, MallocInst) // Heap management instructions -HANDLE_MEMORY_INST(26, Free , FreeInst ) -HANDLE_MEMORY_INST(27, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(28, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(29, Store , StoreInst ) -HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst) - LAST_MEMORY_INST(30) + FIRST_MEMORY_INST(19) +HANDLE_MEMORY_INST(19, Malloc, MallocInst) // Heap management instructions +HANDLE_MEMORY_INST(20, Free , FreeInst ) +HANDLE_MEMORY_INST(21, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(22, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(23, Store , StoreInst ) +HANDLE_MEMORY_INST(24, GetElementPtr, GetElementPtrInst) + LAST_MEMORY_INST(24) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(31) -HANDLE_CAST_INST(31, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(32, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(33, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(34, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(35, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(36, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(37, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(38, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(39, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(40, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(41, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(42, BitCast , BitCastInst ) // Type cast - LAST_CAST_INST(42) + FIRST_CAST_INST(25) +HANDLE_CAST_INST(25, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(26, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(27, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(28, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(29, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(30, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(31, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(32, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(33, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(34, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(35, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(36, BitCast , BitCastInst ) // Type cast + LAST_CAST_INST(36) // Other operators... - FIRST_OTHER_INST(43) -HANDLE_OTHER_INST(43, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(44, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(45, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(46, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(47, Shl , ShiftInst ) // Shift Left operations (logical) -HANDLE_OTHER_INST(48, LShr , ShiftInst ) // Logical Shift right (unsigned) -HANDLE_OTHER_INST(49, AShr , ShiftInst ) // Arithmetic shift right (signed) -HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector. -HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. - LAST_OTHER_INST(56) + FIRST_OTHER_INST(37) +HANDLE_OTHER_INST(37, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(38, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(39, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(40, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(41, Shl , ShiftInst ) // Shift Left operations (logical) +HANDLE_OTHER_INST(42, LShr , ShiftInst ) // Logical Shift right (unsigned) +HANDLE_OTHER_INST(43, AShr , ShiftInst ) // Arithmetic shift right (signed) +HANDLE_OTHER_INST(44, Select , SelectInst ) // select instruction +HANDLE_OTHER_INST(45, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(46, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(47, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(48, ExtractElement, ExtractElementInst)// extract from vector. +HANDLE_OTHER_INST(49, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(50, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. + LAST_OTHER_INST(50) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index ce75969..a0376c7 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -71,6 +71,16 @@ public: /// extra information (e.g. load is volatile) agree. bool isIdenticalTo(Instruction *I) const; + /// This function determines if the specified instruction executes the same + /// operation as the current one. This means that the opcodes, type, operand + /// types and any other factors affecting the operation must be the same. This + /// is similar to isIdenticalTo except the operands themselves don't have to + /// be identical. + /// @returns true if the specified instruction is the same operation as + /// the current one. + /// @brief Determine if one instruction is the same operation as another. + bool isSameOperationAs(Instruction *I) const; + /// use_back - Specialize the methods defined in Value, as we know that an /// instruction can only be used by other instructions. Instruction *use_back() { return cast<Instruction>(*use_begin());} @@ -155,12 +165,6 @@ public: bool isCommutative() const { return isCommutative(getOpcode()); } static bool isCommutative(unsigned op); - /// isComparison - Return true if the instruction is a Set* instruction: - /// - bool isComparison() const { return isComparison(getOpcode()); } - static bool isComparison(unsigned op); - - /// isTrappingInstruction - Return true if the instruction may trap. /// bool isTrapping() const { diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 5f71256..c786623 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -440,7 +440,8 @@ public: ICMP_SLT = 40, ///< signed less than ICMP_SLE = 41, ///< signed less or equal FIRST_ICMP_PREDICATE = ICMP_EQ, - LAST_ICMP_PREDICATE = ICMP_SLE + LAST_ICMP_PREDICATE = ICMP_SLE, + BAD_ICMP_PREDICATE = ICMP_SLE + 1 }; /// @brief Constructor with insert-before-instruction semantics. @@ -490,16 +491,30 @@ public: /// This is a static version that you can use without an instruction /// available. /// @brief Return the predicate as if the operands were swapped. - static Predicate getSwappedPredicate(Predicate Opcode); + static Predicate getSwappedPredicate(Predicate pred); + + /// For example, EQ->EQ, SLE->SLE, UGT->SGT, etc. + /// @returns the predicate that would be the result if the operand were + /// regarded as signed. + /// @brief Return the signed version of the predicate + Predicate getSignedPredicate() const { + return getSignedPredicate(getPredicate()); + } + + /// This is a static version that you can use without an instruction. + /// @brief Return the signed version of the predicate. + static Predicate getSignedPredicate(Predicate pred); /// This also tests for commutativity. If isEquality() returns true then - /// the predicate is also commutative. Only the equality predicates are - /// commutative. + /// the predicate is also commutative. /// @returns true if the predicate of this instruction is EQ or NE. /// @brief Determine if this is an equality predicate. bool isEquality() const { return SubclassData == ICMP_EQ || SubclassData == ICMP_NE; } + + /// @returns true if the predicate of this ICmpInst is commutative + /// @brief Determine if this relation is commutative. bool isCommutative() const { return isEquality(); } /// @returns true if the predicate is relational (not EQ or NE). @@ -508,6 +523,14 @@ public: return !isEquality(); } + /// @returns true if the predicate of this ICmpInst is signed, false otherwise + /// @brief Determine if this instruction's predicate is signed. + bool isSignedPredicate() { return isSignedPredicate(getPredicate()); } + + /// @returns true if the predicate provided is signed, false otherwise + /// @brief Determine if the predicate is signed. + static bool isSignedPredicate(Predicate pred); + /// Exchange the two operands to this instruction in such a way that it does /// not modify the semantics of the instruction. The predicate value may be /// changed to retain the same result if the predicate is order dependent @@ -559,7 +582,8 @@ public: FCMP_UNE =14, ///< 1 1 1 0 True if unordered or not equal FCMP_TRUE =15, ///< 1 1 1 1 Always true (always folded) FIRST_FCMP_PREDICATE = FCMP_FALSE, - LAST_FCMP_PREDICATE = FCMP_TRUE + LAST_FCMP_PREDICATE = FCMP_TRUE, + BAD_FCMP_PREDICATE = FCMP_TRUE + 1 }; /// @brief Constructor with insert-before-instruction semantics. @@ -646,71 +670,6 @@ public: } }; - -//===----------------------------------------------------------------------===// -// SetCondInst Class -//===----------------------------------------------------------------------===// - -/// SetCondInst class - Represent a setCC operator, where CC is eq, ne, lt, gt, -/// le, or ge. -/// -class SetCondInst : public BinaryOperator { -public: - SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS, - const std::string &Name = "", Instruction *InsertBefore = 0); - SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS, - const std::string &Name, BasicBlock *InsertAtEnd); - - /// getInverseCondition - Return the inverse of the current condition opcode. - /// For example seteq -> setne, setgt -> setle, setlt -> setge, etc... - /// - BinaryOps getInverseCondition() const { - return getInverseCondition(getOpcode()); - } - - /// getInverseCondition - Static version that you can use without an - /// instruction available. - /// - static BinaryOps getInverseCondition(BinaryOps Opcode); - - /// getSwappedCondition - Return the condition opcode that would be the result - /// of exchanging the two operands of the setcc instruction without changing - /// the result produced. Thus, seteq->seteq, setle->setge, setlt->setgt, etc. - /// - BinaryOps getSwappedCondition() const { - return getSwappedCondition(getOpcode()); - } - - /// getSwappedCondition - Static version that you can use without an - /// instruction available. - /// - static BinaryOps getSwappedCondition(BinaryOps Opcode); - - /// isEquality - Return true if this comparison is an ==/!= comparison. - /// - bool isEquality() const { - return getOpcode() == SetEQ || getOpcode() == SetNE; - } - - /// isRelational - Return true if this comparison is a </>/<=/>= comparison. - /// - bool isRelational() const { - return !isEquality(); - } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SetCondInst *) { return true; } - static inline bool classof(const Instruction *I) { - return I->getOpcode() == SetEQ || I->getOpcode() == SetNE || - I->getOpcode() == SetLE || I->getOpcode() == SetGE || - I->getOpcode() == SetLT || I->getOpcode() == SetGT; - } - static inline bool classof(const Value *V) { - return isa<Instruction>(V) && classof(cast<Instruction>(V)); - } -}; - - //===----------------------------------------------------------------------===// // CallInst Class //===----------------------------------------------------------------------===// diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index 3a271bb..a5c1c61 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -36,7 +36,7 @@ #include <typeinfo> #include <cassert> -//#define USE_OLD_PASSMANAGER 1 +#define USE_OLD_PASSMANAGER 1 namespace llvm { diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h index f50e979..806dc80 100644 --- a/include/llvm/Support/ConstantRange.h +++ b/include/llvm/Support/ConstantRange.h @@ -12,13 +12,19 @@ // constant, which MAY wrap around the end of the numeric range. To do this, it // keeps track of a [lower, upper) bound, which specifies an interval just like // STL iterators. When used with boolean values, the following are important -// ranges (other integral ranges use min/max values for special range values): +// ranges: : // // [F, F) = {} = Empty set // [T, F) = {T} // [F, T) = {F} // [T, T) = {F, T} = Full set // +// The other integral ranges use min/max values for special range values. For +// example, for 8-bit types, it uses: +// [0, 0) = {} = Empty set +// [255, 255) = {0..255} = Full Set +// +// Note that ConstantRange always keeps unsigned values. //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_CONSTANT_RANGE_H @@ -51,9 +57,11 @@ class ConstantRange { /// ConstantRange(Constant *Lower, Constant *Upper); - /// Initialize a set of values that all satisfy the condition with C. - /// - ConstantRange(unsigned SetCCOpcode, ConstantIntegral *C); + /// Initialize a set of values that all satisfy the predicate with C. The + /// predicate should be either an ICmpInst::Predicate or FCmpInst::Predicate + /// value. + /// @brief Get a range for a relation with a constant integral. + ConstantRange(unsigned short predicate, ConstantIntegral *C); /// getLower - Return the lower value for this range... /// @@ -79,11 +87,13 @@ class ConstantRange { /// isWrappedSet - Return true if this set wraps around the top of the range, /// for example: [100, 8) /// - bool isWrappedSet() const; + bool isWrappedSet(bool isSigned) const; /// contains - Return true if the specified value is in the set. + /// The isSigned parameter indicates whether the comparisons should be + /// performed as if the values are signed or not. /// - bool contains(ConstantInt *Val) const; + bool contains(ConstantInt *Val, bool isSigned) const; /// getSingleElement - If this set contains a single element, return it, /// otherwise return null. @@ -117,7 +127,7 @@ class ConstantRange { /// one of the sets but not the other. For example: [100, 8) intersect [3, /// 120) yields [3, 120) /// - ConstantRange intersectWith(const ConstantRange &CR) const; + ConstantRange intersectWith(const ConstantRange &CR, bool isSigned) const; /// union - Return the range that results from the union of this range with /// another range. The resultant range is guaranteed to include the elements @@ -125,7 +135,7 @@ class ConstantRange { /// [3, 15), which includes 9, 10, and 11, which were not included in either /// set before. /// - ConstantRange unionWith(const ConstantRange &CR) const; + ConstantRange unionWith(const ConstantRange &CR, bool isSigned) const; /// zeroExtend - Return a new range in the specified integer type, which must /// be strictly larger than the current type. The returned range will diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index f444feb..15e5e98 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -167,7 +167,6 @@ public: RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} - RetTy visitSetCondInst(SetCondInst &I) { DELEGATE(BinaryOperator);} RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);} diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index 2974ad3..6db2142 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -248,13 +248,6 @@ struct BinaryOpClass_match { }; template<typename LHS, typename RHS> -inline BinaryOpClass_match<LHS, RHS, SetCondInst, Instruction::BinaryOps> -m_SetCond(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) { - return BinaryOpClass_match<LHS, RHS, - SetCondInst, Instruction::BinaryOps>(Op, L, R); -} - -template<typename LHS, typename RHS> inline BinaryOpClass_match<LHS, RHS, ShiftInst, Instruction::OtherOps> m_Shift(Instruction::OtherOps &Op, const LHS &L, const RHS &R) { return BinaryOpClass_match<LHS, RHS, @@ -270,6 +263,45 @@ m_Shift(const LHS &L, const RHS &R) { } //===----------------------------------------------------------------------===// +// Matchers for CmpInst classes +// + +template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy> +struct CmpClass_match { + PredicateTy &Predicate; + LHS_t L; + RHS_t R; + + CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, + const RHS_t &RHS) + : Predicate(Pred), L(LHS), R(RHS) {} + + template<typename OpTy> + bool match(OpTy *V) { + if (Class *I = dyn_cast<Class>(V)) + if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) { + Predicate = I->getPredicate(); + return true; + } + return false; + } +}; + +template<typename LHS, typename RHS> +inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate> +m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) { + return CmpClass_match<LHS, RHS, + ICmpInst, ICmpInst::Predicate>(Pred, L, R); +} + +template<typename LHS, typename RHS> +inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate> +m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) { + return CmpClass_match<LHS, RHS, + FCmpInst, FCmpInst::Predicate>(Pred, L, R); +} + +//===----------------------------------------------------------------------===// // Matchers for unary operators // diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 4ee2f1a..4fc016d 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -49,13 +49,15 @@ bool ConstantFoldTerminator(BasicBlock *BB); Constant *ConstantFoldInstruction(Instruction *I); /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the -/// specified opcode and operands. If successful, the constant result is -/// returned, if not, null is returned. Note that this function can fail when -/// attempting to fold instructions like loads and stores, which have no -/// constant expression form. +/// specified operands. If successful, the constant result is returned, if not, +/// null is returned. Note that this function can fail when attempting to +/// fold instructions like loads and stores, which have no constant expression +/// form. /// -Constant *ConstantFoldInstOperands(unsigned Opc, const Type *DestTy, - const std::vector<Constant*> &Ops); +Constant *ConstantFoldInstOperands( + const Instruction *I, ///< The model instruction + const std::vector<Constant*> &Ops ///< The constant operands to use. +); /// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a |