[llvm-commits] CVS: llvm/lib/Transforms/ExprTypeConvert.cpp LevelRaise.cpp

Reid Spencer reid at x10sys.com
Sun Nov 26 17:06:25 PST 2006



Changes in directory llvm/lib/Transforms:

ExprTypeConvert.cpp updated: 1.113 -> 1.114
LevelRaise.cpp updated: 1.112 -> 1.113
---
Log message:

For PR950: http://llvm.org/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.


---
Diffs of the changes:  (+53 -73)

 ExprTypeConvert.cpp |   67 ++++++++++++++++------------------------------------
 LevelRaise.cpp      |   59 ++++++++++++++++++++++++---------------------
 2 files changed, 53 insertions(+), 73 deletions(-)


Index: llvm/lib/Transforms/ExprTypeConvert.cpp
diff -u llvm/lib/Transforms/ExprTypeConvert.cpp:1.113 llvm/lib/Transforms/ExprTypeConvert.cpp:1.114
--- llvm/lib/Transforms/ExprTypeConvert.cpp:1.113	Sun Nov 26 03:17:06 2006
+++ llvm/lib/Transforms/ExprTypeConvert.cpp	Sun Nov 26 19:05:10 2006
@@ -52,12 +52,10 @@
   if (I == 0) return false;              // Otherwise, we can't convert!
 
   switch (I->getOpcode()) {
-  case Instruction::Cast:
-    // We can convert the expr if the cast destination type is losslessly
-    // convertible to the requested type.
-    if (!Ty->isLosslesslyConvertibleTo(I->getType())) return false;
-
-    // We also do not allow conversion of a cast that casts from a ptr to array
+  case Instruction::BitCast:
+    if (!cast<BitCastInst>(I)->isLosslessCast())
+      return false;
+    // We do not allow conversion of a cast that casts from a ptr to array
     // of X to a *X.  For example: cast [4 x %List *] * %val to %List * *
     //
     if (const PointerType *SPT =
@@ -66,6 +64,7 @@
         if (const ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType()))
           if (AT->getElementType() == DPT->getElementType())
             return false;
+    // Otherwise it is a lossless cast and we can allow it
     break;
 
   case Instruction::Add:
@@ -227,9 +226,9 @@
   Constant *Dummy = Constant::getNullValue(Ty);
 
   switch (I->getOpcode()) {
-  case Instruction::Cast:
+  case Instruction::BitCast:
     assert(VMC.NewCasts.count(ValueHandle(VMC, I)) == 0);
-    Res = new CastInst(I->getOperand(0), Ty, Name);
+    Res = CastInst::createInferredCast(I->getOperand(0), Ty, Name);
     VMC.NewCasts.insert(ValueHandle(VMC, Res));
     break;
 
@@ -307,7 +306,8 @@
       Indices.pop_back();
       if (GetElementPtrInst::getIndexedType(BaseType, Indices, true) == PVTy) {
         if (Indices.size() == 0)
-          Res = new CastInst(GEP->getPointerOperand(), BaseType); // NOOP CAST
+          // We want to no-op cast this so use BitCast
+          Res = new BitCastInst(GEP->getPointerOperand(), BaseType);
         else
           Res = new GetElementPtrInst(GEP->getPointerOperand(), Indices, Name);
         break;
@@ -411,10 +411,6 @@
   return true;
 }
 
-
-
-
-
 // OperandConvertibleToType - Return true if it is possible to convert operand
 // V of User (instruction) U to the specified type.  This is true iff it is
 // possible to change the specified instruction to accept this.  CTMap is a map
@@ -431,29 +427,18 @@
     return false;
 
   Instruction *I = dyn_cast<Instruction>(U);
-  if (I == 0) return false;              // We can't convert!
+  if (I == 0) return false;              // We can't convert non-instructions!
 
   switch (I->getOpcode()) {
-  case Instruction::Cast:
+  case Instruction::BitCast:
     assert(I->getOperand(0) == V);
     // We can convert the expr if the cast destination type is losslessly
-    // convertible to the requested type.
-    // Also, do not change a cast that is a noop cast.  For all intents and
-    // purposes it should be eliminated.
-    if (!Ty->isLosslesslyConvertibleTo(I->getOperand(0)->getType()) ||
+    // convertible to the requested type.  Also, do not change a cast that 
+    // is a noop cast.  For all intents and purposes it should be eliminated.
+    if (!cast<BitCastInst>(I)->isLosslessCast() || 
         I->getType() == I->getOperand(0)->getType())
       return false;
 
-    // Do not allow a 'cast ushort %V to uint' to have it's first operand be
-    // converted to a 'short' type.  Doing so changes the way sign promotion
-    // happens, and breaks things.  Only allow the cast to take place if the
-    // signedness doesn't change... or if the current cast is not a lossy
-    // conversion.
-    //
-    if (!I->getType()->isLosslesslyConvertibleTo(I->getOperand(0)->getType()) &&
-        I->getOperand(0)->getType()->isSigned() != Ty->isSigned())
-      return false;
-
     // We also do not allow conversion of a cast that casts from a ptr to array
     // of X to a *X.  For example: cast [4 x %List *] * %val to %List * *
     //
@@ -642,7 +627,8 @@
       // arguments if possible.
       //
       for (unsigned i = 0, NA = FTy->getNumParams(); i < NA; ++i)
-        if (!FTy->getParamType(i)->isLosslesslyConvertibleTo(I->getOperand(i+1)->getType()))
+        if (!FTy->getParamType(i)->canLosslesslyBitCastTo(
+              I->getOperand(i+1)->getType()))
           return false;   // Operands must have compatible types!
 
       // Okay, at this point, we know that all of the arguments can be
@@ -662,7 +648,7 @@
     // If we get this far, we know the value is in the varargs section of the
     // function!  We can convert if we don't reinterpret the value...
     //
-    return Ty->isLosslesslyConvertibleTo(V->getType());
+    return Ty->canLosslesslyBitCastTo(V->getType());
   }
   }
   return false;
@@ -718,19 +704,8 @@
                   Constant::getNullValue(NewTy) : 0;
 
   switch (I->getOpcode()) {
-  case Instruction::Cast:
-    if (VMC.NewCasts.count(ValueHandle(VMC, I))) {
-      // This cast has already had it's value converted, causing a new cast to
-      // be created.  We don't want to create YET ANOTHER cast instruction
-      // representing the original one, so just modify the operand of this cast
-      // instruction, which we know is newly created.
-      I->setOperand(0, NewVal);
-      I->setName(Name);  // give I its name back
-      return;
-
-    } else {
-      Res = new CastInst(NewVal, I->getType(), Name);
-    }
+  case Instruction::BitCast:
+    Res = CastInst::createInferredCast(NewVal, I->getType(), Name);
     break;
 
   case Instruction::Add:
@@ -895,9 +870,9 @@
       for (unsigned i = 0; i != NewTy->getNumParams(); ++i)
         if (Params[i]->getType() != NewTy->getParamType(i)) {
           // Create a cast to convert it to the right type, we know that this
-          // is a lossless cast...
+          // is a no-op cast...
           //
-          Params[i] = new CastInst(Params[i], NewTy->getParamType(i),
+          Params[i] = new BitCastInst(Params[i], NewTy->getParamType(i),
                                    "callarg.cast." +
                                    Params[i]->getName(), It);
         }


Index: llvm/lib/Transforms/LevelRaise.cpp
diff -u llvm/lib/Transforms/LevelRaise.cpp:1.112 llvm/lib/Transforms/LevelRaise.cpp:1.113
--- llvm/lib/Transforms/LevelRaise.cpp:1.112	Sun Nov 26 03:17:06 2006
+++ llvm/lib/Transforms/LevelRaise.cpp	Sun Nov 26 19:05:10 2006
@@ -87,15 +87,6 @@
   return new RPR();
 }
 
-
-// isReinterpretingCast - Return true if the cast instruction specified will
-// cause the operand to be "reinterpreted".  A value is reinterpreted if the
-// cast instruction would cause the underlying bits to change.
-//
-static inline bool isReinterpretingCast(const CastInst *CI) {
-  return!CI->getOperand(0)->getType()->isLosslesslyConvertibleTo(CI->getType());
-}
-
 bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
   Instruction *I = BI;
   const TargetData &TD = getAnalysis<TargetData>();
@@ -129,7 +120,7 @@
 
     // Check to see if it's a cast of an instruction that does not depend on the
     // specific type of the operands to do it's job.
-    if (!isReinterpretingCast(CI)) {
+    if (CI->isLosslessCast()) {
       ValueTypeCache ConvertedTypes;
 
       // Check to see if we can convert the source of the cast to match the
@@ -238,7 +229,7 @@
             Indices.push_back(Constant::getNullValue(Type::UIntTy));
 
             // Did we find what we're looking for?
-            if (ElTy->isLosslesslyConvertibleTo(DestPointedTy)) break;
+            if (ElTy->canLosslesslyBitCastTo(DestPointedTy)) break;
 
             // Nope, go a level deeper.
             ++Depth;
@@ -257,9 +248,23 @@
                                                            Name, BI);
 
             // Make the old cast instruction reference the new GEP instead of
-            // the old src value.
-            //
-            CI->setOperand(0, GEP);
+            // the old src value. 
+            if (CI->getOperand(0)->getType() == GEP->getType()) {
+              // If the source types are the same we can safely replace the
+              // first operand of the CastInst because the opcode won't 
+              // change as a result.
+              CI->setOperand(0, GEP);
+            } else {
+              // The existing and new operand 0 types are different so we must
+              // replace CI with a new CastInst so that we are assured to 
+              // get the correct cast opcode.
+              CastInst *NewCI = CastInst::createInferredCast(
+                GEP, CI->getType(), CI->getName(), CI);
+              CI->replaceAllUsesWith(NewCI);
+              CI->eraseFromParent();
+              CI = NewCI;
+              BI = NewCI; // Don't let the iterator invalidate
+            }
 
             PRINT_PEEPHOLE2("cast-for-first:out", *GEP, *CI);
             ++NumGEPInstFormed;
@@ -273,7 +278,7 @@
     Value *Pointer = SI->getPointerOperand();
 
     // Peephole optimize the following instructions:
-    // %t = cast <T1>* %P to <T2> * ;; If T1 is losslessly convertible to T2
+    // %t = cast <T1>* %P to <T2> * ;; If T1 is losslessly castable to T2
     // store <T2> %V, <T2>* %t
     //
     // Into:
@@ -289,13 +294,14 @@
       if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType
         if (const PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
           // convertible types?
-          if (Val->getType()->isLosslesslyConvertibleTo(CSPT->getElementType())) {
+          if (Val->getType()->canLosslesslyBitCastTo(CSPT->getElementType()))
+          {
             PRINT_PEEPHOLE3("st-src-cast:in ", *Pointer, *Val, *SI);
 
             // Insert the new T cast instruction... stealing old T's name
             std::string Name(CI->getName()); CI->setName("");
-            CastInst *NCI = new CastInst(Val, CSPT->getElementType(),
-                                         Name, BI);
+            CastInst *NCI = CastInst::create(Instruction::BitCast, Val, 
+                CSPT->getElementType(), Name, BI);
 
             // Replace the old store with a new one!
             ReplaceInstWithInst(BB->getInstList(), BI,
@@ -327,14 +333,16 @@
       if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType
         if (const PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
           // convertible types?
-          if (PtrElType->isLosslesslyConvertibleTo(CSPT->getElementType())) {
+          if (PtrElType->canLosslesslyBitCastTo(CSPT->getElementType())) {
             PRINT_PEEPHOLE2("load-src-cast:in ", *Pointer, *LI);
 
             // Create the new load instruction... loading the pre-casted value
             LoadInst *NewLI = new LoadInst(CastSrc, LI->getName(), BI);
 
             // Insert the new T cast instruction... stealing old T's name
-            CastInst *NCI = new CastInst(NewLI, LI->getType(), CI->getName());
+            CastInst *NCI = 
+              CastInst::create(Instruction::BitCast, NewLI, LI->getType(), 
+                               CI->getName());
 
             // Replace the old store with a new one!
             ReplaceInstWithInst(BB->getInstList(), BI, NCI);
@@ -366,15 +374,12 @@
 
       // Create a new cast, inserting it right before the function call...
       Value *NewCast;
-      Constant *ConstantCallSrc = 0;
       if (Constant *CS = dyn_cast<Constant>(CI->getCalledValue()))
-        ConstantCallSrc = CS;
-
-      if (ConstantCallSrc)
-        NewCast = ConstantExpr::getCast(ConstantCallSrc, NewPFunTy);
+        NewCast = ConstantExpr::getBitCast(CS, NewPFunTy);
       else
-        NewCast = new CastInst(CI->getCalledValue(), NewPFunTy,
-                               CI->getCalledValue()->getName()+"_c",CI);
+        NewCast = CastInst::create(Instruction::BitCast, CI->getCalledValue(), 
+                                   NewPFunTy, 
+                                   CI->getCalledValue()->getName()+"_c", CI);
 
       // Create a new call instruction...
       CallInst *NewCall = new CallInst(NewCast,






More information about the llvm-commits mailing list