aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp29
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp7
3 files changed, 38 insertions, 0 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index a1576be..def09c7 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -136,6 +136,8 @@ public:
OPC_EmitRegister,
OPC_EmitConvertToTarget,
OPC_EmitMergeInputChains,
+ OPC_EmitMergeInputChains1_0,
+ OPC_EmitMergeInputChains1_1,
OPC_EmitCopyToReg,
OPC_EmitNodeXForm,
OPC_EmitNode,
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 3981826..6e5a6ad 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2440,6 +2440,35 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
continue;
}
+ case OPC_EmitMergeInputChains1_0: // OPC_EmitMergeInputChains, 1, 0
+ case OPC_EmitMergeInputChains1_1: { // OPC_EmitMergeInputChains, 1, 1
+ // These are space-optimized forms of OPC_EmitMergeInputChains.
+ assert(InputChain.getNode() == 0 &&
+ "EmitMergeInputChains should be the first chain producing node");
+ assert(ChainNodesMatched.empty() &&
+ "Should only have one EmitMergeInputChains per match");
+
+ // Read all of the chained nodes.
+ unsigned RecNo = Opcode == OPC_EmitMergeInputChains1_1;
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ ChainNodesMatched.push_back(RecordedNodes[RecNo].getNode());
+
+ // FIXME: What if other value results of the node have uses not matched
+ // by this pattern?
+ if (ChainNodesMatched.back() != NodeToMatch &&
+ !RecordedNodes[RecNo].hasOneUse()) {
+ ChainNodesMatched.clear();
+ break;
+ }
+
+ // Merge the input chains if they are not intra-pattern references.
+ InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG);
+
+ if (InputChain.getNode() == 0)
+ break; // Failed to merge.
+ continue;
+ }
+
case OPC_EmitMergeInputChains: {
assert(InputChain.getNode() == 0 &&
"EmitMergeInputChains should be the first chain producing node");
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
index 8855034..25b7a2f 100644
--- a/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -449,6 +449,13 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
case Matcher::EmitMergeInputChains: {
const EmitMergeInputChainsMatcher *MN =
cast<EmitMergeInputChainsMatcher>(N);
+
+ // Handle the specialized forms OPC_EmitMergeInputChains1_0 and 1_1.
+ if (MN->getNumNodes() == 1 && MN->getNode(0) < 2) {
+ OS << "OPC_EmitMergeInputChains1_" << MN->getNode(0) << ",\n";
+ return 1;
+ }
+
OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", ";
for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i)
OS << MN->getNode(i) << ", ";