[llvm-commits] [llvm] r61852 - /llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp

Chris Lattner sabre at nondot.org
Tue Jan 6 23:18:45 PST 2009


Author: lattner
Date: Wed Jan  7 01:18:45 2009
New Revision: 61852

URL: http://llvm.org/viewvc/llvm-project?rev=61852&view=rev
Log:
Factor a bunch of code out into a helper method.

Modified:
    llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=61852&r1=61851&r2=61852&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Wed Jan  7 01:18:45 2009
@@ -117,6 +117,11 @@
     void RewriteBitCastUserOfAlloca(Instruction *BCInst, AllocationInst *AI,
                                     SmallVector<AllocaInst*, 32> &NewElts);
     
+    void RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *BCInst,
+                                      AllocationInst *AI,
+                                      SmallVector<AllocaInst*, 32> &NewElts);
+
+    
     const Type *CanConvertToScalar(Value *V, bool &IsNotTrivial);
     void ConvertToScalar(AllocationInst *AI, const Type *Ty);
     void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset);
@@ -593,179 +598,182 @@
 /// instead.
 void SROA::RewriteBitCastUserOfAlloca(Instruction *BCInst, AllocationInst *AI,
                                       SmallVector<AllocaInst*, 32> &NewElts) {
-  Constant *Zero = Constant::getNullValue(Type::Int32Ty);
-  
   Value::use_iterator UI = BCInst->use_begin(), UE = BCInst->use_end();
   while (UI != UE) {
-    if (BitCastInst *BCU = dyn_cast<BitCastInst>(*UI)) {
+    Instruction *User = cast<Instruction>(*UI++);
+    if (BitCastInst *BCU = dyn_cast<BitCastInst>(User)) {
       RewriteBitCastUserOfAlloca(BCU, AI, NewElts);
-      ++UI;
       BCU->eraseFromParent();
       continue;
     }
 
-    // Otherwise, must be memcpy/memmove/memset of the entire aggregate.  Split
-    // into one per element.
-    MemIntrinsic *MI = dyn_cast<MemIntrinsic>(*UI);
-    
-    // If it's not a mem intrinsic, it must be some other user of a gep of the
-    // first pointer.  Just leave these alone.
-    if (!MI) {
-      ++UI;
+    if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(User)) {
+      // This must be memcpy/memmove/memset of the entire aggregate.
+      // Split into one per element.
+      RewriteMemIntrinUserOfAlloca(MI, BCInst, AI, NewElts);
+      MI->eraseFromParent();
       continue;
     }
-    
-    // If this is a memcpy/memmove, construct the other pointer as the
-    // appropriate type.
-    Value *OtherPtr = 0;
-    if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(MI)) {
-      if (BCInst == MCI->getRawDest())
-        OtherPtr = MCI->getRawSource();
-      else {
-        assert(BCInst == MCI->getRawSource());
-        OtherPtr = MCI->getRawDest();
-      }
-    } else if (MemMoveInst *MMI = dyn_cast<MemMoveInst>(MI)) {
-      if (BCInst == MMI->getRawDest())
-        OtherPtr = MMI->getRawSource();
-      else {
-        assert(BCInst == MMI->getRawSource());
-        OtherPtr = MMI->getRawDest();
-      }
+      
+    // If it's not a mem intrinsic, it must be some other user of a gep of the
+    // first pointer.  Just leave these alone.
+    continue;
+  }      
+}
+
+/// RewriteMemIntrinUserOfAlloca - MI is a memcpy/memset/memmove from or to AI.
+/// Rewrite it to copy or set the elements of the scalarized memory.
+void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *BCInst,
+                                        AllocationInst *AI,
+                                        SmallVector<AllocaInst*, 32> &NewElts) {
+  
+  // If this is a memcpy/memmove, construct the other pointer as the
+  // appropriate type.
+  Value *OtherPtr = 0;
+  if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(MI)) {
+    if (BCInst == MCI->getRawDest())
+      OtherPtr = MCI->getRawSource();
+    else {
+      assert(BCInst == MCI->getRawSource());
+      OtherPtr = MCI->getRawDest();
+    }
+  } else if (MemMoveInst *MMI = dyn_cast<MemMoveInst>(MI)) {
+    if (BCInst == MMI->getRawDest())
+      OtherPtr = MMI->getRawSource();
+    else {
+      assert(BCInst == MMI->getRawSource());
+      OtherPtr = MMI->getRawDest();
     }
-    
-    // If there is an other pointer, we want to convert it to the same pointer
-    // type as AI has, so we can GEP through it.
+  }
+  
+  // If there is an other pointer, we want to convert it to the same pointer
+  // type as AI has, so we can GEP through it safely.
+  if (OtherPtr) {
+    // It is likely that OtherPtr is a bitcast, if so, remove it.
+    if (BitCastInst *BC = dyn_cast<BitCastInst>(OtherPtr))
+      OtherPtr = BC->getOperand(0);
+    // All zero GEPs are effectively bitcasts.
+    if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(OtherPtr))
+      if (GEP->hasAllZeroIndices())
+        OtherPtr = GEP->getOperand(0);
+    
+    if (ConstantExpr *BCE = dyn_cast<ConstantExpr>(OtherPtr))
+      if (BCE->getOpcode() == Instruction::BitCast)
+        OtherPtr = BCE->getOperand(0);
+    
+    // If the pointer is not the right type, insert a bitcast to the right
+    // type.
+    if (OtherPtr->getType() != AI->getType())
+      OtherPtr = new BitCastInst(OtherPtr, AI->getType(), OtherPtr->getName(),
+                                 MI);
+  }
+  
+  // Process each element of the aggregate.
+  Value *TheFn = MI->getOperand(0);
+  const Type *BytePtrTy = MI->getRawDest()->getType();
+  bool SROADest = MI->getRawDest() == BCInst;
+  
+  Constant *Zero = Constant::getNullValue(Type::Int32Ty);
+
+  for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
+    // If this is a memcpy/memmove, emit a GEP of the other element address.
+    Value *OtherElt = 0;
     if (OtherPtr) {
-      // It is likely that OtherPtr is a bitcast, if so, remove it.
-      if (BitCastInst *BC = dyn_cast<BitCastInst>(OtherPtr))
-        OtherPtr = BC->getOperand(0);
-      // All zero GEPs are effectively bitcasts.
-      if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(OtherPtr))
-        if (GEP->hasAllZeroIndices())
-          OtherPtr = GEP->getOperand(0);
-        
-      if (ConstantExpr *BCE = dyn_cast<ConstantExpr>(OtherPtr))
-        if (BCE->getOpcode() == Instruction::BitCast)
-          OtherPtr = BCE->getOperand(0);
-      
-      // If the pointer is not the right type, insert a bitcast to the right
-      // type.
-      if (OtherPtr->getType() != AI->getType())
-        OtherPtr = new BitCastInst(OtherPtr, AI->getType(), OtherPtr->getName(),
-                                   MI);
-    }
-
-    // Process each element of the aggregate.
-    Value *TheFn = MI->getOperand(0);
-    const Type *BytePtrTy = MI->getRawDest()->getType();
-    bool SROADest = MI->getRawDest() == BCInst;
-
-    for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
-      // If this is a memcpy/memmove, emit a GEP of the other element address.
-      Value *OtherElt = 0;
-      if (OtherPtr) {
-        Value *Idx[2] = { Zero, ConstantInt::get(Type::Int32Ty, i) };
-        OtherElt = GetElementPtrInst::Create(OtherPtr, Idx, Idx + 2,
+      Value *Idx[2] = { Zero, ConstantInt::get(Type::Int32Ty, i) };
+      OtherElt = GetElementPtrInst::Create(OtherPtr, Idx, Idx + 2,
                                            OtherPtr->getNameStr()+"."+utostr(i),
-                                             MI);
+                                           MI);
+    }
+    
+    Value *EltPtr = NewElts[i];
+    const Type *EltTy =cast<PointerType>(EltPtr->getType())->getElementType();
+    
+    // If we got down to a scalar, insert a load or store as appropriate.
+    if (EltTy->isSingleValueType()) {
+      if (isa<MemCpyInst>(MI) || isa<MemMoveInst>(MI)) {
+        Value *Elt = new LoadInst(SROADest ? OtherElt : EltPtr, "tmp",
+                                  MI);
+        new StoreInst(Elt, SROADest ? EltPtr : OtherElt, MI);
+        continue;
       }
-
-      Value *EltPtr = NewElts[i];
-      const Type *EltTy =cast<PointerType>(EltPtr->getType())->getElementType();
+      assert(isa<MemSetInst>(MI));
       
-      // If we got down to a scalar, insert a load or store as appropriate.
-      if (EltTy->isSingleValueType()) {
-        if (isa<MemCpyInst>(MI) || isa<MemMoveInst>(MI)) {
-          Value *Elt = new LoadInst(SROADest ? OtherElt : EltPtr, "tmp",
-                                    MI);
-          new StoreInst(Elt, SROADest ? EltPtr : OtherElt, MI);
-          continue;
+      // If the stored element is zero (common case), just store a null
+      // constant.
+      Constant *StoreVal;
+      if (ConstantInt *CI = dyn_cast<ConstantInt>(MI->getOperand(2))) {
+        if (CI->isZero()) {
+          StoreVal = Constant::getNullValue(EltTy);  // 0.0, null, 0, <0,0>
         } else {
-          assert(isa<MemSetInst>(MI));
-
-          // If the stored element is zero (common case), just store a null
-          // constant.
-          Constant *StoreVal;
-          if (ConstantInt *CI = dyn_cast<ConstantInt>(MI->getOperand(2))) {
-            if (CI->isZero()) {
-              StoreVal = Constant::getNullValue(EltTy);  // 0.0, null, 0, <0,0>
-            } else {
-              // If EltTy is a vector type, get the element type.
-              const Type *ValTy = EltTy;
-              if (const VectorType *VTy = dyn_cast<VectorType>(ValTy))
-                ValTy = VTy->getElementType();
-
-              // Construct an integer with the right value.
-              unsigned EltSize = TD->getTypeSizeInBits(ValTy);
-              APInt OneVal(EltSize, CI->getZExtValue());
-              APInt TotalVal(OneVal);
-              // Set each byte.
-              for (unsigned i = 0; 8*i < EltSize; ++i) {
-                TotalVal = TotalVal.shl(8);
-                TotalVal |= OneVal;
-              }
-
-              // Convert the integer value to the appropriate type.
-              StoreVal = ConstantInt::get(TotalVal);
-              if (isa<PointerType>(ValTy))
-                StoreVal = ConstantExpr::getIntToPtr(StoreVal, ValTy);
-              else if (ValTy->isFloatingPoint())
-                StoreVal = ConstantExpr::getBitCast(StoreVal, ValTy);
-              assert(StoreVal->getType() == ValTy && "Type mismatch!");
-              
-              // If the requested value was a vector constant, create it.
-              if (EltTy != ValTy) {
-                unsigned NumElts = cast<VectorType>(ValTy)->getNumElements();
-                SmallVector<Constant*, 16> Elts(NumElts, StoreVal);
-                StoreVal = ConstantVector::get(&Elts[0], NumElts);
-              }
-            }
-            new StoreInst(StoreVal, EltPtr, MI);
-            continue;
+          // If EltTy is a vector type, get the element type.
+          const Type *ValTy = EltTy;
+          if (const VectorType *VTy = dyn_cast<VectorType>(ValTy))
+            ValTy = VTy->getElementType();
+          
+          // Construct an integer with the right value.
+          unsigned EltSize = TD->getTypeSizeInBits(ValTy);
+          APInt OneVal(EltSize, CI->getZExtValue());
+          APInt TotalVal(OneVal);
+          // Set each byte.
+          for (unsigned i = 0; 8*i < EltSize; ++i) {
+            TotalVal = TotalVal.shl(8);
+            TotalVal |= OneVal;
+          }
+          
+          // Convert the integer value to the appropriate type.
+          StoreVal = ConstantInt::get(TotalVal);
+          if (isa<PointerType>(ValTy))
+            StoreVal = ConstantExpr::getIntToPtr(StoreVal, ValTy);
+          else if (ValTy->isFloatingPoint())
+            StoreVal = ConstantExpr::getBitCast(StoreVal, ValTy);
+          assert(StoreVal->getType() == ValTy && "Type mismatch!");
+          
+          // If the requested value was a vector constant, create it.
+          if (EltTy != ValTy) {
+            unsigned NumElts = cast<VectorType>(ValTy)->getNumElements();
+            SmallVector<Constant*, 16> Elts(NumElts, StoreVal);
+            StoreVal = ConstantVector::get(&Elts[0], NumElts);
           }
-          // Otherwise, if we're storing a byte variable, use a memset call for
-          // this element.
         }
+        new StoreInst(StoreVal, EltPtr, MI);
+        continue;
       }
-      
-      // Cast the element pointer to BytePtrTy.
-      if (EltPtr->getType() != BytePtrTy)
-        EltPtr = new BitCastInst(EltPtr, BytePtrTy, EltPtr->getNameStr(), MI);
-    
-      // Cast the other pointer (if we have one) to BytePtrTy. 
-      if (OtherElt && OtherElt->getType() != BytePtrTy)
-        OtherElt = new BitCastInst(OtherElt, BytePtrTy,OtherElt->getNameStr(),
-                                   MI);
+      // Otherwise, if we're storing a byte variable, use a memset call for
+      // this element.
+    }
     
-      unsigned EltSize = TD->getABITypeSize(EltTy);
-
-      // Finally, insert the meminst for this element.
-      if (isa<MemCpyInst>(MI) || isa<MemMoveInst>(MI)) {
-        Value *Ops[] = {
-          SROADest ? EltPtr : OtherElt,  // Dest ptr
-          SROADest ? OtherElt : EltPtr,  // Src ptr
-          ConstantInt::get(MI->getOperand(3)->getType(), EltSize), // Size
-          Zero  // Align
-        };
-        CallInst::Create(TheFn, Ops, Ops + 4, "", MI);
-      } else {
-        assert(isa<MemSetInst>(MI));
-        Value *Ops[] = {
-          EltPtr, MI->getOperand(2),  // Dest, Value,
-          ConstantInt::get(MI->getOperand(3)->getType(), EltSize), // Size
-          Zero  // Align
-        };
-        CallInst::Create(TheFn, Ops, Ops + 4, "", MI);
-      }
+    // Cast the element pointer to BytePtrTy.
+    if (EltPtr->getType() != BytePtrTy)
+      EltPtr = new BitCastInst(EltPtr, BytePtrTy, EltPtr->getNameStr(), MI);
+    
+    // Cast the other pointer (if we have one) to BytePtrTy. 
+    if (OtherElt && OtherElt->getType() != BytePtrTy)
+      OtherElt = new BitCastInst(OtherElt, BytePtrTy,OtherElt->getNameStr(),
+                                 MI);
+    
+    unsigned EltSize = TD->getABITypeSize(EltTy);
+    
+    // Finally, insert the meminst for this element.
+    if (isa<MemCpyInst>(MI) || isa<MemMoveInst>(MI)) {
+      Value *Ops[] = {
+        SROADest ? EltPtr : OtherElt,  // Dest ptr
+        SROADest ? OtherElt : EltPtr,  // Src ptr
+        ConstantInt::get(MI->getOperand(3)->getType(), EltSize), // Size
+        Zero  // Align
+      };
+      CallInst::Create(TheFn, Ops, Ops + 4, "", MI);
+    } else {
+      assert(isa<MemSetInst>(MI));
+      Value *Ops[] = {
+        EltPtr, MI->getOperand(2),  // Dest, Value,
+        ConstantInt::get(MI->getOperand(3)->getType(), EltSize), // Size
+        Zero  // Align
+      };
+      CallInst::Create(TheFn, Ops, Ops + 4, "", MI);
     }
-
-    // Finally, MI is now dead, as we've modified its actions to occur on all of
-    // the elements of the aggregate.
-    ++UI;
-    MI->eraseFromParent();
   }
 }
+  
 
 /// HasPadding - Return true if the specified type has any structure or
 /// alignment padding, false otherwise.





More information about the llvm-commits mailing list