[llvm-commits] [llvm] r45944 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner sabre at nondot.org
Sun Jan 13 15:50:24 PST 2008


Author: lattner
Date: Sun Jan 13 17:50:23 2008
New Revision: 45944

URL: http://llvm.org/viewvc/llvm-project?rev=45944&view=rev
Log:
factor memcpy/memmove simplification out to its own SimplifyMemTransfer 
method, no functionality change.

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

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

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Jan 13 17:50:23 2008
@@ -366,6 +366,8 @@
     Instruction *PromoteCastOfAllocation(BitCastInst &CI, AllocationInst &AI);
     Instruction *MatchBSwap(BinaryOperator &I);
     bool SimplifyStoreAtEndOfBlock(StoreInst &SI);
+    Instruction *SimplifyMemTransfer(MemIntrinsic *MI);
+
 
     Value *EvaluateInDifferentType(Value *V, const Type *Ty, bool isSigned);
   };
@@ -7808,6 +7810,43 @@
   return 0;
 }
 
+Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) {
+  unsigned DstAlign = GetOrEnforceKnownAlignment(MI->getOperand(1), TD);
+  unsigned SrcAlign = GetOrEnforceKnownAlignment(MI->getOperand(2), TD);
+  unsigned MinAlign = std::min(DstAlign, SrcAlign);
+  unsigned CopyAlign = MI->getAlignment()->getZExtValue();
+
+  if (CopyAlign < MinAlign) {
+    MI->setAlignment(ConstantInt::get(Type::Int32Ty, MinAlign));
+    return MI;
+  }
+  
+  // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with
+  // load/store.
+  ConstantInt *MemOpLength = dyn_cast<ConstantInt>(MI->getOperand(3));
+  if (MemOpLength == 0) return 0;
+  
+  // Source and destination pointer types are always "i8*" for intrinsic.
+  //   If Size is 8 then use Int64Ty
+  //   If Size is 4 then use Int32Ty
+  //   If Size is 2 then use Int16Ty
+  //   If Size is 1 then use Int8Ty
+  unsigned Size = MemOpLength->getZExtValue();
+  if (Size == 0 || Size > 8 || (Size&(Size-1)))
+    return 0;  // If not 1/2/4/8, exit.
+  
+  Type *NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3));
+  // If the memcpy/memmove provides better alignment info than we can
+  // infer, use it.
+  SrcAlign = std::max(SrcAlign, CopyAlign);
+  DstAlign = std::max(DstAlign, CopyAlign);
+  
+  Value *Src = InsertBitCastBefore(MI->getOperand(2), NewPtrTy, *MI);
+  Value *Dest = InsertBitCastBefore(MI->getOperand(1), NewPtrTy, *MI);
+  Value *L = new LoadInst(Src, "tmp", false, SrcAlign, MI);
+  new StoreInst(L, Dest, false, DstAlign, MI);
+  return EraseInstFromFunction(*MI);
+}
 
 /// visitCallInst - CallInst simplification.  This mostly only handles folding 
 /// of intrinsic instructions.  For normal calls, it allows visitCallSite to do
@@ -7837,7 +7876,7 @@
     // If we have a memmove and the source operation is a constant global,
     // then the source and dest pointers can't alias, so we can change this
     // into a call to memcpy.
-    if (MemMoveInst *MMI = dyn_cast<MemMoveInst>(II)) {
+    if (MemMoveInst *MMI = dyn_cast<MemMoveInst>(MI)) {
       if (GlobalVariable *GVSrc = dyn_cast<GlobalVariable>(MMI->getSource()))
         if (GVSrc->isConstant()) {
           Module *M = CI.getParent()->getParent()->getParent();
@@ -7854,40 +7893,8 @@
     // If we can determine a pointer alignment that is bigger than currently
     // set, update the alignment.
     if (isa<MemCpyInst>(MI) || isa<MemMoveInst>(MI)) {
-      unsigned DstAlign = GetOrEnforceKnownAlignment(MI->getOperand(1), TD);
-      unsigned SrcAlign = GetOrEnforceKnownAlignment(MI->getOperand(2), TD);
-      unsigned MinAlign = std::min(DstAlign, SrcAlign);
-      unsigned CopyAlign = MI->getAlignment()->getZExtValue();
-      if (CopyAlign < MinAlign) {
-        MI->setAlignment(ConstantInt::get(Type::Int32Ty, MinAlign));
-        Changed = true;
-      }
-      
-      // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with
-      // load/store.
-      if (ConstantInt *MemOpLength = dyn_cast<ConstantInt>(CI.getOperand(3))) {
-        // Source and destination pointer types are always "i8*" for intrinsic.
-        //   If Size is 8 then use Int64Ty
-        //   If Size is 4 then use Int32Ty
-        //   If Size is 2 then use Int16Ty
-        //   If Size is 1 then use Int8Ty
-        unsigned Size = MemOpLength->getZExtValue();
-        if (Size && Size <= 8 && !(Size&(Size-1))) {
-          Type *NewPtrTy = PointerType::getUnqual(IntegerType::get(Size<<3));
-          // If the memcpy/memmove provides better alignment info than we can
-          // infer, use it.
-          SrcAlign = std::max(SrcAlign, CopyAlign);
-          DstAlign = std::max(DstAlign, CopyAlign);
-          
-          Value *Src = InsertBitCastBefore(CI.getOperand(2), NewPtrTy, CI);
-          Value *Dest = InsertBitCastBefore(CI.getOperand(1), NewPtrTy, CI);
-          Value *L = new LoadInst(Src, "tmp", false, SrcAlign, &CI);
-          Value *NS = new StoreInst(L, Dest, false, DstAlign, &CI);
-          CI.replaceAllUsesWith(NS);
-          Changed = true;
-          return EraseInstFromFunction(CI);
-        }
-      }
+      if (Instruction *I = SimplifyMemTransfer(MI))
+        return I;
     } else if (isa<MemSetInst>(MI)) {
       unsigned Alignment = GetOrEnforceKnownAlignment(MI->getDest(), TD);
       if (MI->getAlignment()->getZExtValue() < Alignment) {





More information about the llvm-commits mailing list