summaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2006-11-27 01:05:10 +0000
committerReid Spencer <rspencer@reidspencer.com>2006-11-27 01:05:10 +0000
commit3da59db637a887474c1b1346c1f3ccf53b6c4663 (patch)
treeb061e2133efdb9ea9bb334c1b15ceea881bb88f8 /include/llvm
parent5fed9b90447a9a95a1f670ccd9c23aea8c937451 (diff)
downloadllvm-3da59db637a887474c1b1346c1f3ccf53b6c4663.tar.gz
llvm-3da59db637a887474c1b1346c1f3ccf53b6c4663.tar.bz2
llvm-3da59db637a887474c1b1346c1f3ccf53b6c4663.tar.xz
For PR950:
The long awaited CAST patch. This introduces 12 new instructions into LLVM to replace the cast instruction. Corresponding changes throughout LLVM are provided. This passes llvm-test, llvm/test, and SPEC CPUINT2000 with the exception of 175.vpr which fails only on a slight floating point output difference. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31931 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h6
-rw-r--r--include/llvm/Constants.h28
-rw-r--r--include/llvm/InstrTypes.h155
-rw-r--r--include/llvm/Instruction.def69
-rw-r--r--include/llvm/Instruction.h17
-rw-r--r--include/llvm/Instructions.h509
-rw-r--r--include/llvm/Support/InstVisitor.h3
-rw-r--r--include/llvm/Support/PatternMatch.h34
-rw-r--r--include/llvm/Type.h10
9 files changed, 732 insertions, 99 deletions
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index 391c12b2ba..163d35761c 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -27,7 +27,7 @@ namespace llvm {
/// rewrite expressions in canonical form.
///
/// Clients should create an instance of this class when rewriting is needed,
- /// and destroying it when finished to allow the release of the associated
+ /// and destroy it when finished to allow the release of the associated
/// memory.
struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
ScalarEvolution &SE;
@@ -115,12 +115,12 @@ namespace llvm {
Value *visitTruncateExpr(SCEVTruncateExpr *S) {
Value *V = expand(S->getOperand());
- return new CastInst(V, S->getType(), "tmp.", InsertPt);
+ return CastInst::createInferredCast(V, S->getType(), "tmp.", InsertPt);
}
Value *visitZeroExtendExpr(SCEVZeroExtendExpr *S) {
Value *V = expandInTy(S->getOperand(),S->getType()->getUnsignedVersion());
- return new CastInst(V, S->getType(), "tmp.", InsertPt);
+ return CastInst::createInferredCast(V, S->getType(), "tmp.", InsertPt);
}
Value *visitAddExpr(SCEVAddExpr *S) {
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index 20f36438b1..f78ace36f8 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -516,9 +516,33 @@ public:
/// Cast constant expr
///
+ static Constant *getTrunc (Constant *C, const Type *Ty);
+ static Constant *getSignExtend (Constant *C, const Type *Ty);
+ static Constant *getZeroExtend (Constant *C, const Type *Ty);
+ static Constant *getFPTrunc (Constant *C, const Type *Ty);
+ static Constant *getFPExtend (Constant *C, const Type *Ty);
+ static Constant *getUIToFP (Constant *C, const Type *Ty);
+ static Constant *getSIToFP (Constant *C, const Type *Ty);
+ static Constant *getFPToUI (Constant *C, const Type *Ty);
+ static Constant *getFPToSI (Constant *C, const Type *Ty);
+ static Constant *getPtrToInt (Constant *C, const Type *Ty);
+ static Constant *getIntToPtr (Constant *C, const Type *Ty);
+ static Constant *getBitCast (Constant *C, const Type *Ty);
+
+ // @brief Convenience function for getting one of the casting operations
+ // using a CastOps opcode.
+ static Constant *getCast(
+ unsigned ops, ///< The opcode for the conversion
+ Constant *C, ///< The constant to be converted
+ const Type *Ty ///< The type to which the constant is converted
+ );
+
+ // @brief Get a ConstantExpr Conversion operator that casts C to Ty
static Constant *getCast(Constant *C, const Type *Ty);
- static Constant *getSignExtend(Constant *C, const Type *Ty);
- static Constant *getZeroExtend(Constant *C, const Type *Ty);
+
+ /// @brief Return true if this is a convert constant expression
+ bool isCast() const;
+
/// Select constant expr
///
diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h
index 627aad4304..0a489f3d08 100644
--- a/include/llvm/InstrTypes.h
+++ b/include/llvm/InstrTypes.h
@@ -244,6 +244,161 @@ public:
};
//===----------------------------------------------------------------------===//
+// CastInst Class
+//===----------------------------------------------------------------------===//
+
+/// CastInst - This is the base class for all instructions that perform data
+/// casts. It is simply provided so that instruction category testing
+/// can be performed with code like:
+///
+/// if (isa<CastInst>(Instr)) { ... }
+/// @brief Base class of casting instructions.
+class CastInst : public UnaryInstruction {
+ /// @brief Copy constructor
+ CastInst(const CastInst &CI)
+ : UnaryInstruction(CI.getType(), CI.getOpcode(), CI.getOperand(0)) {
+ }
+ /// @brief Do not allow default construction
+ CastInst();
+protected:
+ /// @brief Constructor with insert-before-instruction semantics for subclasses
+ CastInst(const Type *Ty, unsigned iType, Value *S,
+ const std::string &Name = "", Instruction *InsertBefore = 0)
+ : UnaryInstruction(Ty, iType, S, Name, InsertBefore) {
+ }
+ /// @brief Constructor with insert-at-end-of-block semantics for subclasses
+ CastInst(const Type *Ty, unsigned iType, Value *S,
+ const std::string &Name, BasicBlock *InsertAtEnd)
+ : UnaryInstruction(Ty, iType, S, Name, InsertAtEnd) {
+ }
+public:
+ /// Provides a way to construct any of the CastInst subclasses using an
+ /// opcode instead of the subclass's constructor. The opcode must be in the
+ /// CastOps category (Instruction::isCast(opcode) returns true). This
+ /// constructor has insert-before-instruction semantics to automatically
+ /// insert the new CastInst before InsertBefore (if it is non-null).
+ /// @brief Construct any of the CastInst subclasses
+ static CastInst *create(
+ Instruction::CastOps, ///< The opcode of the cast instruction
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+ /// Provides a way to construct any of the CastInst subclasses using an
+ /// opcode instead of the subclass's constructor. The opcode must be in the
+ /// CastOps category. This constructor has insert-at-end-of-block semantics
+ /// to automatically insert the new CastInst at the end of InsertAtEnd (if
+ /// its non-null).
+ /// @brief Construct any of the CastInst subclasses
+ static CastInst *create(
+ Instruction::CastOps, ///< The opcode for the cast instruction
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which operand is casted
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// Returns the opcode necessary to cast Val into Ty using usual casting
+ /// rules.
+ static Instruction::CastOps getCastOpcode(
+ const Value *Val, ///< The value to cast
+ const Type *Ty ///< The Type to which the value should be casted
+ );
+
+ /// Joins the create method (with insert-before-instruction semantics) above
+ /// with the getCastOpcode method. getOpcode(S,Ty) is called first to
+ /// obtain the opcode for casting S to type Ty. Then the get(...) method is
+ /// called to create the CastInst and insert it. The instruction is
+ /// inserted before InsertBefore (if it is non-null). The cast created is
+ /// inferred, because only the types involved are used in determining which
+ /// cast opcode to use. For specific casts, use one of the create methods.
+ /// @brief Inline helper method to join create with getCastOpcode.
+ inline static CastInst *createInferredCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< Type to which operand should be casted
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the CastInst
+ ) {
+ return create(getCastOpcode(S, Ty), S, Ty, Name, InsertBefore);
+ }
+
+ /// Joins the get method (with insert-at-end-of-block semantics) method
+ /// above with the getCastOpcode method. getOpcode(S,Ty) is called first to
+ /// obtain the usual casting opcode for casting S to type Ty. Then the
+ /// get(...) method is called to create the CastInst and insert it. The
+ /// instruction is inserted at the end of InsertAtEnd (if it is non-null).
+ /// The created cast is inferred, because only the types involved are used
+ /// in determining which cast opcode to use. For specific casts, use one of
+ /// the create methods.
+ /// @brief Inline helper method to join create with getCastOpcode.
+ inline static CastInst *createInferredCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< Type to which operand should be casted
+ const std::string &Name, ///< Name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ ) {
+ return create(getCastOpcode(S, Ty), S, Ty, Name, InsertAtEnd);
+ }
+
+ /// There are several places where we need to know if a cast instruction
+ /// only deals with integer source and destination types. To simplify that
+ /// logic, this method is provided.
+ /// @returns true iff the cast has only integral typed operand and dest type.
+ /// @brief Determine if this is an integer-only cast.
+ bool isIntegerCast() const;
+
+ /// A lossless cast is one that does not alter the basic value. It implies
+ /// a no-op cast but is more stringent, preventing things like int->float,
+ /// long->double, int->ptr, or packed->anything.
+ /// @returns true iff the cast is lossless.
+ /// @brief Determine if this is a lossless cast.
+ bool isLosslessCast() const;
+
+ /// A no-op cast is one that can be effected without changing any bits.
+ /// It implies that the source and destination types are the same size. The
+ /// IntPtrTy argument is used to make accurate determinations for casts
+ /// involving Integer and Pointer types. They are no-op casts if the integer
+ /// is the same size as the pointer. However, pointer size varies with
+ /// platform. Generally, the result of TargetData::getIntPtrType() should be
+ /// passed in. If that's not available, use Type::ULongTy, which will make
+ /// the isNoopCast call conservative.
+ /// @brief Determine if this cast is a no-op cast.
+ bool isNoopCast(
+ const Type *IntPtrTy ///< Integer type corresponding to pointer
+ ) const;
+
+ /// Determine how a pair of casts can be eliminated, if they can be at all.
+ /// This is a helper function for both CastInst and ConstantExpr.
+ /// @returns 0 if the CastInst pair can't be eliminated
+ /// @returns Instruction::CastOps value for a cast that can replace
+ /// the pair, casting SrcTy to DstTy.
+ /// @brief Determine if a cast pair is eliminable
+ static unsigned isEliminableCastPair(
+ Instruction::CastOps firstOpcode, ///< Opcode of first cast
+ Instruction::CastOps secondOpcode, ///< Opcode of second cast
+ const Type *SrcTy, ///< SrcTy of 1st cast
+ const Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast
+ const Type *DstTy, ///< DstTy of 2nd cast
+ const Type *IntPtrTy ///< Integer type corresponding to Ptr types
+ );
+
+ /// @brief Return the opcode of this CastInst
+ Instruction::CastOps getOpcode() const {
+ return Instruction::CastOps(Instruction::getOpcode());
+ }
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const CastInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
// CmpInst Class
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def
index 55c668ab1a..dac14d33bd 100644
--- a/include/llvm/Instruction.def
+++ b/include/llvm/Instruction.def
@@ -60,6 +60,20 @@
#define LAST_MEMORY_INST(num)
#endif
+#ifndef FIRST_CAST_INST
+#define FIRST_CAST_INST(num)
+#endif
+#ifndef HANDLE_CAST_INST
+#ifndef HANDLE_INST
+#define HANDLE_CAST_INST(num, opcode, Class)
+#else
+#define HANDLE_CAST_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_CAST_INST
+#define LAST_CAST_INST(num)
+#endif
+
#ifndef FIRST_OTHER_INST
#define FIRST_OTHER_INST(num)
#endif
@@ -124,24 +138,41 @@ HANDLE_MEMORY_INST(29, Store , StoreInst )
HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
LAST_MEMORY_INST(30)
+// 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 , CastInst ) // Truncate integers
+HANDLE_CAST_INST(32, ZExt , CastInst ) // Zero extend integers
+HANDLE_CAST_INST(33, SExt , CastInst ) // Sign extend integers
+HANDLE_CAST_INST(34, FPToUI , CastInst ) // floating point -> UInt
+HANDLE_CAST_INST(35, FPToSI , CastInst ) // floating point -> SInt
+HANDLE_CAST_INST(36, UIToFP , CastInst ) // UInt -> floating point
+HANDLE_CAST_INST(37, SIToFP , CastInst ) // SInt -> floating point
+HANDLE_CAST_INST(38, FPTrunc , CastInst ) // Truncate floating point
+HANDLE_CAST_INST(39, FPExt , CastInst ) // Extend floating point
+HANDLE_CAST_INST(40, PtrToInt, CastInst ) // Pointer -> Integer
+HANDLE_CAST_INST(41, IntToPtr, CastInst ) // Integer -> Pointer
+HANDLE_CAST_INST(42, BitCast , CastInst ) // Type cast
+ LAST_CAST_INST(42)
+
// Other operators...
- FIRST_OTHER_INST(31)
-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)
+ 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)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST
@@ -155,6 +186,10 @@ HANDLE_OTHER_INST(45, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
#undef HANDLE_MEMORY_INST
#undef LAST_MEMORY_INST
+#undef FIRST_CAST_INST
+#undef HANDLE_CAST_INST
+#undef LAST_CAST_INST
+
#undef FIRST_OTHER_INST
#undef HANDLE_OTHER_INST
#undef LAST_OTHER_INST
diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h
index 591e0d2b88..4af83c7a56 100644
--- a/include/llvm/Instruction.h
+++ b/include/llvm/Instruction.h
@@ -125,6 +125,16 @@ public:
return getOpcode() >= BinaryOpsBegin && getOpcode() < BinaryOpsEnd;
}
+ /// @brief Determine if the OpCode is one of the CastInst instructions.
+ static inline bool isCast(unsigned OpCode) {
+ return OpCode >= CastOpsBegin && OpCode < CastOpsEnd;
+ }
+
+ /// @brief Determine if this is one of the CastInst instructions.
+ inline bool isCast() const {
+ return isCast(getOpcode());
+ }
+
/// isAssociative - Return true if the instruction is associative:
///
/// Associative operators satisfy: x op (y op z) === (x op y) op z
@@ -191,6 +201,13 @@ public:
#include "llvm/Instruction.def"
};
+ enum CastOps {
+#define FIRST_CAST_INST(N) CastOpsBegin = N,
+#define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N,
+#define LAST_CAST_INST(N) CastOpsEnd = N+1
+#include "llvm/Instruction.def"
+ };
+
enum OtherOps {
#define FIRST_OTHER_INST(N) OtherOpsBegin = N,
#define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N,
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 8046567fde..5f7125678d 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -710,44 +710,6 @@ public:
}
};
-//===----------------------------------------------------------------------===//
-// CastInst Class
-//===----------------------------------------------------------------------===//
-
-/// CastInst - This class represents a cast from Operand[0] to the type of
-/// the instruction (i->getType()).
-///
-class CastInst : public UnaryInstruction {
- CastInst(const CastInst &CI)
- : UnaryInstruction(CI.getType(), Cast, CI.getOperand(0)) {
- }
-public:
- CastInst(Value *S, const Type *Ty, const std::string &Name = "",
- Instruction *InsertBefore = 0)
- : UnaryInstruction(Ty, Cast, S, Name, InsertBefore) {
- }
- CastInst(Value *S, const Type *Ty, const std::string &Name,
- BasicBlock *InsertAtEnd)
- : UnaryInstruction(Ty, Cast, S, Name, InsertAtEnd) {
- }
-
- /// isTruncIntCast - Return true if this is a truncating integer cast
- /// instruction, e.g. a cast from long to uint.
- bool isTruncIntCast() const;
-
-
- virtual CastInst *clone() const;
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const CastInst *) { return true; }
- static inline bool classof(const Instruction *I) {
- return I->getOpcode() == Cast;
- }
- static inline bool classof(const Value *V) {
- return isa<Instruction>(V) && classof(cast<Instruction>(V));
- }
-};
-
//===----------------------------------------------------------------------===//
// CallInst Class
@@ -1770,6 +1732,477 @@ private:
virtual void setSuccessorV(unsigned idx, BasicBlock *B);
};
+//===----------------------------------------------------------------------===//
+// TruncInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a truncation of integer types.
+class TruncInst : public CastInst {
+ /// Private copy constructor
+ TruncInst(const TruncInst &CI)
+ : CastInst(CI.getType(), Trunc, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ TruncInst(
+ Value *S, ///< The value to be truncated
+ const Type *Ty, ///< The (smaller) type to truncate to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ TruncInst(
+ Value *S, ///< The value to be truncated
+ const Type *Ty, ///< The (smaller) type to truncate to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical TruncInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const TruncInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Trunc;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// ZExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents zero extension of integer types.
+class ZExtInst : public CastInst {
+ /// @brief Private copy constructor
+ ZExtInst(const ZExtInst &CI)
+ : CastInst(CI.getType(), ZExt, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ ZExtInst(
+ Value *S, ///< The value to be zero extended
+ const Type *Ty, ///< The type to zero extend to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end semantics.
+ ZExtInst(
+ Value *S, ///< The value to be zero extended
+ const Type *Ty, ///< The type to zero extend to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical ZExtInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ZExtInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == ZExt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// SExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a sign extension of integer types.
+class SExtInst : public CastInst {
+ /// @brief Private copy constructor
+ SExtInst(const SExtInst &CI)
+ : CastInst(CI.getType(), SExt, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ SExtInst(
+ Value *S, ///< The value to be sign extended
+ const Type *Ty, ///< The type to sign extend to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ SExtInst(
+ Value *S, ///< The value to be sign extended
+ const Type *Ty, ///< The type to sign extend to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical SExtInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SExtInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == SExt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPTruncInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a truncation of floating point types.
+class FPTruncInst : public CastInst {
+ FPTruncInst(const FPTruncInst &CI)
+ : CastInst(CI.getType(), FPTrunc, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPTruncInst(
+ Value *S, ///< The value to be truncated
+ const Type *Ty, ///< The type to truncate to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-before-instruction semantics
+ FPTruncInst(
+ Value *S, ///< The value to be truncated
+ const Type *Ty, ///< The type to truncate to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical FPTruncInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FPTruncInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPTrunc;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents an extension of floating point types.
+class FPExtInst : public CastInst {
+ FPExtInst(const FPExtInst &CI)
+ : CastInst(CI.getType(), FPExt, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPExtInst(
+ Value *S, ///< The value to be extended
+ const Type *Ty, ///< The type to extend to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ FPExtInst(
+ Value *S, ///< The value to be extended
+ const Type *Ty, ///< The type to extend to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical FPExtInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FPExtInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPExt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// UIToFPInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast unsigned integer to floating point.
+class UIToFPInst : public CastInst {
+ UIToFPInst(const UIToFPInst &CI)
+ : CastInst(CI.getType(), UIToFP, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ UIToFPInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ UIToFPInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical UIToFPInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const UIToFPInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == UIToFP;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// SIToFPInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from signed integer to floating point.
+class SIToFPInst : public CastInst {
+ SIToFPInst(const SIToFPInst &CI)
+ : CastInst(CI.getType(), SIToFP, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ SIToFPInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ SIToFPInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical SIToFPInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SIToFPInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == SIToFP;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPToUIInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from floating point to unsigned integer
+class FPToUIInst : public CastInst {
+ FPToUIInst(const FPToUIInst &CI)
+ : CastInst(CI.getType(), FPToUI, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPToUIInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ FPToUIInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< Where to insert the new instruction
+ );
+
+ /// @brief Clone an identical FPToUIInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FPToUIInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPToUI;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPToSIInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from floating point to signed integer.
+class FPToSIInst : public CastInst {
+ FPToSIInst(const FPToSIInst &CI)
+ : CastInst(CI.getType(), FPToSI, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPToSIInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ FPToSIInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical FPToSIInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FPToSIInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPToSI;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// IntToPtrInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from an integer to a pointer.
+class IntToPtrInst : public CastInst {
+ IntToPtrInst(const IntToPtrInst &CI)
+ : CastInst(CI.getType(), IntToPtr, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ IntToPtrInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ IntToPtrInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical IntToPtrInst
+ virtual CastInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const IntToPtrInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == IntToPtr;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// PtrToIntInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from a pointer to an integer
+class PtrToIntInst : public CastInst {
+ PtrToIntInst(const PtrToIntInst &CI)
+ : CastInst(CI.getType(), PtrToInt, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ PtrToIntInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ PtrToIntInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical PtrToIntInst
+ virtual CastInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const PtrToIntInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == PtrToInt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// BitCastInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a no-op cast from one type to another.
+class BitCastInst : public CastInst {
+ BitCastInst(const BitCastInst &CI)
+ : CastInst(CI.getType(), BitCast, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ BitCastInst(
+ Value *S, ///< The value to be casted
+ const Type *Ty, ///< The type to casted to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ BitCastInst(
+ Value *S, ///< The value to be casted
+ const Type *Ty, ///< The type to casted to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical BitCastInst
+ virtual CastInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BitCastInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == BitCast;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
index 713980a86b..e3103a4c38 100644
--- a/include/llvm/Support/InstVisitor.h
+++ b/include/llvm/Support/InstVisitor.h
@@ -143,7 +143,6 @@ public:
void visitFunction (Function &F) {}
void visitBasicBlock(BasicBlock &BB) {}
-
// Define instruction specific visitor functions that can be overridden to
// handle SPECIFIC instructions. These functions automatically define
// visitMul to proxy to visitBinaryOperator for instance in case the user does
@@ -183,7 +182,7 @@ public:
RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); }
RetTy visitShiftInst(ShiftInst &I) { DELEGATE(Instruction); }
RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(Instruction); }
- RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction); }
+ RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); }
RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); }
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index 56f7a9c4f9..2974ad39d4 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -10,7 +10,7 @@
// This file provides a simple and efficient mechanism for performing general
// tree-based pattern matches on the LLVM IR. The power of these routines is
// that it allows you to write concise patterns that are expressive and easy to
-// understand. The other major advantage of this is that is allows to you
+// understand. The other major advantage of this is that it allows you to
// trivially capture/bind elements in the pattern to variables. For example,
// you can do something like this:
//
@@ -336,38 +336,6 @@ template<typename LHS>
inline not_match<LHS> m_Not(const LHS &L) { return L; }
-template<typename Op_t>
-struct cast_match {
- Op_t Op;
- const Type **DestTy;
-
- cast_match(const Op_t &op, const Type **destTy) : Op(op), DestTy(destTy) {}
-
- template<typename OpTy>
- bool match(OpTy *V) {
- if (CastInst *I = dyn_cast<CastInst>(V)) {
- if (DestTy) *DestTy = I->getType();
- return Op.match(I->getOperand(0));
- } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
- if (CE->getOpcode() == Instruction::Cast) {
- if (DestTy) *DestTy = CE->getType();
- return Op.match(CE->getOperand(0));
- }
- }
- return false;
- }
-};
-
-template<typename Op_t>
-inline cast_match<Op_t> m_Cast(const Op_t &Op, const Type *&Ty) {
- return cast_match<Op_t>(Op, &Ty);
-}
-template<typename Op_t>
-inline cast_match<Op_t> m_Cast(const Op_t &Op) {
- return cast_match<Op_t>(Op, 0);
-}
-
-
//===----------------------------------------------------------------------===//
// Matchers for control flow
//
diff --git a/include/llvm/Type.h b/include/llvm/Type.h
index dab6c127cd..6f1957414a 100644
--- a/include/llvm/Type.h
+++ b/include/llvm/Type.h
@@ -194,10 +194,12 @@ public:
///
inline bool isAbstract() const { return Abstract; }
- /// isLosslesslyConvertibleTo - Return true if this type can be converted to
- /// 'Ty' without any reinterpretation of bits. For example, uint to int.
- ///
- bool isLosslesslyConvertibleTo(const Type *Ty) const;
+ /// canLosslesslyBitCastTo - Return true if this type could be converted
+ /// with a lossless BitCast to type 'Ty'. For example, uint to int. BitCasts
+ /// are valid for types of the same size only where no re-interpretation of
+ /// the bits is done.
+ /// @brief Determine if this type could be losslessly bitcast to Ty
+ bool canLosslesslyBitCastTo(const Type *Ty) const;
/// Here are some useful little methods to query what type derived types are