@@ -52,9 +52,8 @@ class MatcherTableEmitter {
5252
5353 SmallVector<unsigned , Matcher::HighestKind+1 > OpcodeCounts;
5454
55- DenseMap<TreePattern *, unsigned > NodePredicateMap;
56- std::vector<TreePredicateFn> NodePredicates;
57- std::vector<TreePredicateFn> NodePredicatesWithOperands;
55+ std::vector<TreePattern *> NodePredicates;
56+ std::vector<TreePattern *> NodePredicatesWithOperands;
5857
5958 // We de-duplicate the predicates by code string, and use this map to track
6059 // all the patterns with "identical" predicates.
@@ -88,6 +87,8 @@ class MatcherTableEmitter {
8887 DenseMap<const ComplexPattern *, unsigned > ComplexPatternUsage;
8988 // Record the usage of PatternPredicate.
9089 std::map<StringRef, unsigned > PatternPredicateUsage;
90+ // Record the usage of Predicate.
91+ DenseMap<TreePattern *, unsigned > PredicateUsage;
9192
9293 // Iterate the whole MatcherTable once and do some statistics.
9394 std::function<void (const Matcher *)> Statistic = [&](const Matcher *N) {
@@ -105,6 +106,8 @@ class MatcherTableEmitter {
105106 ++ComplexPatternUsage[&CPM->getPattern ()];
106107 else if (auto *CPPM = dyn_cast<CheckPatternPredicateMatcher>(N))
107108 ++PatternPredicateUsage[CPPM->getPredicate ()];
109+ else if (auto *PM = dyn_cast<CheckPredicateMatcher>(N))
110+ ++PredicateUsage[PM->getPredicate ().getOrigPatFragRecord ()];
108111 N = N->getNext ();
109112 }
110113 };
@@ -125,6 +128,39 @@ class MatcherTableEmitter {
125128 [](const auto &A, const auto &B) { return A.second > B.second ; });
126129 for (const auto &PatternPredicate : PatternPredicateList)
127130 PatternPredicates.push_back (PatternPredicate.first );
131+
132+ // Sort Predicates by usage.
133+ // Merge predicates with same code.
134+ for (const auto &Usage : PredicateUsage) {
135+ TreePattern *TP = Usage.first ;
136+ TreePredicateFn Pred (TP);
137+ NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode ()].push_back (TP);
138+ }
139+
140+ std::vector<std::pair<TreePattern *, unsigned >> PredicateList;
141+ // Sum the usage.
142+ for (auto &Predicate : NodePredicatesByCodeToRun) {
143+ TinyPtrVector<TreePattern *> &TPs = Predicate.second ;
144+ sort (TPs, [](const auto *A, const auto *B) {
145+ return A->getRecord ()->getName () < B->getRecord ()->getName ();
146+ });
147+ unsigned Uses = 0 ;
148+ for (TreePattern *TP : TPs)
149+ Uses += PredicateUsage.at (TP);
150+
151+ // We only add the first predicate here since they are with the same code.
152+ PredicateList.push_back ({TPs[0 ], Uses});
153+ }
154+
155+ sort (PredicateList,
156+ [](const auto &A, const auto &B) { return A.second > B.second ; });
157+ for (const auto &Predicate : PredicateList) {
158+ TreePattern *TP = Predicate.first ;
159+ if (TreePredicateFn (TP).usesOperands ())
160+ NodePredicatesWithOperands.push_back (TP);
161+ else
162+ NodePredicates.push_back (TP);
163+ }
128164 }
129165
130166 unsigned EmitMatcherList (const Matcher *N, const unsigned Indent,
@@ -139,7 +175,7 @@ class MatcherTableEmitter {
139175 void EmitPatternMatchTable (raw_ostream &OS);
140176
141177private:
142- void EmitNodePredicatesFunction (const std::vector<TreePredicateFn > &Preds,
178+ void EmitNodePredicatesFunction (const std::vector<TreePattern * > &Preds,
143179 StringRef Decl, raw_ostream &OS);
144180
145181 unsigned SizeMatcher (Matcher *N, raw_ostream &OS);
@@ -148,33 +184,13 @@ class MatcherTableEmitter {
148184 raw_ostream &OS);
149185
150186 unsigned getNodePredicate (TreePredicateFn Pred) {
151- TreePattern *TP = Pred.getOrigPatFragRecord ();
152- unsigned &Entry = NodePredicateMap[TP];
153- if (Entry == 0 ) {
154- TinyPtrVector<TreePattern *> &SameCodePreds =
155- NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode ()];
156- if (SameCodePreds.empty ()) {
157- // We've never seen a predicate with the same code: allocate an entry.
158- if (Pred.usesOperands ()) {
159- NodePredicatesWithOperands.push_back (Pred);
160- Entry = NodePredicatesWithOperands.size ();
161- } else {
162- NodePredicates.push_back (Pred);
163- Entry = NodePredicates.size ();
164- }
165- } else {
166- // We did see an identical predicate: re-use it.
167- Entry = NodePredicateMap[SameCodePreds.front ()];
168- assert (Entry != 0 );
169- assert (TreePredicateFn (SameCodePreds.front ()).usesOperands () ==
170- Pred.usesOperands () &&
171- " PatFrags with some code must have same usesOperands setting" );
172- }
173- // In both cases, we've never seen this particular predicate before, so
174- // mark it in the list of predicates sharing the same code.
175- SameCodePreds.push_back (TP);
176- }
177- return Entry-1 ;
187+ // We use the first predicate.
188+ TreePattern *PredPat =
189+ NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode ()][0 ];
190+ return Pred.usesOperands ()
191+ ? llvm::find (NodePredicatesWithOperands, PredPat) -
192+ NodePredicatesWithOperands.begin ()
193+ : llvm::find (NodePredicates, PredPat) - NodePredicates.begin ();
178194 }
179195
180196 unsigned getPatternPredicate (StringRef PredName) {
@@ -529,6 +545,7 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
529545 case Matcher::CheckPredicate: {
530546 TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate ();
531547 unsigned OperandBytes = 0 ;
548+ unsigned PredNo = getNodePredicate (Pred);
532549
533550 if (Pred.usesOperands ()) {
534551 unsigned NumOps = cast<CheckPredicateMatcher>(N)->getNumOperands ();
@@ -537,10 +554,15 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
537554 OS << cast<CheckPredicateMatcher>(N)->getOperandNo (i) << " , " ;
538555 OperandBytes = 1 + NumOps;
539556 } else {
540- OS << " OPC_CheckPredicate, " ;
557+ if (PredNo < 8 ) {
558+ OperandBytes = -1 ;
559+ OS << " OPC_CheckPredicate" << PredNo << " , " ;
560+ } else
561+ OS << " OPC_CheckPredicate, " ;
541562 }
542563
543- OS << getNodePredicate (Pred) << ' ,' ;
564+ if (PredNo >= 8 || Pred.usesOperands ())
565+ OS << PredNo << ' ,' ;
544566 if (!OmitComments)
545567 OS << " // " << Pred.getFnName ();
546568 OS << ' \n ' ;
@@ -1029,8 +1051,7 @@ EmitMatcherList(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
10291051}
10301052
10311053void MatcherTableEmitter::EmitNodePredicatesFunction (
1032- const std::vector<TreePredicateFn> &Preds, StringRef Decl,
1033- raw_ostream &OS) {
1054+ const std::vector<TreePattern *> &Preds, StringRef Decl, raw_ostream &OS) {
10341055 if (Preds.empty ())
10351056 return ;
10361057
@@ -1040,7 +1061,7 @@ void MatcherTableEmitter::EmitNodePredicatesFunction(
10401061 OS << " default: llvm_unreachable(\" Invalid predicate in table?\" );\n " ;
10411062 for (unsigned i = 0 , e = Preds.size (); i != e; ++i) {
10421063 // Emit the predicate code corresponding to this pattern.
1043- const TreePredicateFn PredFn = Preds[i];
1064+ TreePredicateFn PredFn ( Preds[i]) ;
10441065 assert (!PredFn.isAlwaysTrue () && " No code in this predicate" );
10451066 std::string PredFnCodeStr = PredFn.getCodeToRunOnSDNode ();
10461067
0 commit comments