[llvm-commits] [llvm] r96331 - in /llvm/trunk: include/llvm/CodeGen/DAGISelHeader.h utils/TableGen/CodeGenDAGPatterns.h utils/TableGen/DAGISelEmitter.cpp utils/TableGen/DAGISelMatcher.cpp utils/TableGen/DAGISelMatcher.h utils/TableGen/DAGISelMatcherEmitter.cpp utils/TableGen/DAGISelMatcherGen.cpp

Chris Lattner sabre at nondot.org
Mon Feb 15 22:11:00 PST 2010


Author: lattner
Date: Tue Feb 16 00:10:58 2010
New Revision: 96331

URL: http://llvm.org/viewvc/llvm-project?rev=96331&view=rev
Log:
add support for the new isel matcher to generate 
(isprofitable|islegal)tofold checks.

Modified:
    llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
    llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
    llvm/trunk/utils/TableGen/DAGISelMatcher.cpp
    llvm/trunk/utils/TableGen/DAGISelMatcher.h
    llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp
    llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp

Modified: llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h?rev=96331&r1=96330&r2=96331&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h (original)
+++ llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h Tue Feb 16 00:10:58 2010
@@ -202,7 +202,9 @@
   OPC_CheckValueType,
   OPC_CheckComplexPat,
   OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8,
-  OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8
+  OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8,
+  OPC_IsProfitableToFold,
+  OPC_IsLegalToFold
 };
 
 struct MatchScope {
@@ -379,6 +381,19 @@
     case OPC_CheckOrImm8:
       if (CheckOrImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break;
       continue;
+        
+    case OPC_IsProfitableToFold:
+      assert(!NodeStack.size() == 1 && "No parent node");
+      if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(),
+                              NodeToMatch))
+        break;
+      continue;
+    case OPC_IsLegalToFold:
+      assert(!NodeStack.size() == 1 && "No parent node");
+      if (!IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(),
+                         NodeToMatch))
+        break;
+      continue;
     }
     
     // If the code reached this point, then the match failed pop out to the next

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h?rev=96331&r1=96330&r2=96331&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Tue Feb 16 00:10:58 2010
@@ -216,6 +216,13 @@
   void setChild(unsigned i, TreePatternNode *N) {
     Children[i] = N;
   }
+  
+  /// hasChild - Return true if N is any of our children.
+  bool hasChild(const TreePatternNode *N) const {
+    for (unsigned i = 0, e = Children.size(); i != e; ++i)
+      if (Children[i] == N) return true;
+    return false;
+  }
 
   const std::vector<std::string> &getPredicateFns() const {return PredicateFns;}
   void clearPredicateFns() { PredicateFns.clear(); }

Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=96331&r1=96330&r2=96331&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Tue Feb 16 00:10:58 2010
@@ -586,6 +586,8 @@
         //      /        [YY]
         //      |         ^
         //     [XX]-------|
+        
+        // We know we need the check if N's parent is not the root.
         bool NeedCheck = P != Pattern;
         if (!NeedCheck) {
           const SDNodeInfo &PInfo = CGP.getSDNodeInfo(P->getOperator());

Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.cpp?rev=96331&r1=96330&r2=96331&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcher.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcher.cpp Tue Feb 16 00:10:58 2010
@@ -106,3 +106,13 @@
   printChild(OS, indent);
 }
 
+void CheckProfitableToFoldMatcherNode::print(raw_ostream &OS,
+                                             unsigned indent) const {
+  OS.indent(indent) << "CheckProfitableToFold\n";
+  printChild(OS, indent);
+}
+
+void CheckLegalToFoldMatcherNode::print(raw_ostream &OS, unsigned indent) const{
+  OS.indent(indent) << "CheckLegalToFold\n";
+  printChild(OS, indent);
+}

Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.h?rev=96331&r1=96330&r2=96331&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcher.h (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcher.h Tue Feb 16 00:10:58 2010
@@ -48,7 +48,9 @@
     CheckValueType,
     CheckComplexPat,
     CheckAndImm,
-    CheckOrImm
+    CheckOrImm,
+    CheckProfitableToFold,
+    CheckLegalToFold
   };
   const KindTy Kind;
   
@@ -355,8 +357,34 @@
   
   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
 };
