diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index c1d159af63a..44f99181dea 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 8498d60b5d1..7955c7e2630 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(M)->Pattern == &Pattern; + return &cast(M)->Pattern == &Pattern && + cast(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 1f9e09383f2..63c854b748e 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(N)->getPattern(); - OS << "OPC_CheckComplexPat, " << getComplexPat(Pattern) << ','; + const CheckComplexPatMatcher *CCPM = cast(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(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 f4e2b8d884e..433da18cecb 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 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, 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 &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.