X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FDAGISelMatcherEmitter.cpp;h=26f53dca63618c65783b208d11d5739403334150;hb=HEAD;hp=1445edbe720a8d79f52d6addf3056d00bd098192;hpb=b8d17643a5d4fc62aa420760eea92d0afdf2e46a;p=oota-llvm.git diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp index 1445edbe720..26f53dca636 100644 --- a/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -13,12 +13,13 @@ #include "DAGISelMatcher.h" #include "CodeGenDAGPatterns.h" -#include "llvm/TableGen/Record.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/TableGen/Record.h" using namespace llvm; enum { @@ -36,6 +37,10 @@ class MatcherTableEmitter { DenseMap NodePredicateMap; std::vector NodePredicates; + + // We de-duplicate the predicates by code string, and use this map to track + // all the patterns with "identical" predicates. + StringMap> NodePredicatesByCodeToRun; StringMap PatternPredicateMap; std::vector PatternPredicates; @@ -62,10 +67,23 @@ private: formatted_raw_ostream &OS); unsigned getNodePredicate(TreePredicateFn Pred) { - unsigned &Entry = NodePredicateMap[Pred.getOrigPatFragRecord()]; + TreePattern *TP = Pred.getOrigPatFragRecord(); + unsigned &Entry = NodePredicateMap[TP]; if (Entry == 0) { - NodePredicates.push_back(Pred); - Entry = NodePredicates.size(); + TinyPtrVector &SameCodePreds = + NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()]; + if (SameCodePreds.empty()) { + // We've never seen a predicate with the same code: allocate an entry. + NodePredicates.push_back(Pred); + Entry = NodePredicates.size(); + } else { + // We did see an identical predicate: re-use it. + Entry = NodePredicateMap[SameCodePreds.front()]; + assert(Entry != 0); + } + // In both cases, we've never seen this particular predicate before, so + // mark it in the list of predicates sharing the same code. + SameCodePreds.push_back(TP); } return Entry-1; } @@ -132,7 +150,7 @@ static uint64_t EmitVBRValue(uint64_t Val, raw_ostream &OS) { return NumBytes+1; } -/// EmitMatcherOpcodes - Emit bytes for the specified matcher and return +/// EmitMatcher - Emit bytes for the specified matcher and return /// the number of bytes emitted. unsigned MatcherTableEmitter:: EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, @@ -142,7 +160,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, switch (N->getKind()) { case Matcher::Scope: { const ScopeMatcher *SM = cast(N); - assert(SM->getNext() == 0 && "Shouldn't have next after scope"); + assert(SM->getNext() == nullptr && "Shouldn't have next after scope"); unsigned StartIdx = CurrentIdx; @@ -188,7 +206,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, << " children in Scope"; } - OS << '\n' << TmpBuf.str(); + OS << '\n' << TmpBuf; CurrentIdx += ChildSize; } @@ -242,6 +260,12 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, << cast(N)->getMatchNumber() << ",\n"; return 2; + case Matcher::CheckChildSame: + OS << "OPC_CheckChild" + << cast(N)->getChildNo() << "Same, " + << cast(N)->getMatchNumber() << ",\n"; + return 2; + case Matcher::CheckPatternPredicate: { StringRef Pred =cast(N)->getPredicate(); OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ','; @@ -315,16 +339,17 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, assert(ChildSize != 0 && "Should not have a zero-sized child!"); if (i != 0) { + if (!OmitComments) + OS << "/*" << CurrentIdx << "*/"; OS.PadToColumn(Indent*2); if (!OmitComments) - OS << (isa(N) ? - "/*SwitchOpcode*/ " : "/*SwitchType*/ "); + OS << (isa(N) ? + "/*SwitchOpcode*/ " : "/*SwitchType*/ "); } // Emit the VBR. CurrentIdx += EmitVBRValue(ChildSize, OS); - OS << ' '; if (const SwitchOpcodeMatcher *SOM = dyn_cast(N)) OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),"; else @@ -335,11 +360,13 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, if (!OmitComments) OS << "// ->" << CurrentIdx+ChildSize; OS << '\n'; - OS << TmpBuf.str(); + OS << TmpBuf; CurrentIdx += ChildSize; } // Emit the final zero to terminate the switch. + if (!OmitComments) + OS << "/*" << CurrentIdx << "*/"; OS.PadToColumn(Indent*2) << "0, "; if (!OmitComments) OS << (isa(N) ? @@ -369,6 +396,14 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, OS << '\n'; return Bytes; } + case Matcher::CheckChildInteger: { + OS << "OPC_CheckChild" << cast(N)->getChildNo() + << "Integer, "; + unsigned Bytes=1+EmitVBRValue(cast(N)->getValue(), + OS); + OS << '\n'; + return Bytes; + } case Matcher::CheckCondCode: OS << "OPC_CheckCondCode, ISD::" << cast(N)->getCondCodeName() << ",\n"; @@ -598,7 +633,7 @@ EmitMatcherList(const Matcher *N, unsigned Indent, unsigned CurrentIdx, void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { // Emit pattern predicates. if (!PatternPredicates.empty()) { - OS << "bool CheckPatternPredicate(unsigned PredNo) const {\n"; + OS << "bool CheckPatternPredicate(unsigned PredNo) const override {\n"; OS << " switch (PredNo) {\n"; OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n"; for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i) @@ -608,15 +643,9 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { } // Emit Node predicates. - // FIXME: Annoyingly, these are stored by name, which we never even emit. Yay? - StringMap PFsByName; - - for (CodeGenDAGPatterns::pf_iterator I = CGP.pf_begin(), E = CGP.pf_end(); - I != E; ++I) - PFsByName[I->first->getName()] = I->second; - if (!NodePredicates.empty()) { - OS << "bool CheckNodePredicate(SDNode *Node, unsigned PredNo) const {\n"; + OS << "bool CheckNodePredicate(SDNode *Node,\n"; + OS << " unsigned PredNo) const override {\n"; OS << " switch (PredNo) {\n"; OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n"; for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) { @@ -624,7 +653,10 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { TreePredicateFn PredFn = NodePredicates[i]; assert(!PredFn.isAlwaysTrue() && "No code in this predicate"); - OS << " case " << i << ": { // " << NodePredicates[i].getFnName() <<'\n'; + OS << " case " << i << ": { \n"; + for (auto *SimilarPred : + NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()]) + OS << " // " << TreePredicateFn(SimilarPred).getFnName() <<'\n'; OS << PredFn.getCodeToRunOnSDNode() << "\n }\n"; } @@ -635,9 +667,9 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { // Emit CompletePattern matchers. // FIXME: This should be const. if (!ComplexPatterns.empty()) { - OS << "bool CheckComplexPattern(SDNode *Root, SDNode *Parent, SDValue N,\n"; - OS << " unsigned PatternNo,\n"; - OS << " SmallVectorImpl > &Result) {\n"; + OS << "bool CheckComplexPattern(SDNode *Root, SDNode *Parent,\n"; + OS << " SDValue N, unsigned PatternNo,\n"; + OS << " SmallVectorImpl > &Result) override {\n"; OS << " unsigned NextRes = Result.size();\n"; OS << " switch (PatternNo) {\n"; OS << " default: llvm_unreachable(\"Invalid pattern # in table?\");\n"; @@ -676,7 +708,7 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { // Emit SDNodeXForm handlers. // FIXME: This should be const. if (!NodeXForms.empty()) { - OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {\n"; + OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) override {\n"; OS << " switch (XFormNo) {\n"; OS << " default: llvm_unreachable(\"Invalid xform # in table?\");\n"; @@ -707,7 +739,7 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { } static void BuildHistogram(const Matcher *M, std::vector &OpcodeFreq){ - for (; M != 0; M = M->getNext()) { + for (; M != nullptr; M = M->getNext()) { // Count this node. if (unsigned(M->getKind()) >= OpcodeFreq.size()) OpcodeFreq.resize(M->getKind()+1); @@ -748,6 +780,7 @@ void MatcherTableEmitter::EmitHistogram(const Matcher *M, case Matcher::MoveChild: OS << "OPC_MoveChild"; break; case Matcher::MoveParent: OS << "OPC_MoveParent"; break; case Matcher::CheckSame: OS << "OPC_CheckSame"; break; + case Matcher::CheckChildSame: OS << "OPC_CheckChildSame"; break; case Matcher::CheckPatternPredicate: OS << "OPC_CheckPatternPredicate"; break; case Matcher::CheckPredicate: OS << "OPC_CheckPredicate"; break; @@ -757,6 +790,7 @@ void MatcherTableEmitter::EmitHistogram(const Matcher *M, case Matcher::SwitchType: OS << "OPC_SwitchType"; break; case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break; case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break; + case Matcher::CheckChildInteger: OS << "OPC_CheckChildInteger"; break; case Matcher::CheckCondCode: OS << "OPC_CheckCondCode"; break; case Matcher::CheckValueType: OS << "OPC_CheckValueType"; break; case Matcher::CheckComplexPat: OS << "OPC_CheckComplexPat"; break; @@ -797,7 +831,7 @@ void llvm::EmitMatcherTable(const Matcher *TheMatcher, OS << " // this.\n"; OS << " #define TARGET_VAL(X) X & 255, unsigned(X) >> 8\n"; OS << " static const unsigned char MatcherTable[] = {\n"; - unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 5, 0, OS); + unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 6, 0, OS); OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n"; MatcherEmitter.EmitHistogram(TheMatcher, OS);