+
+/// CheckProfitableToFoldMatcherNode - This checks to see if the current node is
+/// worthwhile to try to fold into a large pattern.
+class CheckProfitableToFoldMatcherNode : public MatcherNodeWithChild {
+public:
+  CheckProfitableToFoldMatcherNode()
+  : MatcherNodeWithChild(CheckProfitableToFold) {}
+  
+  static inline bool classof(const MatcherNode *N) {
+    return N->getKind() == CheckProfitableToFold;
+  }
+  
+  virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
+/// CheckLegalToFoldMatcherNode - This checks to see if the current node is
+/// legal to try to fold into a large pattern.
+class CheckLegalToFoldMatcherNode : public MatcherNodeWithChild {
+public:
+  CheckLegalToFoldMatcherNode()
+  : MatcherNodeWithChild(CheckLegalToFold) {}
   
+  static inline bool classof(const MatcherNode *N) {
+    return N->getKind() == CheckLegalToFold;
+  }
   
+  virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
 } // end namespace llvm
 
 #endif

Modified: llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp?rev=96331&r1=96330&r2=96331&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp Tue Feb 16 00:10:58 2010
@@ -151,6 +151,12 @@
     OS << "OPC_CheckOrImm" << ClassifyInt(Val) << ", ";
     return EmitInt(Val, OS)+1;
   }
+  case MatcherNode::CheckProfitableToFold:
+    OS << "OPC_IsProfitableToFold,\n";
+    return 1;
+  case MatcherNode::CheckLegalToFold:
+    OS << "OPC_IsLegalToFold,\n";
+    return 1;
   }
   assert(0 && "Unreachable");
   return 0;

Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=96331&r1=96330&r2=96331&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Tue Feb 16 00:10:58 2010
@@ -189,18 +189,61 @@
   if (N->NodeHasProperty(SDNPHasChain, CGP))
     OpNo = 1;
 
-  if (N->TreeHasProperty(SDNPHasChain, CGP)) {
-    // FIXME: Handle Chains with multiple uses etc.
-    //         [ld]
-    //         ^  ^
-    //         |  |
-    //        /   \---
-    //      /        [YY]
-    //      |         ^
-    //     [XX]-------|
+  // If this node is not the root and the subtree underneath it produces a
+  // chain, then the result of matching the node is also produce a chain.
+  // Beyond that, this means that we're also folding (at least) the root node
+  // into the node that produce the chain (for example, matching
+  // "(add reg, (load ptr))" as a add_with_memory on X86).  This is problematic,
+  // if the 'reg' node also uses the load (say, its chain).  Graphically:
+  //
+  //         [LD]
+  //         ^  ^
+  //         |  \                              DAG's like cheese.
+  //        /    |
+  //       /    [YY]
+  //       |     ^
+  //      [XX]--/
+  //
+  // It would be invalid to fold XX and LD.  In this case, folding the two
+  // nodes together would induce a cycle in the DAG, making it a cyclic DAG (!).
+  // To prevent this, we emit a dynamic check for legality before allowing this
+  // to be folded.
+  //
+  const TreePatternNode *Root = Pattern.getSrcPattern();
+  if (N != Root &&                             // Not the root of the pattern.
+      N->TreeHasProperty(SDNPHasChain, CGP)) { // Has a chain somewhere in tree.
+    
+    AddMatcherNode(new CheckProfitableToFoldMatcherNode());
+    
+    // If this non-root node produces a chain, we may need to emit a validity
+    // check.
+    if (OpNo != 0) {
+      // If there is a node between the root and this node, then we definitely
+      // need to emit the check.
+      bool NeedCheck = !Root->hasChild(N);
+      
+      // If it *is* an immediate child of the root, we can still need a check if
+      // the root SDNode has multiple inputs.  For us, this means that it is an
+      // intrinsic, has multiple operands, or has other inputs like chain or
+      // flag).
+      if (!NeedCheck) {
+        const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Root->getOperator());
+        NeedCheck =
+          Root->getOperator() == CGP.get_intrinsic_void_sdnode() ||
+          Root->getOperator() == CGP.get_intrinsic_w_chain_sdnode() ||
+          Root->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() ||
+          PInfo.getNumOperands() > 1 ||
+          PInfo.hasProperty(SDNPHasChain) ||
+          PInfo.hasProperty(SDNPInFlag) ||
+          PInfo.hasProperty(SDNPOptInFlag);
+      }
+      
+      if (NeedCheck)
+        AddMatcherNode(new CheckLegalToFoldMatcherNode());
+    }
   }
       
-  // FIXME: Handle Flags & .hasOneUse()
+  // FIXME: Handle EmittedUseCheck & Flags & .hasOneUse()
   
   for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
     // Get the code suitable for matching this child.  Move to the child, check





More information about the llvm-commits mailing list