[llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp AlphaInstrInfo.td

Chris Lattner sabre at nondot.org
Tue Oct 10 22:14:10 PDT 2006



Changes in directory llvm/lib/Target/Alpha:

AlphaISelDAGToDAG.cpp updated: 1.56 -> 1.57
AlphaInstrInfo.td updated: 1.127 -> 1.128
---
Log message:

Use cute tblgen tricks to make zap handling more powerful.  Specifically,
when the dag combiner simplifies an and mask, notice this and allow those bits
to be missing from the zap mask.

This compiles Alpha/zapnot4.ll into:

        sll $16,3,$0
        zapnot $0,3,$0
        ret $31,($26),1

instead of:

        ldah $0,1($31)
        lda $0,-8($0)
        sll $16,3,$1
        and $1,$0,$0
        ret $31,($26),1

It would be *really* nice to replace the hunk of code in the 
AlphaISelDAGToDAG.cpp file that matches (and (srl (x, C), c2) into
(SRL (ZAPNOTi)) with a similar pattern, but I've spent enough time poking
at alpha.  Make andrew will do this.



---
Diffs of the changes:  (+70 -21)

 AlphaISelDAGToDAG.cpp |   65 ++++++++++++++++++++++++++++++++++++++++----------
 AlphaInstrInfo.td     |   26 +++++++++++++-------
 2 files changed, 70 insertions(+), 21 deletions(-)


Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.56 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.57
--- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.56	Tue Oct 10 23:29:42 2006
+++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp	Wed Oct 11 00:13:56 2006
@@ -59,19 +59,57 @@
       return x - get_ldah16(x) * IMM_MULT;
     }
 
+    /// get_zapImm - Return a zap mask if X is a valid immediate for a zapnot
+    /// instruction (if not, return 0).  Note that this code accepts partial
+    /// zap masks.  For example (and LHS, 1) is a valid zap, as long we know
+    /// that the bits 1-7 of LHS are already zero.  If LHS is non-null, we are
+    /// in checking mode.  If LHS is null, we assume that the mask has already
+    /// been validated before.
+    uint64_t get_zapImm(SDOperand LHS, uint64_t Constant) {
+      uint64_t BitsToCheck = 0;
+      unsigned Result = 0;
+      for (unsigned i = 0; i != 8; ++i) {
+        if (((Constant >> 8*i) & 0xFF) == 0) {
+          // nothing to do.
+        } else {
+          Result |= 1 << i;
+          if (((Constant >> 8*i) & 0xFF) == 0xFF) {
+            // If the entire byte is set, zapnot the byte.
+          } else if (LHS.Val == 0) {
+            // Otherwise, if the mask was previously validated, we know its okay
+            // to zapnot this entire byte even though all the bits aren't set.
+          } else {
+            // Otherwise we don't know that the it's okay to zapnot this entire
+            // byte.  Only do this iff we can prove that the missing bits are
+            // already null, so the bytezap doesn't need to really null them.
+            BitsToCheck |= ~Constant & (0xFF << 8*i);
+          }
+        }
+      }
+      
+      // If there are missing bits in a byte (for example, X & 0xEF00), check to
+      // see if the missing bits (0x1000) are already known zero if not, the zap
+      // isn't okay to do, as it won't clear all the required bits.
+      if (BitsToCheck &&
+          !getTargetLowering().MaskedValueIsZero(LHS, BitsToCheck))
+        return 0;
+      
+      return Result;
+    }
+    
     static uint64_t get_zapImm(uint64_t x) {
-      unsigned int build = 0;
-      for(int i = 0; i < 8; ++i)
-	{
-	  if ((x & 0x00FF) == 0x00FF)
-	    build |= 1 << i;
-	  else if ((x & 0x00FF) != 0)
-	    { build = 0; break; }
-	  x >>= 8;
-	}
+      unsigned build = 0;
+      for(int i = 0; i != 8; ++i) {
+        if ((x & 0x00FF) == 0x00FF)
+          build |= 1 << i;
+        else if ((x & 0x00FF) != 0)
+          return 0;
+        x >>= 8;
+      }
       return build;
     }
-
+      
+    
     static uint64_t getNearPower2(uint64_t x) {
       if (!x) return 0;
       unsigned at = CountLeadingZeros_64(x);
@@ -380,10 +418,11 @@
       {
 	uint64_t sval = SC->getValue();
 	uint64_t mval = MC->getValue();
-	if (get_zapImm(mval)) //the result is a zap, let the autogened stuff deal
+        // If the result is a zap, let the autogened stuff handle it.
+	if (get_zapImm(N->getOperand(0), mval))
 	  break;
-	// given mask X, and shift S, we want to see if there is any zap in the mask
-	// if we play around with the botton S bits
+	// given mask X, and shift S, we want to see if there is any zap in the
+        // mask if we play around with the botton S bits
 	uint64_t dontcare = (~0ULL) >> (64 - sval);
 	uint64_t mask = mval << sval;
 


Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td
diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.127 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.128
--- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.127	Tue Oct 10 23:12:39 2006
+++ llvm/lib/Target/Alpha/AlphaInstrInfo.td	Wed Oct 11 00:13:56 2006
@@ -59,8 +59,9 @@
 def LH16 : SDNodeXForm<imm, [{ //ldah part of constant (or more if too big)
   return getI64Imm(get_ldah16(N->getValue()));
 }]>;
-def iZAPX : SDNodeXForm<imm, [{ // get imm to ZAPi
-  return getI64Imm(get_zapImm((uint64_t)N->getValue()));
+def iZAPX : SDNodeXForm<and, [{ // get imm to ZAPi
+  ConstantSDNode *RHS = cast<ConstantSDNode>(N->getOperand(1));
+  return getI64Imm(get_zapImm(SDOperand(), RHS->getValue()));
 }]>;
 def nearP2X : SDNodeXForm<imm, [{
   return getI64Imm(Log2_64(getNearPower2((uint64_t)N->getValue())));
@@ -85,10 +86,15 @@
 def immSExt16int  : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field
   return ((int64_t)N->getValue() << 48) >> 48 == ((int64_t)N->getValue() << 32) >> 32;
 }], SExt16>;
-def immZAP  : PatLeaf<(imm), [{ //imm is good for zapi
-  uint64_t build = get_zapImm((uint64_t)N->getValue());
-  return build != 0;
-}], iZAPX>;
+
+def zappat : PatFrag<(ops node:$LHS), (and node:$LHS, imm:$L), [{
+  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
+    uint64_t build = get_zapImm(N->getOperand(0), (uint64_t)RHS->getValue());
+    return build != 0;
+  }
+  return false;
+}]>;
+
 def immFPZ  : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
   return true;
 }]>;
@@ -386,8 +392,12 @@
 def XORi     : OFormL<0x11, 0x40, "xor $RA,$L,$RC",
                       [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))], s_ilog>;
                       
-def ZAPNOTi  : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", 
-                      [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))], s_ishf>; 
+def ZAPNOTi  : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", [], s_ishf>;
+
+// Define the pattern that produces ZAPNOTi.
+def : Pat<(i64 (zappat GPRC:$RA):$imm),
+          (ZAPNOTi GPRC:$RA, (iZAPX GPRC:$imm))>;
+
 
 //Comparison, int
 //So this is a waste of what this instruction can do, but it still saves something






More information about the llvm-commits mailing list