rearrange some code, splitting memcpy/memcpy optimization
out of processMemCpy into its own function.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119687 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index f4876ea..39f40a1 100644
--- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -325,6 +325,8 @@
     bool processMemMove(MemMoveInst *M);
     bool performCallSlotOptzn(Instruction *cpy, Value *cpyDst, Value *cpySrc,
                               uint64_t cpyLen, CallInst *C);
+    bool processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep,
+                                       uint64_t MSize);
     bool iterateOnFunction(Function &F);
   };
   
@@ -665,6 +667,84 @@
   return true;
 }
 
+/// processMemCpyMemCpyDependence - We've found that the (upward scanning)
+/// memory dependence of memcpy 'M' is the memcpy 'MDep'.  Try to simplify M to
+/// copy from MDep's input if we can.  MSize is the size of M's copy.
+/// 
+bool MemCpyOpt::processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep,
+                                              uint64_t MSize) {
+  // We can only transforms memcpy's where the dest of one is the source of the
+  // other.
+  if (M->getSource() != MDep->getDest())
+    return false;
+  
+  // Second, the length of the memcpy's must be the same, or the preceeding one
+  // must be larger than the following one.
+  ConstantInt *C1 = dyn_cast<ConstantInt>(MDep->getLength());
+  if (!C1) return false;
+  
+  uint64_t DepSize = C1->getValue().getZExtValue();
+  
+  if (DepSize < MSize)
+    return false;
+  
+  // Finally, we have to make sure that the dest of the second does not
+  // alias the source of the first
+  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+  if (AA.alias(M->getRawDest(), MSize, MDep->getRawSource(), DepSize) !=
+      AliasAnalysis::NoAlias)
+    return false;
+  else if (AA.alias(M->getRawDest(), MSize, M->getRawSource(), MSize) !=
+           AliasAnalysis::NoAlias)
+    return false;
+  else if (AA.alias(MDep->getRawDest(), DepSize, MDep->getRawSource(), DepSize)
+           != AliasAnalysis::NoAlias)
+    return false;
+  
+  // If all checks passed, then we can transform these memcpy's
+  const Type *ArgTys[3] = { M->getRawDest()->getType(),
+    MDep->getRawSource()->getType(),
+    M->getLength()->getType() };
+  Function *MemCpyFun =
+    Intrinsic::getDeclaration(M->getParent()->getParent()->getParent(),
+                              M->getIntrinsicID(), ArgTys, 3);
+  
+  // Make sure to use the lesser of the alignment of the source and the dest
+  // since we're changing where we're reading from, but don't want to increase
+  // the alignment past what can be read from or written to.
+  // TODO: Is this worth it if we're creating a less aligned memcpy? For
+  // example we could be moving from movaps -> movq on x86.
+  unsigned Align = std::min(MDep->getAlignmentCst()->getZExtValue(),
+                            M->getAlignmentCst()->getZExtValue());
+  LLVMContext &Context = M->getContext();
+  ConstantInt *AlignCI = ConstantInt::get(Type::getInt32Ty(Context), Align);
+  Value *Args[5] = {
+    M->getRawDest(), MDep->getRawSource(), M->getLength(),
+    AlignCI, M->getVolatileCst()
+  };
+  CallInst *C = CallInst::Create(MemCpyFun, Args, Args+5, "", M);
+  
+  
+  MemoryDependenceAnalysis &MD = getAnalysis<MemoryDependenceAnalysis>();
+
+  // If C and M don't interfere, then this is a valid transformation.  If they
+  // did, this would mean that the two sources overlap, which would be bad.
+  MemDepResult dep = MD.getDependency(C);
+  if (dep.isClobber() && dep.getInst() == MDep) {
+    MD.removeInstruction(M);
+    M->eraseFromParent();
+    ++NumMemCpyInstr;
+    return true;
+  }
+  
+  // Otherwise, there was no point in doing this, so we remove the call we
+  // inserted and act like nothing happened.
+  MD.removeInstruction(C);
+  C->eraseFromParent();
+  return false;
+}
+
+
 /// processMemCpy - perform simplification of memcpy's.  If we have memcpy A
 /// which copies X to Y, and memcpy B which copies Y to Z, then we can rewrite
 /// B to be a memcpy from X to Z (or potentially a memmove, depending on
