[llvm-commits] CVS: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp

Chris Lattner sabre at nondot.org
Thu Dec 14 23:32:54 PST 2006



Changes in directory llvm/lib/Transforms/Scalar:

ScalarReplAggregates.cpp updated: 1.57 -> 1.58
---
Log message:

re-enable a temporarily-reverted patch


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

 ScalarReplAggregates.cpp |  185 +++++++++++++++++++++++++++++++++--------------
 1 files changed, 132 insertions(+), 53 deletions(-)


Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.57 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.58
--- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.57	Tue Dec 12 20:26:45 2006
+++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp	Fri Dec 15 01:32:38 2006
@@ -419,39 +419,64 @@
 /// types are incompatible, return true, otherwise update Accum and return
 /// false.
 ///
-/// There are two cases we handle here:
-///   1) An effectively integer union, where the pieces are stored into as
+/// There are three cases we handle here:
+///   1) An effectively-integer union, where the pieces are stored into as
 ///      smaller integers (common with byte swap and other idioms).
-///   2) A union of a vector and its elements.  Here we turn element accesses
-///      into insert/extract element operations.
+///   2) A union of vector types of the same size and potentially its elements.
+///      Here we turn element accesses into insert/extract element operations.
+///   3) A union of scalar types, such as int/float or int/pointer.  Here we
+///      merge together into integers, allowing the xform to work with #1 as
+///      well.
 static bool MergeInType(const Type *In, const Type *&Accum,
                         const TargetData &TD) {
   // If this is our first type, just use it.
   const PackedType *PTy;
   if (Accum == Type::VoidTy || In == Accum) {
     Accum = In;
+  } else if (In == Type::VoidTy) {
+    // Noop.
   } else if (In->isIntegral() && Accum->isIntegral()) {   // integer union.
     // Otherwise pick whichever type is larger.
     if (In->getTypeID() > Accum->getTypeID())
       Accum = In;
   } else if (isa<PointerType>(In) && isa<PointerType>(Accum)) {
     // Pointer unions just stay as one of the pointers.
-  } else if ((PTy = dyn_cast<PackedType>(Accum)) && 
-             PTy->getElementType() == In) {
-    // Accum is a vector, and we are accessing an element: ok.
-  } else if ((PTy = dyn_cast<PackedType>(In)) && 
-             PTy->getElementType() == Accum) {
-    // In is a vector, and accum is an element: ok, remember In.
-    Accum = In;
-  } else if (isa<PointerType>(In) && Accum->isIntegral()) {
-    // Pointer/Integer unions merge together as integers.
-    return MergeInType(TD.getIntPtrType(), Accum, TD);
-  } else if (isa<PointerType>(Accum) && In->isIntegral()) {
-    // Pointer/Integer unions merge together as integers.
-    Accum = TD.getIntPtrType();
-    return MergeInType(In, Accum, TD);
+  } else if (isa<PackedType>(In) || isa<PackedType>(Accum)) {
+    if ((PTy = dyn_cast<PackedType>(Accum)) && 
+        PTy->getElementType() == In) {
+      // Accum is a vector, and we are accessing an element: ok.
+    } else if ((PTy = dyn_cast<PackedType>(In)) && 
+               PTy->getElementType() == Accum) {
+      // In is a vector, and accum is an element: ok, remember In.
+      Accum = In;
+    } else if ((PTy = dyn_cast<PackedType>(In)) && isa<PackedType>(Accum) &&
+               PTy->getBitWidth() == cast<PackedType>(Accum)->getBitWidth()) {
+      // Two vectors of the same size: keep Accum.
+    } else {
+      // Cannot insert an short into a <4 x int> or handle
+      // <2 x int> -> <4 x int>
+      return true;
+    }
   } else {
-    return true;
+    // Pointer/FP/Integer unions merge together as integers.
+    switch (Accum->getTypeID()) {
+    case Type::PointerTyID: Accum = TD.getIntPtrType(); break;
+    case Type::FloatTyID:   Accum = Type::UIntTy; break;
+    case Type::DoubleTyID:  Accum = Type::ULongTy; break;
+    default:
+      assert(Accum->isIntegral() && "Unknown FP type!");
+      break;
+    }
+    
+    switch (In->getTypeID()) {
+    case Type::PointerTyID: In = TD.getIntPtrType(); break;
+    case Type::FloatTyID:   In = Type::UIntTy; break;
+    case Type::DoubleTyID:  In = Type::ULongTy; break;
+    default:
+      assert(In->isIntegral() && "Unknown FP type!");
+      break;
+    }
+    return MergeInType(In, Accum, TD);
   }
   return false;
 }
