aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp10
-rw-r--r--utils/TableGen/DAGISelMatcher.h22
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp14
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp93
4 files changed, 99 insertions, 40 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index c1d159a..44f9918 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2249,11 +2249,15 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
N.getNode()))
break;
continue;
- case OPC_CheckComplexPat:
- if (!CheckComplexPattern(NodeToMatch, N,
- MatcherTable[MatcherIndex++], RecordedNodes))
+ case OPC_CheckComplexPat: {
+ unsigned CPNum = MatcherTable[MatcherIndex++];
+ unsigned RecNo = MatcherTable[MatcherIndex++];
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckComplexPat");
+ if (!CheckComplexPattern(NodeToMatch, RecordedNodes[RecNo], CPNum,
+ RecordedNodes))
break;
continue;
+ }
case OPC_CheckOpcode:
if (!::CheckOpcode(MatcherTable, MatcherIndex, N.getNode())) break;
continue;
diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h
index 8498d60..7955c7e 100644
--- a/utils/TableGen/DAGISelMatcher.h
+++ b/utils/TableGen/DAGISelMatcher.h
@@ -609,14 +609,27 @@ private:
/// the current node.
class CheckComplexPatMatcher : public Matcher {
const ComplexPattern &Pattern;
+
+ /// MatchNumber - This is the recorded nodes slot that contains the node we want to
+ /// match against.
+ unsigned MatchNumber;
+
+ /// Name - The name of the node we're matching, for comment emission.
+ std::string Name;
+
/// FirstResult - This is the first slot in the RecordedNodes list that the
/// result of the match populates.
unsigned FirstResult;
public:
- CheckComplexPatMatcher(const ComplexPattern &pattern, unsigned firstresult)
- : Matcher(CheckComplexPat), Pattern(pattern), FirstResult(firstresult) {}
+ CheckComplexPatMatcher(const ComplexPattern &pattern, unsigned matchnumber,
+ const std::string &name, unsigned firstresult)
+ : Matcher(CheckComplexPat), Pattern(pattern), MatchNumber(matchnumber),
+ Name(name), FirstResult(firstresult) {}
const ComplexPattern &getPattern() const { return Pattern; }
+ unsigned getMatchNumber() const { return MatchNumber; }
+
+ const std::string getName() const { return Name; }
unsigned getFirstResult() const { return FirstResult; }
static inline bool classof(const Matcher *N) {
@@ -629,10 +642,11 @@ public:
private:
virtual void printImpl(raw_ostream &OS, unsigned indent) const;
virtual bool isEqualImpl(const Matcher *M) const {
- return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern;
+ return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern &&
+ cast<CheckComplexPatMatcher>(M)->MatchNumber == MatchNumber;
}
virtual unsigned getHashImpl() const {
- return (unsigned)(intptr_t)&Pattern;
+ return (unsigned)(intptr_t)&Pattern ^ MatchNumber;
}
};
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
index 1f9e093..63c854b 100644
--- a/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -370,20 +370,22 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
return 2;
case Matcher::CheckComplexPat: {
- const ComplexPattern &Pattern =
- cast<CheckComplexPatMatcher>(N)->getPattern();
- OS << "OPC_CheckComplexPat, " << getComplexPat(Pattern) << ',';
+ const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N);
+ const ComplexPattern &Pattern = CCPM->getPattern();
+ OS << "OPC_CheckComplexPat, /*CP*/" << getComplexPat(Pattern) << ", /*#*/"
+ << CCPM->getMatchNumber() << ',';
+
if (!OmitComments) {
OS.PadToColumn(CommentIndent) << "// " << Pattern.getSelectFunc();
- OS << ':';
+ OS << ":$" << CCPM->getName();
for (unsigned i = 0, e = Pattern.getNumOperands(); i != e; ++i)
- OS << " #" << cast<CheckComplexPatMatcher>(N)->getFirstResult()+i;
+ OS << " #" << CCPM->getFirstResult()+i;
if (Pattern.hasProperty(SDNPHasChain))
OS << " + chain result";
}
OS << '\n';
- return 2;
+ return 3;
}
case Matcher::CheckAndImm: {
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index f4e2b8d..433da18 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -72,6 +72,14 @@ namespace {
/// nodes array of all of the recorded input nodes that have flag results.
SmallVector<unsigned, 2> MatchedFlagResultNodes;
+ /// MatchedComplexPatterns - This maintains a list of all of the
+ /// ComplexPatterns that we need to check. The patterns are known to have
+ /// names which were recorded. The second element of each pair is the first
+ /// slot number that the OPC_CheckComplexPat opcode drops the matched
+ /// results into.
+ SmallVector<std::pair<const TreePatternNode*,
+ unsigned>, 2> MatchedComplexPatterns;
+
/// PhysRegInputs - List list has an entry for each explicitly specified
/// physreg input to the pattern. The first elt is the Register node, the
/// second is the recorded slot number the input pattern match saved it in.
@@ -247,30 +255,9 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
exit(1);
}
- // Handle complex pattern.
- const ComplexPattern &CP = CGP.getComplexPattern(LeafRec);
-
- // Emit a CheckComplexPat operation, which does the match (aborting if it
- // fails) and pushes the matched operands onto the recorded nodes list.
- AddMatcher(new CheckComplexPatMatcher(CP, NextRecordedOperandNo));
-
- // Record the right number of operands.
- NextRecordedOperandNo += CP.getNumOperands();
- if (CP.hasProperty(SDNPHasChain))
- ++NextRecordedOperandNo; // Chained node operand.
-
- // If the complex pattern has a chain, then we need to keep track of the
- // fact that we just recorded a chain input. The chain input will be
- // matched as the last operand of the predicate if it was successful.
- if (CP.hasProperty(SDNPHasChain)) {
- // It is the last operand recorded.
- assert(NextRecordedOperandNo > 1 &&
- "Should have recorded input/result chains at least!");
- MatchedChainNodes.push_back(NextRecordedOperandNo-1);
- }
-
- // TODO: Complex patterns can't have output flags, if they did, we'd want
- // to record them.
+ // Remember this ComplexPattern so that we can emit it after all the other
+ // structural matches are done.
+ MatchedComplexPatterns.push_back(std::make_pair(N, 0));
return;
}
@@ -495,6 +482,50 @@ bool MatcherGen::EmitMatcherCode(unsigned Variant) {
// Emit the matcher for the pattern structure and types.
EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes);
+
+ // Now that we've completed the structural type match, emit any ComplexPattern
+ // checks (e.g. addrmode matches). We emit this after the structural match
+ // because they are generally more expensive to evaluate and more difficult to
+ // factor.
+ // FIXME2: Can the patternpredicatematcher be moved to right before this??
+ for (unsigned i = 0, e = MatchedComplexPatterns.size(); i != e; ++i) {
+ const TreePatternNode *N = MatchedComplexPatterns[i].first;
+
+ // Remember where the results of this match get stuck.
+ MatchedComplexPatterns[i].second = NextRecordedOperandNo;
+
+ // Get the slot we recorded the value in from the name on the node.
+ unsigned RecNodeEntry = VariableMap[N->getName()];
+ assert(!N->getName().empty() && RecNodeEntry &&
+ "Complex pattern should have a name and slot");
+ --RecNodeEntry; // Entries in VariableMap are biased.
+
+ const ComplexPattern &CP =
+ CGP.getComplexPattern(((DefInit*)N->getLeafValue())->getDef());
+
+ // Emit a CheckComplexPat operation, which does the match (aborting if it
+ // fails) and pushes the matched operands onto the recorded nodes list.
+ AddMatcher(new CheckComplexPatMatcher(CP, RecNodeEntry,
+ N->getName(), NextRecordedOperandNo));
+
+ // Record the right number of operands.
+ NextRecordedOperandNo += CP.getNumOperands();
+ if (CP.hasProperty(SDNPHasChain)) {
+ // If the complex pattern has a chain, then we need to keep track of the
+ // fact that we just recorded a chain input. The chain input will be
+ // matched as the last operand of the predicate if it was successful.
+ ++NextRecordedOperandNo; // Chained node operand.
+
+ // It is the last operand recorded.
+ assert(NextRecordedOperandNo > 1 &&
+ "Should have recorded input/result chains at least!");
+ MatchedChainNodes.push_back(NextRecordedOperandNo-1);
+ }
+
+ // TODO: Complex patterns can't have output flags, if they did, we'd want
+ // to record them.
+ }
+
return false;
}
@@ -507,18 +538,26 @@ void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps){
assert(!N->getName().empty() && "Operand not named!");
- unsigned SlotNo = getNamedArgumentSlot(N->getName());
-
// A reference to a complex pattern gets all of the results of the complex
// pattern's match.
if (const ComplexPattern *CP = N->getComplexPatternInfo(CGP)) {
+ unsigned SlotNo = 0;
+ for (unsigned i = 0, e = MatchedComplexPatterns.size(); i != e; ++i)
+ if (MatchedComplexPatterns[i].first->getName() == N->getName()) {
+ SlotNo = MatchedComplexPatterns[i].second;
+ break;
+ }
+ assert(SlotNo != 0 && "Didn't get a slot number assigned?");
+
// The first slot entry is the node itself, the subsequent entries are the
// matched values.
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
- ResultOps.push_back(SlotNo+i+1);
+ ResultOps.push_back(SlotNo+i);
return;
}
+ unsigned SlotNo = getNamedArgumentSlot(N->getName());
+
// If this is an 'imm' or 'fpimm' node, make sure to convert it to the target
// version of the immediate so that it doesn't get selected due to some other
// node use.