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

Chris Lattner sabre at nondot.org
Tue Feb 23 21:33:42 PST 2010


Author: lattner
Date: Tue Feb 23 23:33:42 2010
New Revision: 97021

URL: http://llvm.org/viewvc/llvm-project?rev=97021&view=rev
Log:
The new isel was not properly handling patterns that covered
internal nodes with flag results.  Record these with a new 
OPC_MarkFlagResults opcode and use this to update the interior
nodes' flag results properly.  This fixes CodeGen/X86/i256-add.ll
with the new isel.

Modified:
    llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h
    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=97021&r1=97020&r2=97021&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h (original)
+++ llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h Tue Feb 23 23:33:42 2010
@@ -247,6 +247,7 @@
   OPC_EmitCopyToReg,
   OPC_EmitNodeXForm,
   OPC_EmitNode,
+  OPC_MarkFlagResults,
   OPC_CompleteMatch
 };
 
@@ -290,7 +291,7 @@
   SDValue InputChain, InputFlag;
 
   /// HasChainNodesMatched - True if the ChainNodesMatched list is non-empty.
-  bool HasChainNodesMatched;
+  bool HasChainNodesMatched, HasFlagResultNodesMatched;
 };
 
 SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
@@ -354,6 +355,7 @@
   // which ones they are.  The result is captured into this list so that we can
   // update the chain results when the pattern is complete.
   SmallVector<SDNode*, 3> ChainNodesMatched;
+  SmallVector<SDNode*, 3> FlagResultNodesMatched;
   
   DEBUG(errs() << "ISEL: Starting pattern match on root node: ";
         NodeToMatch->dump(CurDAG);
@@ -374,6 +376,7 @@
       NewEntry.InputChain = InputChain;
       NewEntry.InputFlag = InputFlag;
       NewEntry.HasChainNodesMatched = !ChainNodesMatched.empty();
+      NewEntry.HasFlagResultNodesMatched = !FlagResultNodesMatched.empty();
       MatchScopes.push_back(NewEntry);
       continue;
     }
@@ -387,6 +390,7 @@
       NewEntry.InputChain = InputChain;
       NewEntry.InputFlag = InputFlag;
       NewEntry.HasChainNodesMatched = !ChainNodesMatched.empty();
+      NewEntry.HasFlagResultNodesMatched = !FlagResultNodesMatched.empty();
       MatchScopes.push_back(NewEntry);
       continue;
     }
@@ -796,6 +800,21 @@
       DEBUG(errs() << "  Created node: "; Res->dump(CurDAG); errs() << "\n");
       continue;
     }
+        
+    case OPC_MarkFlagResults: {
+      unsigned NumNodes = MatcherTable[MatcherIndex++];
+      
+      // Read and remember all the flag-result nodes.
+      for (unsigned i = 0; i != NumNodes; ++i) {
+        unsigned RecNo = MatcherTable[MatcherIndex++];
+        if (RecNo & 128)
+          RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex);
+
+        assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+        FlagResultNodesMatched.push_back(RecordedNodes[RecNo].getNode());
+      }
+      continue;
+    }
       
     case OPC_CompleteMatch: {
       // The match has been completed, and any new nodes (if any) have been
@@ -844,12 +863,24 @@
           ReplaceUses(ChainVal, InputChain);
         }
       }
-      // If the root node produces a flag, make sure to replace its flag
-      // result with the resultant flag.
-      if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) ==
-            MVT::Flag)
-        ReplaceUses(SDValue(NodeToMatch, NodeToMatch->getNumValues()-1),
-                    InputFlag);
+
+      // If the result produces a flag, update any flag results in the matched
+      // pattern with the flag result.
+      if (InputFlag.getNode() != 0) {
+        // Handle the root node:
+        if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) ==
+              MVT::Flag)
+          ReplaceUses(SDValue(NodeToMatch, NodeToMatch->getNumValues()-1),
+                      InputFlag);
+        
+        // Handle any interior nodes explicitly marked.
+        for (unsigned i = 0, e = FlagResultNodesMatched.size(); i != e; ++i) {
+          SDNode *FRN = FlagResultNodesMatched[i];
+          assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Flag &&
+                 "Doesn't have a flag result");
+          ReplaceUses(SDValue(FRN, FRN->getNumValues()-1), InputFlag);
+        }
+      }
       
       assert(NodeToMatch->use_empty() &&
              "Didn't replace all uses of the node?");
