From 57bf8a483edf97589c3e6085721e72fc187677a8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 4 Mar 2010 01:23:08 +0000 Subject: [PATCH] change the new isel matcher to emit ComplexPattern matches as the very last thing before node emission. This should dramatically reduce the number of times we do 'MatchAddress' on X86, speeding up compile time. This also improves comments in the tables and shrinks the table a bit, now down to 80506 bytes for x86. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97703 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 10 +- utils/TableGen/DAGISelMatcher.h | 22 ++++- utils/TableGen/DAGISelMatcherEmitter.cpp | 14 +-- utils/TableGen/DAGISelMatcherGen.cpp | 93 +++++++++++++------ 4 files changed, 99 insertions(+), 40 deletions(-) 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.