@@ -493,8 +518,7 @@
       
       if (MergeInType(SI->getOperand(0)->getType(), UsedType, TD))
         return 0;
-    } else if (CastInst *CI = dyn_cast<CastInst>(User)) {
-      if (!isa<PointerType>(CI->getType())) return 0;
+    } else if (BitCastInst *CI = dyn_cast<BitCastInst>(User)) {
       IsNotTrivial = true;
       const Type *SubTy = CanConvertToScalar(CI, IsNotTrivial);
       if (!SubTy || MergeInType(SubTy, UsedType, TD)) return 0;
@@ -608,24 +632,54 @@
       Value *NV = new LoadInst(NewAI, LI->getName(), LI);
       if (NV->getType() != LI->getType()) {
         if (const PackedType *PTy = dyn_cast<PackedType>(NV->getType())) {
-          // Must be an element access.
-          unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8);
-          NV = new ExtractElementInst(NV, ConstantInt::get(Type::UIntTy, Elt),
-                                      "tmp", LI);
+          // If the result alloca is a packed type, this is either an element
+          // access or a bitcast to another packed type.
+          if (isa<PackedType>(LI->getType())) {
+            NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
+          } else {
+            // Must be an element access.
+            unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8);
+            NV = new ExtractElementInst(NV, ConstantInt::get(Type::UIntTy, Elt),
+                                        "tmp", LI);
+          }
+        } else if (isa<PointerType>(NV->getType())) {
+          assert(isa<PointerType>(LI->getType()));
+          // Must be ptr->ptr cast.  Anything else would result in NV being
+          // an integer.
+          NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
         } else {
-          if (Offset) {
-            assert(NV->getType()->isInteger() && "Unknown promotion!");
-            if (Offset < TD.getTypeSize(NV->getType())*8) {
-              NV = new ShiftInst(Instruction::LShr, NV, 
-                                 ConstantInt::get(Type::UByteTy, Offset), 
-                                 LI->getName(), LI);
+          assert(NV->getType()->isInteger() && "Unknown promotion!");
+          if (Offset && Offset < TD.getTypeSize(NV->getType())*8) {
+            NV = new ShiftInst(Instruction::LShr, NV, 
+                               ConstantInt::get(Type::UByteTy, Offset), 
+                               LI->getName(), LI);
+          }
+          
+          // If the result is an integer, this is a trunc or bitcast.
+          if (LI->getType()->isIntegral()) {
+            NV = CastInst::createTruncOrBitCast(NV, LI->getType(),
+                                                LI->getName(), LI);
+          } else if (LI->getType()->isFloatingPoint()) {
+            // If needed, truncate the integer to the appropriate size.
+            if (NV->getType()->getPrimitiveSize() > 
+                LI->getType()->getPrimitiveSize()) {
+              switch (LI->getType()->getTypeID()) {
+              default: assert(0 && "Unknown FP type!");
+              case Type::FloatTyID:
+                NV = new TruncInst(NV, Type::UIntTy, LI->getName(), LI);
+                break;
+              case Type::DoubleTyID:
+                NV = new TruncInst(NV, Type::ULongTy, LI->getName(), LI);
+                break;
+              }
             }
+            
+            // Then do a bitcast.
+            NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
           } else {
-            assert((NV->getType()->isInteger() ||
-                    isa<PointerType>(NV->getType())) && "Unknown promotion!");
+            // Otherwise must be a pointer.
+            NV = new IntToPtrInst(NV, LI->getType(), LI->getName(), LI);
           }
-          NV = CastInst::createInferredCast(NV, LI->getType(), LI->getName(), 
-                                            LI);
         }
       }
       LI->replaceAllUsesWith(NV);
@@ -641,30 +695,55 @@
         Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI);
         
         if (const PackedType *PTy = dyn_cast<PackedType>(AllocaType)) {
-          // Must be an element insertion.
-          unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8);
-          SV = new InsertElementInst(Old, SV,
-                                     ConstantInt::get(Type::UIntTy, Elt),
-                                     "tmp", SI);
+          // If the result alloca is a packed type, this is either an element
+          // access or a bitcast to another packed type.
+          if (isa<PackedType>(SV->getType())) {
+            SV = new BitCastInst(SV, AllocaType, SV->getName(), SI);
+          } else {            
+            // Must be an element insertion.
+            unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8);
+            SV = new InsertElementInst(Old, SV,
+                                       ConstantInt::get(Type::UIntTy, Elt),
+                                       "tmp", SI);
+          }
         } else {
-          // Always zero extend the value.
-          if (SV->getType()->isSigned())
-            SV = CastInst::createInferredCast(SV, 
-                SV->getType()->getUnsignedVersion(), SV->getName(), SI);
-          SV = CastInst::createInferredCast(SV, Old->getType(), SV->getName(), 
-                                            SI);
-          if (Offset && Offset < TD.getTypeSize(SV->getType())*8)
+          // If SV is a float, convert it to the appropriate integer type.
+          // If it is a pointer, do the same, and also handle ptr->ptr casts
+          // here.
+          switch (SV->getType()->getTypeID()) {
+          default:
+            assert(!SV->getType()->isFloatingPoint() && "Unknown FP type!");
+            break;
+          case Type::FloatTyID:
+            SV = new BitCastInst(SV, Type::UIntTy, SV->getName(), SI);
+            break;
+          case Type::DoubleTyID:
+            SV = new BitCastInst(SV, Type::ULongTy, SV->getName(), SI);
+            break;
+          case Type::PointerTyID:
+            if (isa<PointerType>(AllocaType))
+              SV = new BitCastInst(SV, AllocaType, SV->getName(), SI);
+            else
+              SV = new PtrToIntInst(SV, TD.getIntPtrType(), SV->getName(), SI);
+            break;
+          }
+
+          unsigned SrcSize = TD.getTypeSize(SV->getType())*8;
+
+          // Always zero extend the value if needed.
+          if (SV->getType() != AllocaType)
+            SV = CastInst::createZExtOrBitCast(SV, AllocaType,
+                                               SV->getName(), SI);
+          if (Offset && Offset < AllocaType->getPrimitiveSizeInBits())
             SV = new ShiftInst(Instruction::Shl, SV,
                                ConstantInt::get(Type::UByteTy, Offset),
                                SV->getName()+".adj", SI);
           // Mask out the bits we are about to insert from the old value.
           unsigned TotalBits = TD.getTypeSize(SV->getType())*8;
-          unsigned InsertBits = TD.getTypeSize(SI->getOperand(0)->getType())*8;
-          if (TotalBits != InsertBits) {
-            assert(TotalBits > InsertBits);
-            uint64_t Mask = ~(((1ULL << InsertBits)-1) << Offset);
-            if (TotalBits != 64)
-              Mask = Mask & ((1ULL << TotalBits)-1);
+          if (TotalBits != SrcSize) {
+            assert(TotalBits > SrcSize);
+            uint64_t Mask = ~(((1ULL << SrcSize)-1) << Offset);
+            Mask = Mask & SV->getType()->getIntegralTypeMask();
             Old = BinaryOperator::createAnd(Old,
                                         ConstantInt::get(Old->getType(), Mask),
                                             Old->getName()+".mask", SI);






More information about the llvm-commits mailing list