Emit redundant opcode checks for andimm and orimm tests at root
authorChris Lattner <sabre@nondot.org>
Mon, 1 Mar 2010 02:15:34 +0000 (02:15 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 1 Mar 2010 02:15:34 +0000 (02:15 +0000)
so that we get grouping at the top level.

Add an optimization to reorder type check & record nodes
after opcode checks.  We prefer to expose tree shape
matching which improves grouping and will enhance the next
optimization.

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

utils/TableGen/DAGISelMatcherGen.cpp
utils/TableGen/DAGISelMatcherOpt.cpp

index 120a3dc1d594e5934fc4482557bd6ea84c42f038..d198488305923100901f2ec41871cd68bac0e2f5 100644 (file)
@@ -320,6 +320,13 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
       N->getPredicateFns().empty()) {
     if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
       if (!isPowerOf2_32(II->getValue())) {  // Don't bother with single bits.
+        // If this is at the root of the pattern, we emit a redundant
+        // CheckOpcode so that the following checks get factored properly under
+        // a single opcode check.
+        if (N == Pattern.getSrcPattern())
+          AddMatcher(new CheckOpcodeMatcher(CInfo));
+
+        // Emit the CheckAndImm/CheckOrImm node.
         if (N->getOperator()->getName() == "and")
           AddMatcher(new CheckAndImmMatcher(II->getValue()));
         else
index 37643c318407e39feaa5b1c63fea733eb5210b8e..11818279052e892526b5f6b34b8b0d86b4a42ca8 100644 (file)
@@ -127,6 +127,26 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
     }
   
   ContractNodes(N->getNextPtr(), CGP);
+  
+  
+  // If we have a CheckType/CheckChildType/Record node followed by a
+  // CheckOpcode, invert the two nodes.  We prefer to do structural checks
+  // before type checks, as this opens opportunities for factoring on targets
+  // like X86 where many operations are valid on multiple types.
+  if ((isa<CheckTypeMatcher>(N) || isa<CheckChildTypeMatcher>(N) ||
+       isa<RecordMatcher>(N)) &&
+      isa<CheckOpcodeMatcher>(N->getNext())) {
+    // Unlink the two nodes from the list.
+    Matcher *CheckType = MatcherPtr.take();
+    Matcher *CheckOpcode = CheckType->takeNext();
+    Matcher *Tail = CheckOpcode->takeNext();
+    
+    // Relink them.
+    MatcherPtr.reset(CheckOpcode);
+    CheckOpcode->setNext(CheckType);
+    CheckType->setNext(Tail);
+    return ContractNodes(MatcherPtr, CGP);
+  }
 }
 
 /// SinkPatternPredicates - Pattern predicates can be checked at any level of