@@ -885,7 +916,9 @@
     InputFlag = LastScope.InputFlag;
     if (!LastScope.HasChainNodesMatched)
       ChainNodesMatched.clear();
-    
+    if (!LastScope.HasFlagResultNodesMatched)
+      FlagResultNodesMatched.clear();
+
     MatchScopes.pop_back();
   }
 }

Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.cpp?rev=97021&r1=97020&r2=97021&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcher.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcher.cpp Tue Feb 23 23:33:42 2010
@@ -185,6 +185,11 @@
   printNext(OS, indent);
 }
 
+void MarkFlagResultsMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+  OS.indent(indent) << "MarkFlagResults <todo: args>\n";
+  printNext(OS, indent);
+}
+
 void CompleteMatchMatcherNode::print(raw_ostream &OS, unsigned indent) const {
   OS.indent(indent) << "CompleteMatch <todo args>\n";
   OS.indent(indent) << "Src = " << *Pattern.getSrcPattern() << "\n";

Modified: llvm/trunk/utils/TableGen/DAGISelMatcher.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcher.h?rev=97021&r1=97020&r2=97021&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcher.h (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcher.h Tue Feb 23 23:33:42 2010
@@ -71,6 +71,7 @@
     EmitCopyToReg,        // Emit a copytoreg into a physreg.
     EmitNode,             // Create a DAG node
     EmitNodeXForm,        // Run a SDNodeXForm
+    MarkFlagResults,      // Indicate which interior nodes have flag results.
     CompleteMatch         // Finish a match and update the results.
   };
   const KindTy Kind;
@@ -623,6 +624,29 @@
   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
 };
   
+/// MarkFlagResultsMatcherNode - This node indicates which non-root nodes in the
+/// pattern produce flags.  This allows CompleteMatchMatcherNode to update them
+/// with the output flag of the resultant code.
+class MarkFlagResultsMatcherNode : public MatcherNode {
+  SmallVector<unsigned, 3> FlagResultNodes;
+public:
+  MarkFlagResultsMatcherNode(const unsigned *nodes, unsigned NumNodes)
+  : MatcherNode(MarkFlagResults), FlagResultNodes(nodes, nodes+NumNodes) {}
+  
+  unsigned getNumNodes() const { return FlagResultNodes.size(); }
+  
+  unsigned getNode(unsigned i) const {
+    assert(i < FlagResultNodes.size());
+    return FlagResultNodes[i];
+  }  
+  
+  static inline bool classof(const MatcherNode *N) {
+    return N->getKind() == MarkFlagResults;
+  }
+  
+  virtual void print(raw_ostream &OS, unsigned indent = 0) const;
+};
+
 /// CompleteMatchMatcherNode - Complete a match by replacing the results of the
 /// pattern with the newly generated nodes.  This also prints a comment
 /// indicating the source and dest patterns.

Modified: llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp?rev=97021&r1=97020&r2=97021&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcherEmitter.cpp Tue Feb 23 23:33:42 2010
@@ -337,6 +337,15 @@
     OS << '\n';
     return 6+EN->getNumVTs()+NumOperandBytes;
   }
+  case MatcherNode::MarkFlagResults: {
+    const MarkFlagResultsMatcherNode *CFR = cast<MarkFlagResultsMatcherNode>(N);
+    OS << "OPC_MarkFlagResults, " << CFR->getNumNodes() << ", ";
+    unsigned NumOperandBytes = 0;
+    for (unsigned i = 0, e = CFR->getNumNodes(); i != e; ++i)
+      NumOperandBytes += EmitVBRValue(CFR->getNode(i), OS);
+    OS << '\n';
+    return 2+NumOperandBytes;
+  }
   case MatcherNode::CompleteMatch: {
     const CompleteMatchMatcherNode *CM = cast<CompleteMatchMatcherNode>(N);
     OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";

Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=97021&r1=97020&r2=97021&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Tue Feb 23 23:33:42 2010
@@ -70,6 +70,10 @@
     /// MatchedChainNodes - This maintains the position in the recorded nodes
     /// array of all of the recorded input nodes that have chains.
     SmallVector<unsigned, 2> MatchedChainNodes;
+
+    /// MatchedFlagResultNodes - This maintains the position in the recorded
+    /// nodes array of all of the recorded input nodes that have flag results.
+    SmallVector<unsigned, 2> MatchedFlagResultNodes;
     
     /// PhysRegInputs - List list has an entry for each explicitly specified
     /// physreg input to the pattern.  The first elt is the Register node, the
@@ -287,6 +291,9 @@
         AddMatcherNode(new CheckChainCompatibleMatcherNode(PrevOp));
       }
     }
