mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 05:29:24 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31867 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
36699cabc5
commit
45fb3f3cb2
@ -243,6 +243,91 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CmpInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// This class is the base class for the comparison instructions.
|
||||
/// @brief Abstract base class of comparison instructions.
|
||||
class CmpInst: public Instruction {
|
||||
CmpInst(); // do not implement
|
||||
protected:
|
||||
CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
|
||||
const std::string &Name = "", Instruction *InsertBefore = 0);
|
||||
|
||||
CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
|
||||
const std::string &Name, BasicBlock *InsertAtEnd);
|
||||
|
||||
Use Ops[2]; // CmpInst instructions always have 2 operands, optimize
|
||||
|
||||
public:
|
||||
/// Construct a compare instruction, given the opcode, the predicate and
|
||||
/// the two operands. Optionally (if InstBefore is specified) insert the
|
||||
/// instruction into a BasicBlock right before the specified instruction.
|
||||
/// The specified Instruction is allowed to be a dereferenced end iterator.
|
||||
/// @brief Create a CmpInst
|
||||
static CmpInst *create(OtherOps Op, unsigned short predicate, Value *S1,
|
||||
Value *S2, const std::string &Name = "",
|
||||
Instruction *InsertBefore = 0);
|
||||
|
||||
/// Construct a compare instruction, given the opcode, the predicate and the
|
||||
/// two operands. Also automatically insert this instruction to the end of
|
||||
/// the BasicBlock specified.
|
||||
/// @brief Create a CmpInst
|
||||
static CmpInst *create(OtherOps Op, unsigned short predicate, Value *S1,
|
||||
Value *S2, const std::string &Name,
|
||||
BasicBlock *InsertAtEnd);
|
||||
|
||||
/// @brief Implement superclass method.
|
||||
virtual CmpInst *clone() const;
|
||||
|
||||
/// The predicate for CmpInst is defined by the subclasses but stored in
|
||||
/// the SubclassData field (see Value.h). We allow it to be fetched here
|
||||
/// as the predicate but there is no enum type for it, just the raw unsigned
|
||||
/// short. This facilitates comparison of CmpInst instances without delving
|
||||
/// into the subclasses since predicate values are distinct between the
|
||||
/// CmpInst subclasses.
|
||||
/// @brief Return the predicate for this instruction.
|
||||
unsigned short getPredicate() const {
|
||||
return SubclassData;
|
||||
}
|
||||
|
||||
/// @brief Provide more efficient getOperand methods.
|
||||
Value *getOperand(unsigned i) const {
|
||||
assert(i < 2 && "getOperand() out of range!");
|
||||
return Ops[i];
|
||||
}
|
||||
void setOperand(unsigned i, Value *Val) {
|
||||
assert(i < 2 && "setOperand() out of range!");
|
||||
Ops[i] = Val;
|
||||
}
|
||||
|
||||
/// @brief CmpInst instructions always have 2 operands.
|
||||
unsigned getNumOperands() const { return 2; }
|
||||
|
||||
/// This is just a convenience that dispatches to the subclasses.
|
||||
/// @brief Swap the operands.
|
||||
void swapOperands();
|
||||
|
||||
/// This is just a convenience that dispatches to the subclasses.
|
||||
/// @brief Determine if this CmpInst is commutative.
|
||||
bool isCommutative();
|
||||
|
||||
/// This is just a convenience that dispatches to the subclasses.
|
||||
/// @brief Determine if this is an equals/not equals predicate.
|
||||
bool isEquality();
|
||||
|
||||
/// @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) {
|
||||
return I->getOpcode() == Instruction::ICmp ||
|
||||
I->getOpcode() == Instruction::FCmp;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -126,20 +126,22 @@ HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
|
||||
|
||||
// Other operators...
|
||||
FIRST_OTHER_INST(31)
|
||||
HANDLE_OTHER_INST(31, PHI , PHINode ) // PHI node instruction
|
||||
HANDLE_OTHER_INST(32, Cast , CastInst ) // Type cast
|
||||
HANDLE_OTHER_INST(33, Call , CallInst ) // Call a function
|
||||
HANDLE_OTHER_INST(34, Shl , ShiftInst ) // Shift Left operations (logical)
|
||||
HANDLE_OTHER_INST(35, LShr , ShiftInst ) // Logical Shift right (unsigned)
|
||||
HANDLE_OTHER_INST(36, AShr , ShiftInst ) // Arithmetic shift right (signed)
|
||||
HANDLE_OTHER_INST(37, Select , SelectInst ) // select instruction
|
||||
HANDLE_OTHER_INST(38, UserOp1, Instruction) // May be used internally in a pass
|
||||
HANDLE_OTHER_INST(39, UserOp2, Instruction) // Internal to passes only
|
||||
HANDLE_OTHER_INST(40, VAArg , VAArgInst ) // vaarg instruction
|
||||
HANDLE_OTHER_INST(41, ExtractElement, ExtractElementInst)// extract from vector.
|
||||
HANDLE_OTHER_INST(42, InsertElement, InsertElementInst) // insert into vector
|
||||
HANDLE_OTHER_INST(43, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
|
||||
LAST_OTHER_INST(43)
|
||||
HANDLE_OTHER_INST(31, ICmp , ICmpInst ) // Integer comparison instruction
|
||||
HANDLE_OTHER_INST(32, FCmp , FCmpInst ) // Floating point comparison instr.
|
||||
HANDLE_OTHER_INST(33, PHI , PHINode ) // PHI node instruction
|
||||
HANDLE_OTHER_INST(34, Cast , CastInst ) // Type cast
|
||||
HANDLE_OTHER_INST(35, Call , CallInst ) // Call a function
|
||||
HANDLE_OTHER_INST(36, Shl , ShiftInst ) // Shift Left operations (logical)
|
||||
HANDLE_OTHER_INST(37, LShr , ShiftInst ) // Logical Shift right (unsigned)
|
||||
HANDLE_OTHER_INST(38, AShr , ShiftInst ) // Arithmetic shift right (signed)
|
||||
HANDLE_OTHER_INST(39, Select , SelectInst ) // select instruction
|
||||
HANDLE_OTHER_INST(40, UserOp1, Instruction) // May be used internally in a pass
|
||||
HANDLE_OTHER_INST(41, UserOp2, Instruction) // Internal to passes only
|
||||
HANDLE_OTHER_INST(42, VAArg , VAArgInst ) // vaarg instruction
|
||||
HANDLE_OTHER_INST(43, ExtractElement, ExtractElementInst)// extract from vector.
|
||||
HANDLE_OTHER_INST(44, InsertElement, InsertElementInst) // insert into vector
|
||||
HANDLE_OTHER_INST(45, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
|
||||
LAST_OTHER_INST(45)
|
||||
|
||||
#undef FIRST_TERM_INST
|
||||
#undef HANDLE_TERM_INST
|
||||
|
@ -414,6 +414,239 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ICmpInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// This instruction compares its operands according to the predicate given
|
||||
/// to the constructor. It only operates on integers, pointers, or packed
|
||||
/// vectors of integrals. The two operands must be the same type.
|
||||
/// @brief Represent an integer comparison operator.
|
||||
class ICmpInst: public CmpInst {
|
||||
public:
|
||||
/// This enumeration lists the possible predicates for the ICmpInst. The
|
||||
/// values in the range 0-31 are reserved for FCmpInst while values in the
|
||||
/// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
|
||||
/// predicate values are not overlapping between the classes.
|
||||
enum Predicate {
|
||||
ICMP_EQ = 32, ///< equal
|
||||
ICMP_NE = 33, ///< not equal
|
||||
ICMP_UGT = 34, ///< unsigned greater than
|
||||
ICMP_UGE = 35, ///< unsigned greater or equal
|
||||
ICMP_ULT = 36, ///< unsigned less than
|
||||
ICMP_ULE = 37, ///< unsigned less or equal
|
||||
ICMP_SGT = 38, ///< signed greater than
|
||||
ICMP_SGE = 39, ///< signed greater or equal
|
||||
ICMP_SLT = 40, ///< signed less than
|
||||
ICMP_SLE = 41, ///< signed less or equal
|
||||
FIRST_ICMP_PREDICATE = ICMP_EQ,
|
||||
LAST_ICMP_PREDICATE = ICMP_SLE
|
||||
};
|
||||
|
||||
/// @brief Constructor with insert-before-instruction semantics.
|
||||
ICmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
Value *LHS, ///< The left-hand-side of the expression
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name = "", ///< Name of the instruction
|
||||
Instruction *InsertBefore = 0 ///< Where to insert
|
||||
) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertBefore) {
|
||||
}
|
||||
|
||||
/// @brief Constructor with insert-at-block-end semantics.
|
||||
ICmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
Value *LHS, ///< The left-hand-side of the expression
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name, ///< Name of the instruction
|
||||
BasicBlock *InsertAtEnd ///< Block to insert into.
|
||||
) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertAtEnd) {
|
||||
}
|
||||
|
||||
/// @brief Return the predicate for this instruction.
|
||||
Predicate getPredicate() const { return Predicate(SubclassData); }
|
||||
|
||||
/// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
|
||||
/// @returns the inverse predicate for the instruction's current predicate.
|
||||
/// @brief Return the inverse of the instruction's predicate.
|
||||
Predicate getInversePredicate() const {
|
||||
return getInversePredicate(getPredicate());
|
||||
}
|
||||
|
||||
/// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
|
||||
/// @returns the inverse predicate for predicate provided in \p pred.
|
||||
/// @brief Return the inverse of a given predicate
|
||||
static Predicate getInversePredicate(Predicate pred);
|
||||
|
||||
/// For example, EQ->EQ, SLE->SGE, ULT->UGT, etc.
|
||||
/// @returns the predicate that would be the result of exchanging the two
|
||||
/// operands of the ICmpInst instruction without changing the result
|
||||
/// produced.
|
||||
/// @brief Return the predicate as if the operands were swapped
|
||||
Predicate getSwappedPredicate() const {
|
||||
return getSwappedPredicate(getPredicate());
|
||||
}
|
||||
|
||||
/// 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);
|
||||
|
||||
/// This also tests for commutativity. If isEquality() returns true then
|
||||
/// the predicate is also commutative. Only the equality predicates are
|
||||
/// 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;
|
||||
}
|
||||
bool isCommutative() const { return isEquality(); }
|
||||
|
||||
/// @returns true if the predicate is relational (not EQ or NE).
|
||||
/// @brief Determine if this a relational predicate.
|
||||
bool isRelational() const {
|
||||
return !isEquality();
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// (e.g. ult).
|
||||
/// @brief Swap operands and adjust predicate.
|
||||
void swapOperands() {
|
||||
SubclassData = getSwappedPredicate();
|
||||
std::swap(Ops[0], Ops[1]);
|
||||
}
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const ICmpInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::ICmp;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FCmpInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// This instruction compares its operands according to the predicate given
|
||||
/// to the constructor. It only operates on floating point values or packed
|
||||
/// vectors of floating point values. The operands must be identical types.
|
||||
/// @brief Represents a floating point comparison operator.
|
||||
class FCmpInst: public CmpInst {
|
||||
public:
|
||||
/// This enumeration lists the possible predicates for the FCmpInst. Values
|
||||
/// in the range 0-31 are reserved for FCmpInst.
|
||||
enum Predicate {
|
||||
// Opcode U L G E Intuitive operation
|
||||
FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
|
||||
FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
|
||||
FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
|
||||
FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
|
||||
FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
|
||||
FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
|
||||
FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
|
||||
FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
|
||||
FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
|
||||
FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
|
||||
FCMP_UGT =10, ///< 1 0 1 0 True if unordered or greater than
|
||||
FCMP_UGE =11, ///< 1 0 1 1 True if unordered, greater than, or equal
|
||||
FCMP_ULT =12, ///< 1 1 0 0 True if unordered or less than
|
||||
FCMP_ULE =13, ///< 1 1 0 1 True if unordered, less than, or equal
|
||||
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
|
||||
};
|
||||
|
||||
/// @brief Constructor with insert-before-instruction semantics.
|
||||
FCmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
Value *LHS, ///< The left-hand-side of the expression
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name = "", ///< Name of the instruction
|
||||
Instruction *InsertBefore = 0 ///< Where to insert
|
||||
) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertBefore) {
|
||||
}
|
||||
|
||||
/// @brief Constructor with insert-at-block-end semantics.
|
||||
FCmpInst(
|
||||
Predicate pred, ///< The predicate to use for the comparison
|
||||
Value *LHS, ///< The left-hand-side of the expression
|
||||
Value *RHS, ///< The right-hand-side of the expression
|
||||
const std::string &Name, ///< Name of the instruction
|
||||
BasicBlock *InsertAtEnd ///< Block to insert into.
|
||||
) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertAtEnd) {
|
||||
}
|
||||
|
||||
/// @brief Return the predicate for this instruction.
|
||||
Predicate getPredicate() const { return Predicate(SubclassData); }
|
||||
|
||||
/// For example, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
|
||||
/// @returns the inverse predicate for the instructions current predicate.
|
||||
/// @brief Return the inverse of the predicate
|
||||
Predicate getInversePredicate() const {
|
||||
return getInversePredicate(getPredicate());
|
||||
}
|
||||
|
||||
/// For example, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
|
||||
/// @returns the inverse predicate for \p pred.
|
||||
/// @brief Return the inverse of a given predicate
|
||||
static Predicate getInversePredicate(Predicate pred);
|
||||
|
||||
/// For example, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
|
||||
/// @returns the predicate that would be the result of exchanging the two
|
||||
/// operands of the ICmpInst instruction without changing the result
|
||||
/// produced.
|
||||
/// @brief Return the predicate as if the operands were swapped
|
||||
Predicate getSwappedPredicate() const {
|
||||
return getSwappedPredicate(getPredicate());
|
||||
}
|
||||
|
||||
/// 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);
|
||||
|
||||
/// This also tests for commutativity. If isEquality() returns true then
|
||||
/// the predicate is also commutative. Only the equality predicates are
|
||||
/// 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 == FCMP_OEQ || SubclassData == FCMP_ONE ||
|
||||
SubclassData == FCMP_UEQ || SubclassData == FCMP_UNE;
|
||||
}
|
||||
bool isCommutative() const { return isEquality(); }
|
||||
|
||||
/// @returns true if the predicate is relational (not EQ or NE).
|
||||
/// @brief Determine if this a relational predicate.
|
||||
bool isRelational() const { return !isEquality(); }
|
||||
|
||||
/// 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
|
||||
/// (e.g. ult).
|
||||
/// @brief Swap operands and adjust predicate.
|
||||
void swapOperands() {
|
||||
SubclassData = getSwappedPredicate();
|
||||
std::swap(Ops[0], Ops[1]);
|
||||
}
|
||||
|
||||
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const FCmpInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::FCmp;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SetCondInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -169,6 +169,8 @@ public:
|
||||
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);}
|
||||
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
|
||||
RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }
|
||||
@ -192,6 +194,7 @@ public:
|
||||
RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); }
|
||||
RetTy visitAllocationInst(AllocationInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); }
|
||||
|
||||
// If the user wants a 'default' case, they can choose to override this
|
||||
// function. If this function is not overloaded in the users subclass, then
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)); }
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user