[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp

Evan Cheng evan.cheng at apple.com
Tue Mar 7 15:29:52 PST 2006



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.103 -> 1.104
---
Log message:

Use rep/stosl; and Count 0x3; rep/stosb for memset with 4 byte aligned dest.
and variable value.
Similarly for memcpy.


---
Diffs of the changes:  (+72 -12)

 X86ISelLowering.cpp |   84 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 72 insertions(+), 12 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.103 llvm/lib/Target/X86/X86ISelLowering.cpp:1.104
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.103	Mon Mar  6 20:02:57 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Tue Mar  7 17:29:39 2006
@@ -1711,7 +1711,7 @@
     // If not DWORD aligned, call memset if size is less than the threshold.
     // It knows how to align to the right boundary first.
     if ((Align & 3) != 0 ||
-        !(I && I->getValue() >= Subtarget->getMinRepStrSizeThreshold())) {
+        (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) {
       MVT::ValueType IntPtr = getPointerTy();
       const Type *IntPtrTy = getTargetData().getIntPtrType();
       std::vector<std::pair<SDOperand, const Type*> > Args;
@@ -1730,6 +1730,7 @@
     SDOperand Count;
     ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Op.getOperand(2));
     unsigned BytesLeft = 0;
+    bool TwoRepStos = false;
     if (ValC) {
       unsigned ValReg;
       unsigned Val = ValC->getValue() & 255;
@@ -1745,8 +1746,14 @@
         break;
       case 0:   // DWORD aligned
         AVT = MVT::i32;
-        Count = DAG.getConstant(I->getValue() / 4, MVT::i32);
-        BytesLeft = I->getValue() % 4;
+        if (I) {
+          Count = DAG.getConstant(I->getValue() / 4, MVT::i32);
+          BytesLeft = I->getValue() % 4;
+        } else {
+          Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
+                              DAG.getConstant(2, MVT::i8));
+          TwoRepStos = true;
+        }
         Val = (Val << 8)  | Val;
         Val = (Val << 16) | Val;
         ValReg = X86::EAX;
@@ -1772,10 +1779,33 @@
     InFlag = Chain.getValue(1);
     Chain  = DAG.getCopyToReg(Chain, X86::EDI, Op.getOperand(1), InFlag);
     InFlag = Chain.getValue(1);
-    Chain  = DAG.getNode(X86ISD::REP_STOS, MVT::Other, Chain,
-                         DAG.getValueType(AVT), InFlag);
 
-    if (BytesLeft) {
+    std::vector<MVT::ValueType> Tys;
+    Tys.push_back(MVT::Other);
+    Tys.push_back(MVT::Flag);
+    std::vector<SDOperand> Ops;
+    Ops.push_back(Chain);
+    Ops.push_back(DAG.getValueType(AVT));
+    Ops.push_back(InFlag);
+    Chain  = DAG.getNode(X86ISD::REP_STOS, Tys, Ops);
+
+    if (TwoRepStos) {
+      InFlag = Chain.getValue(1);
+      Count = Op.getOperand(3);
+      MVT::ValueType CVT = Count.getValueType();
+      SDOperand Left = DAG.getNode(ISD::AND, CVT, Count,
+                                   DAG.getConstant(3, CVT));
+      Chain  = DAG.getCopyToReg(Chain, X86::ECX, Left, InFlag);
+      InFlag = Chain.getValue(1);
+      Tys.clear();
+      Tys.push_back(MVT::Other);
+      Tys.push_back(MVT::Flag);
+      Ops.clear();
+      Ops.push_back(Chain);
+      Ops.push_back(DAG.getValueType(MVT::i8));
+      Ops.push_back(InFlag);
+      Chain  = DAG.getNode(X86ISD::REP_STOS, Tys, Ops);
+    } else if (BytesLeft) {
       // Issue stores for the last 1 - 3 bytes.
       SDOperand Value;
       unsigned Val = ValC->getValue() & 255;
@@ -1813,7 +1843,7 @@
     // If not DWORD aligned, call memcpy if size is less than the threshold.
     // It knows how to align to the right boundary first.
     if ((Align & 3) != 0 ||
-        !(I && I->getValue() >= Subtarget->getMinRepStrSizeThreshold())) {
+        (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) {
       MVT::ValueType IntPtr = getPointerTy();
       const Type *IntPtrTy = getTargetData().getIntPtrType();
       std::vector<std::pair<SDOperand, const Type*> > Args;
@@ -1829,6 +1859,7 @@
     MVT::ValueType AVT;
     SDOperand Count;
     unsigned BytesLeft = 0;
+    bool TwoRepMovs = false;
     switch (Align & 3) {
     case 2:   // WORD aligned
       AVT = MVT::i16;
@@ -1837,8 +1868,14 @@
       break;
     case 0:   // DWORD aligned
       AVT = MVT::i32;
-      Count = DAG.getConstant(I->getValue() / 4, MVT::i32);
-      BytesLeft = I->getValue() % 4;
+      if (I) {
+        Count = DAG.getConstant(I->getValue() / 4, MVT::i32);
+        BytesLeft = I->getValue() % 4;
+      } else {
+        Count = DAG.getNode(ISD::SRL, MVT::i32, Op.getOperand(3),
+                            DAG.getConstant(2, MVT::i8));
+        TwoRepMovs = true;
+      }
       break;
     default:  // Byte aligned
       AVT = MVT::i8;
@@ -1853,10 +1890,33 @@
     InFlag = Chain.getValue(1);
     Chain  = DAG.getCopyToReg(Chain, X86::ESI, Op.getOperand(2), InFlag);
     InFlag = Chain.getValue(1);
-    Chain = DAG.getNode(X86ISD::REP_MOVS, MVT::Other, Chain,
-                        DAG.getValueType(AVT), InFlag);
 
-    if (BytesLeft) {
+    std::vector<MVT::ValueType> Tys;
+    Tys.push_back(MVT::Other);
+    Tys.push_back(MVT::Flag);
+    std::vector<SDOperand> Ops;
+    Ops.push_back(Chain);
+    Ops.push_back(DAG.getValueType(AVT));
+    Ops.push_back(InFlag);
+    Chain = DAG.getNode(X86ISD::REP_MOVS, Tys, Ops);
+
+    if (TwoRepMovs) {
+      InFlag = Chain.getValue(1);
+      Count = Op.getOperand(3);
+      MVT::ValueType CVT = Count.getValueType();
+      SDOperand Left = DAG.getNode(ISD::AND, CVT, Count,
+                                   DAG.getConstant(3, CVT));
+      Chain  = DAG.getCopyToReg(Chain, X86::ECX, Left, InFlag);
+      InFlag = Chain.getValue(1);
+      Tys.clear();
+      Tys.push_back(MVT::Other);
+      Tys.push_back(MVT::Flag);
+      Ops.clear();
+      Ops.push_back(Chain);
+      Ops.push_back(DAG.getValueType(MVT::i8));
+      Ops.push_back(InFlag);
+      Chain = DAG.getNode(X86ISD::REP_MOVS, Tys, Ops);
+    } else if (BytesLeft) {
       // Issue loads and stores for the last 1 - 3 bytes.
       unsigned Offset = I->getValue() - BytesLeft;
       SDOperand DstAddr = Op.getOperand(1);






More information about the llvm-commits mailing list