Take a baby step towards getting rid of inferred casts. Provide methods on
authorReid Spencer <rspencer@reidspencer.com>
Mon, 4 Dec 2006 02:43:42 +0000 (02:43 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Mon, 4 Dec 2006 02:43:42 +0000 (02:43 +0000)
CastInst and ConstantExpr that allow the signedness to be explicitly passed
in and reliance on signedness removed from getCastOpcode. These are
temporary measures useful during the conversion of inferred casts.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32164 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Constants.h
include/llvm/InstrTypes.h
lib/VMCore/Constants.cpp
lib/VMCore/Instructions.cpp

index 06aaca65d5de785f5113ec38b7aaa96dce8bd564..335913813bcbe9dd4a913e995360fd53feda8bbd 100644 (file)
@@ -541,8 +541,15 @@ public:
     const Type *Ty ///< The type to which the constant is converted
   );
 
+  // This method uses the CastInst::getCastOpcode method to infer the
+  // cast opcode to use. 
   // @brief Get a ConstantExpr Conversion operator that casts C to Ty
-  static Constant *getCast(Constant *C, const Type *Ty);
+  static Constant *getInferredCast(Constant *C, bool SrcIsSigned, 
+                                   const Type *Ty, bool DestIsSigned);
+
+  static Constant *getCast(Constant *C, const Type *Ty) {
+    return getInferredCast(C, C->getType()->isSigned(), Ty, Ty->isSigned());
+  }
 
   /// @brief Return true if this is a convert constant expression
   bool isCast() const;
index 0a489f3d08d5e0e7c9e4ac7510384762e16d00fe..07d13da59d5206967922b6b304a3e5bfd87ded49 100644 (file)
@@ -303,7 +303,9 @@ public:
   /// rules.
   static Instruction::CastOps getCastOpcode(
     const Value *Val, ///< The value to cast
-    const Type *Ty    ///< The Type to which the value should be casted
+    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
   );
 
   /// Joins the create method (with insert-before-instruction semantics) above 
@@ -316,12 +318,21 @@ public:
   /// @brief Inline helper method to join create with getCastOpcode.
   inline static CastInst *createInferredCast(
     Value *S,                     ///< The value to be casted (operand 0)
+    bool SrcIsSigned,             ///< Whether to treat the source as signed
     const Type *Ty,               ///< Type to which operand should be casted
+    bool DstIsSigned,             ///< Whether to treate the dest. as signed
     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);
+    return create(getCastOpcode(S, SrcIsSigned, Ty, DstIsSigned), 
+                  S, Ty, Name, InsertBefore);
   }
+  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
+  );
 
   /// Joins the get method (with insert-at-end-of-block semantics) method 
   /// above with the getCastOpcode method. getOpcode(S,Ty) is called first to
@@ -334,13 +345,23 @@ public:
   /// @brief Inline helper method to join create with getCastOpcode.
   inline static CastInst *createInferredCast(
     Value *S,                     ///< The value to be casted (operand 0)
+    bool SrcIsSigned,             ///< Whether to treat the source as signed
     const Type *Ty,               ///< Type to which operand should be casted
+    bool DstIsSigned,             ///< Whether to treate the dest. as signed
     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);
+    return create(getCastOpcode(S, SrcIsSigned, Ty, DstIsSigned), 
+                  S, Ty, Name, InsertAtEnd);
   }
 
+  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
+  );
+
   /// 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.
index 71615b2c4a98ec4b9af7be02118149be0d6782fe..10fdda504c37f96aeecdecdabf0c47982df48441 100644 (file)
@@ -1486,9 +1486,11 @@ static inline Constant *getFoldedCast(
   return ExprConstants->getOrCreate(Ty, Key);
 }
 
-Constant *ConstantExpr::getCast( Constant *C, const Type *Ty ) {
+Constant *ConstantExpr::getInferredCast(Constant *C, bool SrcIsSigned, 
+                                const Type *Ty, bool DestIsSigned) {
   // Note: we can't inline this because it requires the Instructions.h header
-  return getCast(CastInst::getCastOpcode(C, Ty), C, Ty);
+  return getCast(
+    CastInst::getCastOpcode(C, SrcIsSigned, Ty, DestIsSigned), C, Ty);
 }
 
 Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
@@ -1612,10 +1614,9 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
 
 Constant *ConstantExpr::getSizeOf(const Type *Ty) {
   // sizeof is implemented as: (ulong) gep (Ty*)null, 1
-  return getCast(
-    getGetElementPtr(getNullValue(PointerType::get(Ty)),
-                 std::vector<Constant*>(1, ConstantInt::get(Type::UIntTy, 1))),
-    Type::ULongTy);
+  return getCast(Instruction::PtrToInt, getGetElementPtr(getNullValue(
+    PointerType::get(Ty)), std::vector<Constant*>(1, 
+    ConstantInt::get(Type::UIntTy, 1))), Type::ULongTy);
 }
 
 Constant *ConstantExpr::getPtrPtrFromArrayPtr(Constant *C) {
index f4866423176d9da9b9c35fb77a0e1f20927d2eb4..de1ebced7bcc4f6b74d0e23fb29131f095b44db5 100644 (file)
@@ -1507,7 +1507,8 @@ CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty,
 // should not assert in checkCast. In other words, this produces a "correct"
 // casting opcode for the arguments passed to it.
 Instruction::CastOps
-CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
+CastInst::getCastOpcode(
+  const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
   // Get the bit sizes, we'll need these
   const Type *SrcTy = Src->getType();
   unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();   // 0 for ptr/packed
@@ -1519,7 +1520,7 @@ CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
       if (DestBits < SrcBits)
         return Trunc;                               // int -> smaller int
       else if (DestBits > SrcBits) {                // its an extension
-        if (SrcTy->isSigned())
+        if (SrcIsSigned)
           return SExt;                              // signed -> SEXT
         else
           return ZExt;                              // unsigned -> ZEXT
@@ -1527,7 +1528,7 @@ CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
         return BitCast;                             // Same size, No-op cast
       }
     } else if (SrcTy->isFloatingPoint()) {          // Casting from floating pt
-      if (DestTy->isSigned()
+      if (DestIsSigned
         return FPToSI;                              // FP -> sint
       else
         return FPToUI;                              // FP -> uint 
@@ -1542,7 +1543,7 @@ CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
     }
   } else if (DestTy->isFloatingPoint()) {           // Casting to floating pt
     if (SrcTy->isIntegral()) {                      // Casting from integral
-      if (SrcTy->isSigned())
+      if (SrcIsSigned)
         return SIToFP;                              // sint -> FP
       else
         return UIToFP;                              // uint -> FP
@@ -1649,6 +1650,20 @@ checkCast(Instruction::CastOps op, Value *S, const Type *DstTy) {
   }
 }
 
+CastInst *CastInst::createInferredCast(
+  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore)
+{
+  return createInferredCast(S, S->getType()->isSigned(), Ty, Ty->isSigned(),
+      Name, InsertBefore);
+}
+
+CastInst *CastInst::createInferredCast(
+  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) 
+{
+  return createInferredCast(S, S->getType()->isSigned(), Ty, Ty->isSigned(),
+      Name, InsertAtEnd);
+}
+
 TruncInst::TruncInst(
   Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
 ) : CastInst(Ty, Trunc, S, Name, InsertBefore) {