@@ -52,9 +52,8 @@ class MatcherTableEmitter {
52
52
53
53
SmallVector<unsigned , Matcher::HighestKind+1 > OpcodeCounts;
54
54
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;
58
57
59
58
// We de-duplicate the predicates by code string, and use this map to track
60
59
// all the patterns with "identical" predicates.
@@ -87,7 +86,9 @@ class MatcherTableEmitter {
87
86
// Record the usage of ComplexPattern.
88
87
MapVector<const ComplexPattern *, unsigned > ComplexPatternUsage;
89
88
// Record the usage of PatternPredicate.
90
- std::map<StringRef, unsigned > PatternPredicateUsage;
89
+ MapVector<StringRef, unsigned > PatternPredicateUsage;
90
+ // Record the usage of Predicate.
91
+ MapVector<TreePattern *, unsigned > PredicateUsage;
91
92
92
93
// Iterate the whole MatcherTable once and do some statistics.
93
94
std::function<void (const Matcher *)> Statistic = [&](const Matcher *N) {
@@ -105,6 +106,8 @@ class MatcherTableEmitter {
105
106
++ComplexPatternUsage[&CPM->getPattern ()];
106
107
else if (auto *CPPM = dyn_cast<CheckPatternPredicateMatcher>(N))
107
108
++PatternPredicateUsage[CPPM->getPredicate ()];
109
+ else if (auto *PM = dyn_cast<CheckPredicateMatcher>(N))
110
+ ++PredicateUsage[PM->getPredicate ().getOrigPatFragRecord ()];
108
111
N = N->getNext ();
109
112
}
110
113
};
@@ -127,6 +130,40 @@ class MatcherTableEmitter {
127
130
});
128
131
for (const auto &PatternPredicate : PatternPredicateList)
129
132
PatternPredicates.push_back (PatternPredicate.first );
133
+
134
+ // Sort Predicates by usage.
135
+ // Merge predicates with same code.
136
+ for (const auto &Usage : PredicateUsage) {
137
+ TreePattern *TP = Usage.first ;
138
+ TreePredicateFn Pred (TP);
139
+ NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode ()].push_back (TP);
140
+ }
141
+
142
+ std::vector<std::pair<TreePattern *, unsigned >> PredicateList;
143
+ // Sum the usage.
144
+ for (auto &Predicate : NodePredicatesByCodeToRun) {
145
+ TinyPtrVector<TreePattern *> &TPs = Predicate.second ;
146
+ stable_sort (TPs, [](const auto *A, const auto *B) {
147
+ return A->getRecord ()->getName () < B->getRecord ()->getName ();
148
+ });
149
+ unsigned Uses = 0 ;
150
+ for (TreePattern *TP : TPs)
151
+ Uses += PredicateUsage[TP];
152
+
153
+ // We only add the first predicate here since they are with the same code.
154
+ PredicateList.push_back ({TPs[0 ], Uses});
155
+ }
156
+
157
+ stable_sort (PredicateList, [](const auto &A, const auto &B) {
158
+ return A.second > B.second ;
159
+ });
160
+ for (const auto &Predicate : PredicateList) {
161
+ TreePattern *TP = Predicate.first ;
162
+ if (TreePredicateFn (TP).usesOperands ())
163
+ NodePredicatesWithOperands.push_back (TP);
164
+ else
165
+ NodePredicates.push_back (TP);
166
+ }
130
167
}
131
168
132
169
unsigned EmitMatcherList (const Matcher *N, const unsigned Indent,
@@ -141,7 +178,7 @@ class MatcherTableEmitter {
141
178
void EmitPatternMatchTable (raw_ostream &OS);
142
179
143
180
private:
144
- void EmitNodePredicatesFunction (const std::vector<TreePredicateFn > &Preds,
181
+ void EmitNodePredicatesFunction (const std::vector<TreePattern * > &Preds,
145
182
StringRef Decl, raw_ostream &OS);
146
183
147
184
unsigned SizeMatcher (Matcher *N, raw_ostream &OS);
@@ -150,33 +187,13 @@ class MatcherTableEmitter {
150
187
raw_ostream &OS);
151
188
152
189
unsigned getNodePredicate (TreePredicateFn Pred) {
153
- TreePattern *TP = Pred.getOrigPatFragRecord ();
154
- unsigned &Entry = NodePredicateMap[TP];
155
- if (Entry == 0 ) {
156
- TinyPtrVector<TreePattern *> &SameCodePreds =
157
- NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode ()];
158
- if (SameCodePreds.empty ()) {
159
- // We've never seen a predicate with the same code: allocate an entry.
160
- if (Pred.usesOperands ()) {
161
- NodePredicatesWithOperands.push_back (Pred);
162
- Entry = NodePredicatesWithOperands.size ();
163
- } else {
164
- NodePredicates.push_back (Pred);
165
- Entry = NodePredicates.size ();
166
- }
167
- } else {
168
- // We did see an identical predicate: re-use it.
169
- Entry = NodePredicateMap[SameCodePreds.front ()];
170
- assert (Entry != 0 );
171
- assert (TreePredicateFn (SameCodePreds.front ()).usesOperands () ==
172
- Pred.usesOperands () &&
173
- " PatFrags with some code must have same usesOperands setting" );
174
- }
175
- // In both cases, we've never seen this particular predicate before, so
176
- // mark it in the list of predicates sharing the same code.
177
- SameCodePreds.push_back (TP);
178
- }
179
- return Entry-1 ;
190
+ // We use the first predicate.
191
+ TreePattern *PredPat =
192
+ NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode ()][0 ];
193
+ return Pred.usesOperands ()
194
+ ? llvm::find (NodePredicatesWithOperands, PredPat) -
195
+ NodePredicatesWithOperands.begin ()
196
+ : llvm::find (NodePredicates, PredPat) - NodePredicates.begin ();
180
197
}
181
198
182
199
unsigned getPatternPredicate (StringRef PredName) {
@@ -531,6 +548,7 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
531
548
case Matcher::CheckPredicate: {
532
549
TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate ();
533
550
unsigned OperandBytes = 0 ;
551
+ unsigned PredNo = getNodePredicate (Pred);
534
552
535
553
if (Pred.usesOperands ()) {
536
554
unsigned NumOps = cast<CheckPredicateMatcher>(N)->getNumOperands ();
@@ -539,10 +557,15 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
539
557
OS << cast<CheckPredicateMatcher>(N)->getOperandNo (i) << " , " ;
540
558
OperandBytes = 1 + NumOps;
541
559
} else {
542
- OS << " OPC_CheckPredicate, " ;
560
+ if (PredNo < 8 ) {
561
+ OperandBytes = -1 ;
562
+ OS << " OPC_CheckPredicate" << PredNo << " , " ;
563
+ } else
564
+ OS << " OPC_CheckPredicate, " ;
543
565
}
544
566
545
- OS << getNodePredicate (Pred) << ' ,' ;
567
+ if (PredNo >= 8 || Pred.usesOperands ())
568
+ OS << PredNo << ' ,' ;
546
569
if (!OmitComments)
547
570
OS << " // " << Pred.getFnName ();
548
571
OS << ' \n ' ;
@@ -1031,8 +1054,7 @@ EmitMatcherList(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
1031
1054
}
1032
1055
1033
1056
void MatcherTableEmitter::EmitNodePredicatesFunction (
1034
- const std::vector<TreePredicateFn> &Preds, StringRef Decl,
1035
- raw_ostream &OS) {
1057
+ const std::vector<TreePattern *> &Preds, StringRef Decl, raw_ostream &OS) {
1036
1058
if (Preds.empty ())
1037
1059
return ;
1038
1060
@@ -1042,7 +1064,7 @@ void MatcherTableEmitter::EmitNodePredicatesFunction(
1042
1064
OS << " default: llvm_unreachable(\" Invalid predicate in table?\" );\n " ;
1043
1065
for (unsigned i = 0 , e = Preds.size (); i != e; ++i) {
1044
1066
// Emit the predicate code corresponding to this pattern.
1045
- const TreePredicateFn PredFn = Preds[i];
1067
+ TreePredicateFn PredFn ( Preds[i]) ;
1046
1068
assert (!PredFn.isAlwaysTrue () && " No code in this predicate" );
1047
1069
std::string PredFnCodeStr = PredFn.getCodeToRunOnSDNode ();
1048
1070
0 commit comments