Lower memcpy with small constant size operand into a series of load / store
authorEvan Cheng <evan.cheng@apple.com>
Wed, 15 Feb 2006 01:54:51 +0000 (01:54 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 15 Feb 2006 01:54:51 +0000 (01:54 +0000)
ops.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26195 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 8caa5c32bcd70f1e6819bb363709faaad51c113f..0c52edaf88f86dc7c44870458e37c9b0814f7bae 100644 (file)
@@ -1641,19 +1641,45 @@ void SelectionDAGLowering::visitMemIntrinsic(CallInst &I, unsigned Op) {
           MVT::ValueType VT = MemOps[i];
           unsigned VTSize = getSizeInBits(VT) / 8;
           SDOperand Value = getMemsetValue(Op2, VT, DAG);
-          OutChains.
-            push_back(DAG.getNode(ISD::STORE, MVT::Other, getRoot(),
-                                  Value,
-                                  getMemBasePlusOffset(Op1, Offset, DAG, TLI),
-                                  DAG.getSrcValue(NULL)));
+          SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, getRoot(),
+                                        Value,
+                                        getMemBasePlusOffset(Op1, Offset, DAG, TLI),
+                                        DAG.getSrcValue(I.getOperand(1), Offset));
+          OutChains.push_back(Store);
+          Offset += VTSize;
+        }
+      }
+      break;
+    }
+    case ISD::MEMCPY: {
+      if (MeetsMaxMemopRequirement(MemOps, TLI.getMaxStoresPerMemcpy(),
+                                   Size->getValue(), Align, TLI)) {
+        unsigned NumMemOps = MemOps.size();
+        unsigned Offset = 0;
+        for (unsigned i = 0; i < NumMemOps; i++) {
+          MVT::ValueType VT = MemOps[i];
+          unsigned VTSize = getSizeInBits(VT) / 8;
+          SDOperand Value =
+            DAG.getLoad(VT, getRoot(),
+                        getMemBasePlusOffset(Op2, Offset, DAG, TLI),
+                        DAG.getSrcValue(I.getOperand(2), Offset));
+          SDOperand Store =
+            DAG.getNode(ISD::STORE, MVT::Other, Value.getValue(1),
+                        Value,
+                        getMemBasePlusOffset(Op1, Offset, DAG, TLI),
+                        DAG.getSrcValue(I.getOperand(1), Offset));
+          OutChains.push_back(Store);
           Offset += VTSize;
         }
-
-        DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains));
-        return;
       }
+      break;
     }
     }
+
+    if (!OutChains.empty()) {
+      DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains));
+      return;
+    }
   }
 
   std::vector<SDOperand> Ops;