@@ -683,85 +763,16 @@
   MemDepResult dep = MD.getDependency(M);
   if (!dep.isClobber())
     return false;
-  if (!isa<MemCpyInst>(dep.getInst())) {
-    if (CallInst *C = dyn_cast<CallInst>(dep.getInst())) {
-      bool changed = performCallSlotOptzn(M, M->getDest(), M->getSource(),
-                                  cpyLen->getZExtValue(), C);
-      if (changed) M->eraseFromParent();
-      return changed;
-    }
-    return false;
-  }
   
-  MemCpyInst *MDep = cast<MemCpyInst>(dep.getInst());
-  
-  // We can only transforms memcpy's where the dest of one is the source of the
-  // other
-  if (M->getSource() != MDep->getDest())
-    return false;
-  
-  // Second, the length of the memcpy's must be the same, or the preceeding one
-  // must be larger than the following one.
-  ConstantInt *C1 = dyn_cast<ConstantInt>(MDep->getLength());
-  ConstantInt *C2 = dyn_cast<ConstantInt>(M->getLength());
-  if (!C1 || !C2)
-    return false;
-  
-  uint64_t DepSize = C1->getValue().getZExtValue();
-  uint64_t CpySize = C2->getValue().getZExtValue();
-  
-  if (DepSize < CpySize)
-    return false;
-  
-  // Finally, we have to make sure that the dest of the second does not
-  // alias the source of the first
-  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
-  if (AA.alias(M->getRawDest(), CpySize, MDep->getRawSource(), DepSize) !=
-      AliasAnalysis::NoAlias)
-    return false;
-  else if (AA.alias(M->getRawDest(), CpySize, M->getRawSource(), CpySize) !=
-           AliasAnalysis::NoAlias)
-    return false;
-  else if (AA.alias(MDep->getRawDest(), DepSize, MDep->getRawSource(), DepSize)
-           != AliasAnalysis::NoAlias)
-    return false;
-  
-  // If all checks passed, then we can transform these memcpy's
-  const Type *ArgTys[3] = { M->getRawDest()->getType(),
-                            MDep->getRawSource()->getType(),
-                            M->getLength()->getType() };
-  Function *MemCpyFun = Intrinsic::getDeclaration(
-                                 M->getParent()->getParent()->getParent(),
-                                 M->getIntrinsicID(), ArgTys, 3);
+  if (MemCpyInst *MDep = dyn_cast<MemCpyInst>(dep.getInst()))
+    return processMemCpyMemCpyDependence(M, MDep, cpyLen->getZExtValue());
     
-  // Make sure to use the lesser of the alignment of the source and the dest
-  // since we're changing where we're reading from, but don't want to increase
-  // the alignment past what can be read from or written to.
-  // TODO: Is this worth it if we're creating a less aligned memcpy? For
-  // example we could be moving from movaps -> movq on x86.
-  unsigned Align = std::min(MDep->getAlignmentCst()->getZExtValue(),
-                            M->getAlignmentCst()->getZExtValue());
-  LLVMContext &Context = M->getContext();
-  ConstantInt *AlignCI = ConstantInt::get(Type::getInt32Ty(Context), Align);
-  Value *Args[5] = {
-    M->getRawDest(), MDep->getRawSource(), M->getLength(),
-    AlignCI, M->getVolatileCst()
-  };
-  CallInst *C = CallInst::Create(MemCpyFun, Args, Args+5, "", M);
-  
-  // If C and M don't interfere, then this is a valid transformation.  If they
-  // did, this would mean that the two sources overlap, which would be bad.
-  if (MD.getDependency(C) == dep) {
-    MD.removeInstruction(M);
-    M->eraseFromParent();
-    ++NumMemCpyInstr;
-    return true;
+  if (CallInst *C = dyn_cast<CallInst>(dep.getInst())) {
+    bool changed = performCallSlotOptzn(M, M->getDest(), M->getSource(),
+                                        cpyLen->getZExtValue(), C);
+    if (changed) M->eraseFromParent();
+    return changed;
   }
-  
-  // Otherwise, there was no point in doing this, so we remove the call we
-  // inserted and act like nothing happened.
-  MD.removeInstruction(C);
-  C->eraseFromParent();
   return false;
 }