summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-02-21 06:03:07 +0000
committerChris Lattner <sabre@nondot.org>2010-02-21 06:03:07 +0000
commit77f2e2724dc488bbf032e87f8f25f333730a0fb5 (patch)
treea7448610c2bdd7da61f0f95a5d6d0a94b3aa430d
parentf1c6428164f6f5e07cbc88c1c1440efbf29c0d5f (diff)
downloadllvm-77f2e2724dc488bbf032e87f8f25f333730a0fb5.tar.gz
llvm-77f2e2724dc488bbf032e87f8f25f333730a0fb5.tar.bz2
llvm-77f2e2724dc488bbf032e87f8f25f333730a0fb5.tar.xz
implement the last known missing feature: updating uses of results
of the matched pattern to use the newly created node results. Onto the "making it actually work" phase! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96724 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/DAGISelHeader.h62
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp2
-rw-r--r--utils/TableGen/DAGISelMatcher.cpp3
-rw-r--r--utils/TableGen/DAGISelMatcher.h24
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp16
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp8
6 files changed, 84 insertions, 31 deletions
diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h
index 41e3b2fb0a..9acd406792 100644
--- a/include/llvm/CodeGen/DAGISelHeader.h
+++ b/include/llvm/CodeGen/DAGISelHeader.h
@@ -101,7 +101,8 @@ void SelectRoot(SelectionDAG &DAG) {
// a reference to the root node, preventing it from being deleted,
// and tracking any changes of the root.
HandleSDNode Dummy(CurDAG->getRoot());
- ISelPosition = llvm::next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode()));
+ ISelPosition = SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode());
+ ++ISelPosition;
// The AllNodes list is now topological-sorted. Visit the
// nodes by starting at the end of the list (the root of the
@@ -114,21 +115,15 @@ void SelectRoot(SelectionDAG &DAG) {
// makes it theoretically possible to disable the DAGCombiner.
if (Node->use_empty())
continue;
-#if 0
- DAG.setSubgraphColor(Node, "red");
-#endif
+
SDNode *ResNode = Select(Node);
// If node should not be replaced, continue with the next one.
if (ResNode == Node)
continue;
// Replace node.
- if (ResNode) {
-#if 0
- DAG.setSubgraphColor(ResNode, "yellow");
- DAG.setSubgraphColor(ResNode, "black");
-#endif
+ if (ResNode)
ReplaceUses(Node, ResNode);
- }
+
// If after the replacement this node is not used any more,
// remove this dead node.
if (Node->use_empty()) { // Don't delete EntryToken, etc.
@@ -232,7 +227,8 @@ enum BuiltinOpcodes {
OPC_EmitMergeInputChains,
OPC_EmitCopyToReg,
OPC_EmitNodeXForm,
- OPC_EmitNode
+ OPC_EmitNode,
+ OPC_CompleteMatch
};
enum {
@@ -572,6 +568,7 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
if (NumChains == 1) {
unsigned RecNo = MatcherTable[MatcherIndex++];
assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ ChainNodesMatched.push_back(RecordedNodes[RecNo].getNode());
InputChain = RecordedNodes[RecNo].getOperand(0);
assert(InputChain.getValueType() == MVT::Other && "Not a chain");
continue;
@@ -707,6 +704,49 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
}
continue;
}
+
+ case OPC_CompleteMatch: {
+ // The match has been completed, and any new nodes (if any) have been
+ // created. Patch up references to the matched dag to use the newly
+ // created nodes.
+ unsigned NumResults = MatcherTable[MatcherIndex++];
+
+ for (unsigned i = 0; i != NumResults; ++i) {
+ unsigned ResSlot = MatcherTable[MatcherIndex++];
+ assert(ResSlot < RecordedNodes.size() && "Invalid CheckSame");
+ SDValue Res = RecordedNodes[ResSlot];
+ assert(NodeToMatch->getValueType(i) == Res.getValueType() &&
+ "invalid replacement");
+ ReplaceUses(SDValue(NodeToMatch, i), Res);
+ }
+
+ // Now that all the normal results are replaced, we replace the chain and
+ // flag results if present.
+ if (!ChainNodesMatched.empty()) {
+ assert(InputChain.getNode() != 0 &&
+ "Matched input chains but didn't produce a chain");
+ // Loop over all of the nodes we matched that produced a chain result.
+ // Replace all the chain results with the final chain we ended up with.
+ for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
+ SDNode *ChainNode = ChainNodesMatched[i];
+ SDValue ChainVal = SDValue(ChainNode, ChainNode->getNumValues()-1);
+ if (ChainVal.getValueType() == MVT::Flag)
+ ChainVal = ChainVal.getValue(ChainVal->getNumValues()-2);
+ assert(ChainVal.getValueType() == MVT::Other && "Not a chain?");
+ 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);
+
+ // FIXME: We just return here, which interacts correctly with SelectRoot
+ // above. We should fix this to not return an SDNode* anymore.
+ return 0;
+ }
}
// If the code reached this point, then the match failed pop out to the next
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 55a9d36588..d0da11479c 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -1917,7 +1917,7 @@ void DAGISelEmitter::run(raw_ostream &OS) {
// definitions. Emit the resultant instruction selector.
EmitInstructionSelector(OS);
-#if 0
+#if 1
MatcherNode *Matcher = 0;
// Walk the patterns backwards, building a matcher for each and adding it to
// the matcher for the whole target.
diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp
index eaaaefb3ab..b3c846c9ce 100644
--- a/utils/TableGen/DAGISelMatcher.cpp
+++ b/utils/TableGen/DAGISelMatcher.cpp
@@ -180,7 +180,8 @@ void EmitNodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
printNext(OS, indent);
}
-void PatternMarkerMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+void CompleteMatchMatcherNode::print(raw_ostream &OS, unsigned indent) const {
+ OS.indent(indent) << "CompleteMatch <todo args>\n";
OS.indent(indent) << "Src = " << *Pattern.getSrcPattern() << "\n";
OS.indent(indent) << "Dst = " << *Pattern.getDstPattern() << "\n";
printNext(OS, indent);
diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h
index 4dcb4d6af7..c162a0cbaa 100644
--- a/utils/TableGen/DAGISelMatcher.h
+++ b/utils/TableGen/DAGISelMatcher.h
@@ -70,7 +70,7 @@ public:
EmitCopyToReg, // Emit a copytoreg into a physreg.
EmitNode, // Create a DAG node
EmitNodeXForm, // Run a SDNodeXForm
- PatternMarker // Comment for printing.
+ CompleteMatch // Finish a match and update the results.
};
const KindTy Kind;
@@ -601,19 +601,25 @@ public:
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
};
-
-/// PatternMarkerMatcherNode - This prints as a comment indicating the source
-/// and dest patterns.
-class PatternMarkerMatcherNode : public MatcherNode {
+
+/// 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.
+class CompleteMatchMatcherNode : public MatcherNode {
+ SmallVector<unsigned, 2> Results;
const PatternToMatch &Pattern;
public:
- PatternMarkerMatcherNode(const PatternToMatch &pattern)
- : MatcherNode(PatternMarker), Pattern(pattern) {}
-
+ CompleteMatchMatcherNode(const unsigned *results, unsigned numresults,
+ const PatternToMatch &pattern)
+ : MatcherNode(CompleteMatch), Results(results, results+numresults),
+ Pattern(pattern) {}
+
+ unsigned getNumResults() const { return Results.size(); }
+ unsigned getResult(unsigned R) const { return Results[R]; }
const PatternToMatch &getPattern() const { return Pattern; }
static inline bool classof(const MatcherNode *N) {
- return N->getKind() == PatternMarker;
+ return N->getKind() == CompleteMatch;
}
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
index 077dd5df4d..de17005576 100644
--- a/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -305,13 +305,19 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
OS << '\n';
return 5+EN->getNumVTs()+EN->getNumOperands();
}
- case MatcherNode::PatternMarker:
- OS << "// Src: "
- << *cast<PatternMarkerMatcherNode>(N)->getPattern().getSrcPattern() << '\n';
- OS.PadToColumn(Indent*2) << "// Dst: "
- << *cast<PatternMarkerMatcherNode>(N)->getPattern().getDstPattern() << '\n';
+ case MatcherNode::CompleteMatch: {
+ const CompleteMatchMatcherNode *CM = cast<CompleteMatchMatcherNode>(N);
+ OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
+ for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
+ OS << CM->getResult(i) << ", ";
+ OS << '\n';
+ OS.PadToColumn(Indent*2) << "// Src: "
+ << *CM->getPattern().getSrcPattern() << '\n';
+ OS.PadToColumn(Indent*2) << "// Dst: "
+ << *CM->getPattern().getDstPattern() << '\n';
return 0;
}
+ }
assert(0 && "Unreachable");
return 0;
}
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 693c4ccf8d..b22fa875e0 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -723,8 +723,8 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
// The newly emitted node gets recorded.
// FIXME2: This should record all of the results except the (implicit) one.
- OutputOps.push_back(NextRecordedOperandNo++);
-
+ if (ResultVTs[0] != MVT::Other)
+ OutputOps.push_back(NextRecordedOperandNo++);
// FIXME2: Kill off all the SelectionDAG::SelectNodeTo and getMachineNode
// variants. Call MorphNodeTo instead of SelectNodeTo.
@@ -776,11 +776,11 @@ void MatcherGen::EmitResultCode() {
// We know that the resulting pattern has exactly one result/
// FIXME2: why? what about something like (set a,b,c, (complexpat))
// FIXME2: Implicit results should be pushed here I guess?
- assert(Ops.size() == 1);
+ assert(Ops.size() <= 1);
// FIXME: Handle Ops.
// FIXME: Handle (set EAX, (foo)) but not (implicit EFLAGS)
- AddMatcherNode(new PatternMarkerMatcherNode(Pattern));
+ AddMatcherNode(new CompleteMatchMatcherNode(Ops.data(), Ops.size(), Pattern));
}