For PR411:
[oota-llvm.git] / include / llvm / InstrTypes.h
index 0a489f3d08d5e0e7c9e4ac7510384762e16d00fe..348671a527ab3958d41bb49edb3669a6314b355a 100644 (file)
@@ -299,47 +299,113 @@ public:
     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
+  /// @brief Create a ZExt or BitCast cast instruction
+  static CastInst *createZExtOrBitCast(
+    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
   );
 
-  /// 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
+  /// @brief Create a ZExt or BitCast cast instruction
+  static CastInst *createZExtOrBitCast(
+    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
+  );
+
+  /// @brief Create a SExt or BitCast cast instruction
+  static CastInst *createSExtOrBitCast(
+    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 CastInst
-  ) {
-    return create(getCastOpcode(S, Ty), S, Ty, Name, InsertBefore);
-  }
+    Instruction *InsertBefore = 0 ///< Place to insert the instruction
+  );
 
-  /// 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);
-  }
+  /// @brief Create a BitCast or a PtrToInt cast instruction
+  static CastInst *createPointerCast(
+    Value *S,                ///< The pointer 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
+  );
+
+  /// @brief Create a BitCast or a PtrToInt cast instruction
+  static CastInst *createPointerCast(
+    Value *S,                ///< The pointer 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
+  );
+
+  /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
+  static CastInst *createIntegerCast(
+    Value *S,                ///< The pointer value to be casted (operand 0)
+    const Type *Ty,          ///< The type to which cast should be made
+    bool isSigned,           ///< Whether to regard S as signed or not
+    const std::string &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = 0 ///< Place to insert the instruction
+  );
+
+  /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
+  static CastInst *createIntegerCast(
+    Value *S,                ///< The integer value to be casted (operand 0)
+    const Type *Ty,          ///< The integer type to which operand is casted
+    bool isSigned,           ///< Whether to regard S as signed or not
+    const std::string &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
+  static CastInst *createFPCast(
+    Value *S,                ///< The floating point value to be casted 
+    const Type *Ty,          ///< The floating point type to cast to
+    const std::string &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = 0 ///< Place to insert the instruction
+  );
+
+  /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
+  static CastInst *createFPCast(
+    Value *S,                ///< The floating point value to be casted 
+    const Type *Ty,          ///< The floating point type to cast to
+    const std::string &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Create a SExt or BitCast cast instruction
+  static CastInst *createSExtOrBitCast(
+    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
+  );
+
+  /// @brief Create a Trunc or BitCast cast instruction
+  static CastInst *createTruncOrBitCast(
+    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
+  );
+
+  /// @brief Create a Trunc or BitCast cast instruction
+  static CastInst *createTruncOrBitCast(
+    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. 
+  /// @brief Infer the opcode for cast operand and type
+  static Instruction::CastOps getCastOpcode(
+    const Value *Val, ///< The value to cast
+    bool SrcIsSigned, ///< Whether to treat the source as signed
+    const Type *Ty,   ///< The Type to which the value should be casted
+    bool DstIsSigned  ///< Whether to treate the dest. as signed
+  );
 
   /// There are several places where we need to know if a cast instruction 
   /// only deals with integer source and destination types. To simplify that
@@ -361,7 +427,7 @@ public:
   /// 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
+  /// passed in. If that's not available, use Type::Int64Ty, which will make
   /// the isNoopCast call conservative.
   /// @brief Determine if this cast is a no-op cast. 
   bool isNoopCast(
@@ -388,6 +454,17 @@ public:
     return Instruction::CastOps(Instruction::getOpcode()); 
   }
 
+  /// @brief Return the source type, as a convenience
+  const Type* getSrcTy() const { return getOperand(0)->getType(); }
+  /// @brief Return the destination type, as a convenience
+  const Type* getDestTy() const { return getType(); }
+
+  /// This method can be used to determine if a cast from S to DstTy using
+  /// Opcode op is valid or not. 
+  /// @returns true iff the proposed cast is valid.
+  /// @brief Determine if a cast is valid without creating one.
+  static bool castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy);
+
   /// @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) {
@@ -436,6 +513,11 @@ public:
   /// @brief Implement superclass method.
   virtual CmpInst *clone() const;
 
+  /// @brief Get the opcode casted to the right type
+  OtherOps getOpcode() const {
+    return static_cast<OtherOps>(Instruction::getOpcode());
+  }
+
   /// 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 
@@ -461,7 +543,8 @@ public:
   unsigned getNumOperands() const { return 2; }
 
   /// This is just a convenience that dispatches to the subclasses.
-  /// @brief Swap the operands.
+  /// @brief Swap the operands and adjust predicate accordingly to retain
+  /// the same comparison.
   void swapOperands();
 
   /// This is just a convenience that dispatches to the subclasses.
@@ -472,6 +555,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) {