[llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp

Chris Lattner sabre at nondot.org
Tue Oct 10 21:06:09 PDT 2006



Changes in directory llvm/utils/TableGen:

DAGISelEmitter.cpp updated: 1.265 -> 1.266
---
Log message:

Special case tblgen generated code for patterns like (and X, 255) or (or X, 42).
The dag/inst combiners often 'simplify' the masked value based on whether
or not the bits are live or known zero/one.  This is good and dandy, but 
often causes special case patterns to fail, such as alpha's CMPBGE pattern,
which looks like "(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))".
Here the pattern for (and X, 255) should match actual dags like (and X, 254) if
the dag combiner proved that the missing bits are already zero (one for 'or').

For CodeGen/Alpha/cmpbge.ll:test2 for example, this results in:

        sll $16,1,$0
        cmpbge $0,$17,$0
        ret $31,($26),1

instead of:

        sll $16,1,$0
        and $0,254,$0
        and $17,255,$1
        cmpule $1,$0,$0
        ret $31,($26),1

... and requires no target-specific code.



---
Diffs of the changes:  (+36 -1)

 DAGISelEmitter.cpp |   37 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 36 insertions(+), 1 deletion(-)


Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.265 llvm/utils/TableGen/DAGISelEmitter.cpp:1.266
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.265	Tue Oct 10 22:35:34 2006
+++ llvm/utils/TableGen/DAGISelEmitter.cpp	Tue Oct 10 23:05:55 2006
@@ -2320,6 +2320,41 @@
       emitCheck(N->getPredicateFn() + "(" + RootName + ".Val)");
 
     
+    // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
+    // a constant without a predicate fn that has more that one bit set, handle
+    // this as a special case.  This is usually for targets that have special
+    // handling of certain large constants (e.g. alpha with it's 8/16/32-bit
+    // handling stuff).  Using these instructions is often far more efficient
+    // than materializing the constant.  Unfortunately, both the instcombiner
+    // and the dag combiner can often infer that bits are dead, and thus drop
+    // them from the mask in the dag.  For example, it might turn 'AND X, 255'
+    // into 'AND X, 254' if it knows the low bit is set.  Emit code that checks
+    // to handle this.
+    if (!N->isLeaf() && 
+        (N->getOperator()->getName() == "and" || 
+         N->getOperator()->getName() == "or") &&
+        N->getChild(1)->isLeaf() &&
+        N->getChild(1)->getPredicateFn().empty()) {
+      if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
+        if (!isPowerOf2_32(II->getValue())) {  // Don't bother with single bits.
+          emitInit("SDOperand " + RootName + "0" + " = " +
+                   RootName + ".getOperand(" + utostr(0) + ");");
+          emitInit("SDOperand " + RootName + "1" + " = " +
+                   RootName + ".getOperand(" + utostr(1) + ");");
+
+          emitCheck("isa<ConstantSDNode>(" + RootName + "1)");
+          const char *MaskPredicate = N->getOperator()->getName() == "or"
+            ? "CheckOrMask(" : "CheckAndMask(";
+          emitCheck(MaskPredicate + RootName + "0, cast<ConstantSDNode>(" +
+                    RootName + "1), " + itostr(II->getValue()) + ")");
+          
+          EmitChildMatchCode(N->getChild(0), N, RootName + utostr(0),
+                             ChainSuffix + utostr(0), FoundChain);
+          return;
+        }
+      }
+    }
+    
     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
       emitInit("SDOperand " + RootName + utostr(OpNo) + " = " +
                RootName + ".getOperand(" +utostr(OpNo) + ");");
@@ -2344,7 +2379,7 @@
       emitCheck(Code + ")");
     }
   }
-  
+
   void EmitChildMatchCode(TreePatternNode *Child, TreePatternNode *Parent,
                           const std::string &RootName,
                           const std::string &ChainSuffix, bool &FoundChain) {






More information about the llvm-commits mailing list