Emulate the current isel's "IsChainCompatible" logic for now.
authorChris Lattner <sabre@nondot.org>
Wed, 17 Feb 2010 06:23:39 +0000 (06:23 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 17 Feb 2010 06:23:39 +0000 (06:23 +0000)
I'd like to eventually rip it out, but for now producing the
same selections as the old matcher is more important.

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

include/llvm/CodeGen/DAGISelHeader.h
utils/TableGen/DAGISelMatcher.cpp
utils/TableGen/DAGISelMatcher.h
utils/TableGen/DAGISelMatcherEmitter.cpp
utils/TableGen/DAGISelMatcherGen.cpp

index 8cd11f6d26790e436a62615872e2fcb8738b80c6..70c2e02ff4f3008e04054f60ce0371df171b06ba 100644 (file)
@@ -217,7 +217,8 @@ enum BuiltinOpcodes {
   OPC_CheckComplexPat,
   OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8,
   OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8,
-  OPC_CheckFoldableChainNode
+  OPC_CheckFoldableChainNode,
+  OPC_CheckChainCompatible
 };
 
 struct MatchScope {
@@ -409,6 +410,13 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
       
       continue;
     }
+    case OPC_CheckChainCompatible: {
+      unsigned PrevNode = MatcherTable[MatcherIndex++];
+      assert(PrevNode < RecordedNodes.size() && "Invalid CheckChainCompatible");
+      if (!IsChainCompatible(RecordedNodes[PrevNode].getNode(), N.getNode()))
+        break;
+      continue;
+    }
     }
     
     // If the code reached this point, then the match failed pop out to the next
index d7519cec292b87f5c79ecc306bc04686424e51c9..83061093bc15418e730c82511375229dd15b2267 100644 (file)
@@ -111,3 +111,9 @@ void CheckFoldableChainNodeMatcherNode::print(raw_ostream &OS,
   OS.indent(indent) << "CheckFoldableChainNode\n";
   printChild(OS, indent);
 }
+
+void CheckChainCompatibleMatcherNode::print(raw_ostream &OS,
+                                              unsigned indent) const {
+  OS.indent(indent) << "CheckChainCompatibleMatcherNode " << PreviousOp << "\n";
+  printChild(OS, indent);
+}
index 53cf923e7035be1b676f753744dab715e1ea1262..3aa29cdbe2535c2a706845db0fb41f42a188d1db 100644 (file)
@@ -50,7 +50,8 @@ public:
     CheckComplexPat,
     CheckAndImm,
     CheckOrImm,
-    CheckFoldableChainNode
+    CheckFoldableChainNode,
+    CheckChainCompatible
   };
   const KindTy Kind;
   
@@ -380,6 +381,25 @@ public:
   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
 };
 
+/// CheckChainCompatibleMatcherNode - Verify that the current node's chain
+/// operand is 'compatible' with the specified recorded node's.
+class CheckChainCompatibleMatcherNode : public MatcherNodeWithChild {
+  unsigned PreviousOp;
+public:
+  CheckChainCompatibleMatcherNode(unsigned previousop)
+    : MatcherNodeWithChild(CheckChainCompatible), PreviousOp(previousop) {}
+  
+  unsigned getPreviousOp() const { return PreviousOp; }
+  
+  static inline bool classof(const MatcherNode *N) {
+    return N->getKind() == CheckChainCompatible;
+  }
+  
+  virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+  
+  
+
 } // end namespace llvm
 
 #endif
index 9b37254cbdde575efd9fcf391d4a7fa305a27f35..8e29c4717232383cb42edc6882e13db5a4bca385 100644 (file)
@@ -204,6 +204,10 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
   case MatcherNode::CheckFoldableChainNode:
     OS << "OPC_CheckFoldableChainNode,\n";
     return 1;
+  case MatcherNode::CheckChainCompatible:
+    OS << "OPC_CheckChainCompatible, "
+       << cast<CheckChainCompatibleMatcherNode>(N)->getPreviousOp() << ",\n";
+    return 2;
   }
   assert(0 && "Unreachable");
   return 0;
index e2ffb8e7171dac7a66cfea42797e1ac0bf26d8ce..8efcb4f982f09b077a82db4f4eff0cef4bd7214d 100644 (file)
@@ -165,6 +165,16 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
       assert(NextRecordedOperandNo > 1 &&
              "Should have recorded input/result chains at least!");
       InputChains.push_back(NextRecordedOperandNo-1);
+
+      // IF we need to check chains, do so, see comment for
+      // "NodeHasProperty(SDNPHasChain" below.
+      if (InputChains.size() > 1) {
+        // FIXME: This is broken, we should eliminate this nonsense completely,
+        // but we want to produce the same selections that the old matcher does
+        // for now.
+        unsigned PrevOp = InputChains[InputChains.size()-2];
+        AddMatcherNode(new CheckChainCompatibleMatcherNode(PrevOp));
+      }
     }
     return;
   }
@@ -229,10 +239,13 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
     // sure that folding the chain won't induce cycles in the DAG.  This could
     // happen if there were an intermediate node between the indbr and load, for
     // example.
-    
-    // FIXME: Emit "IsChainCompatible(lastchain.getNode(), CurrentNode)".
-    // Rename IsChainCompatible -> IsChainUnreachable, add comment about
-    // complexity.
+    if (InputChains.size() > 1) {
+      // FIXME: This is broken, we should eliminate this nonsense completely,
+      // but we want to produce the same selections that the old matcher does
+      // for now.
+      unsigned PrevOp = InputChains[InputChains.size()-2];
+      AddMatcherNode(new CheckChainCompatibleMatcherNode(PrevOp));
+    }
     
     // Don't look at the input chain when matching the tree pattern to the
     // SDNode.