+    
+    // TODO: Complex patterns can't have output flags, if they did, we'd want
+    // to record them.
     return;
   }
   
@@ -416,6 +423,18 @@
         AddMatcherNode(new CheckFoldableChainNodeMatcherNode());
     }
   }
+
+  // If this node has an output flag and isn't the root, remember it.
+  if (N->NodeHasProperty(SDNPOutFlag, CGP) && 
+      N != Pattern.getSrcPattern()) {
+    // TODO: This redundantly records nodes with both flags and chains.
+    
+    // Record the node and remember it in our chained nodes list.
+    AddMatcherNode(new RecordMatcherNode("'" + N->getOperator()->getName() +
+                                         "' flag output node"));
+    // Remember all of the nodes with output flags our pattern will match.
+    MatchedFlagResultNodes.push_back(NextRecordedOperandNo++);
+  }
   
   // If this node is known to have an input flag or if it *might* have an input
   // flag, capture it as the flag input of the pattern.
@@ -598,16 +617,16 @@
   
   bool isRoot = N == Pattern.getDstPattern();
 
-  // NodeHasOutFlag - True if this node has a flag.
-  bool NodeHasInFlag = false, NodeHasOutFlag = false;
+  // TreeHasOutFlag - True if this tree has a flag.
+  bool TreeHasInFlag = false, TreeHasOutFlag = false;
   if (isRoot) {
     const TreePatternNode *SrcPat = Pattern.getSrcPattern();
-    NodeHasInFlag = SrcPat->TreeHasProperty(SDNPOptInFlag, CGP) ||
+    TreeHasInFlag = SrcPat->TreeHasProperty(SDNPOptInFlag, CGP) ||
                     SrcPat->TreeHasProperty(SDNPInFlag, CGP);
   
     // FIXME2: this is checking the entire pattern, not just the node in
     // question, doing this just for the root seems like a total hack.
-    NodeHasOutFlag = SrcPat->TreeHasProperty(SDNPOutFlag, CGP);
+    TreeHasOutFlag = SrcPat->TreeHasProperty(SDNPOutFlag, CGP);
   }
 
   // NumResults - This is the number of results produced by the instruction in
@@ -668,7 +687,7 @@
                                                   PhysRegInputs[i].first));
     // Even if the node has no other flag inputs, the resultant node must be
     // flagged to the CopyFromReg nodes we just generated.
-    NodeHasInFlag = true;
+    TreeHasInFlag = true;
   }
   
   // Result order: node results, chain, flags
@@ -694,7 +713,7 @@
   }
   if (NodeHasChain)
     ResultVTs.push_back(MVT::Other);
-  if (NodeHasOutFlag)
+  if (TreeHasOutFlag)
     ResultVTs.push_back(MVT::Flag);
 
   // FIXME2: Instead of using the isVariadic flag on the instruction, we should
@@ -727,7 +746,7 @@
   AddMatcherNode(new EmitNodeMatcherNode(II.Namespace+"::"+II.TheDef->getName(),
                                          ResultVTs.data(), ResultVTs.size(),
                                          InstOps.data(), InstOps.size(),
-                                         NodeHasChain, NodeHasInFlag,
+                                         NodeHasChain, TreeHasInFlag,
                                          NodeHasMemRefs,NumFixedArityOperands));
   
   // The non-chain and non-flag results of the newly emitted node get recorded.
@@ -813,6 +832,13 @@
   assert(Ops.size() >= NumSrcResults && "Didn't provide enough results");
   Ops.resize(NumSrcResults);
 #endif
+
+  // If the matched pattern covers nodes which define a flag result, emit a node
+  // that tells the matcher about them so that it can update their results.
+  if (!MatchedFlagResultNodes.empty())
+    AddMatcherNode(new MarkFlagResultsMatcherNode(MatchedFlagResultNodes.data(),
+                                                MatchedFlagResultNodes.size()));
+  
   
   // We know that the resulting pattern has exactly one result/
   // FIXME2: why?  what about something like (set a,b,c, (complexpat))





More information about the llvm-commits mailing list