@@ -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.
@@ -88,6 +87,8 @@ class MatcherTableEmitter {
88
87
DenseMap<const ComplexPattern *, unsigned > ComplexPatternUsage;
89
88
// Record the usage of PatternPredicate.
90
89
std::map<StringRef, unsigned > PatternPredicateUsage;
90
+ // Record the usage of Predicate.
91
+ DenseMap<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
};
@@ -125,6 +128,39 @@ class MatcherTableEmitter {
125
128
[](const auto &A, const auto &B) { return A.second > B.second ; });
126
129
for (const auto &PatternPredicate : PatternPredicateList)
127
130
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
+ }
128
164
}
129
165
130
166
unsigned EmitMatcherList (const Matcher *N, const unsigned Indent,
@@ -139,7 +175,7 @@ class MatcherTableEmitter {
139
175
void EmitPatternMatchTable (raw_ostream &OS);
140
176
141
177
private:
142
- void EmitNodePredicatesFunction (const std::vector<TreePredicateFn > &Preds,
178
+ void EmitNodePredicatesFunction (const std::vector<TreePattern * > &Preds,
143
179
StringRef Decl, raw_ostream &OS);
144
180
145
181
unsigned SizeMatcher (Matcher *N, raw_ostream &OS);
@@ -148,33 +184,13 @@ class MatcherTableEmitter {
148
184
raw_ostream &OS);
149
185
150
186
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 ();
178
194
}
179
195
180
196
unsigned getPatternPredicate (StringRef PredName) {
@@ -529,6 +545,7 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
529
545
case Matcher::CheckPredicate: {
530
546
TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate ();
531
547
unsigned OperandBytes = 0 ;
548
+ unsigned PredNo = getNodePredicate (Pred);
532
549
533
550
if (Pred.usesOperands ()) {
534
551
unsigned NumOps = cast<CheckPredicateMatcher>(N)->getNumOperands ();
@@ -537,10 +554,15 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
537
554
OS << cast<CheckPredicateMatcher>(N)->getOperandNo (i) << " , " ;
538
555
OperandBytes = 1 + NumOps;
539
556
} else {
540
- OS << " OPC_CheckPredicate, " ;
557
+ if (PredNo < 8 ) {
558
+ OperandBytes = -1 ;
559
+ OS << " OPC_CheckPredicate" << PredNo << " , " ;
560
+ } else
561
+ OS << " OPC_CheckPredicate, " ;
541
562
}
542
563
543
- OS << getNodePredicate (Pred) << ' ,' ;
564
+ if (PredNo >= 8 || Pred.usesOperands ())
565
+ OS << PredNo << ' ,' ;
544
566
if (!OmitComments)
545
567
OS << " // " << Pred.getFnName ();
546
568
OS << ' \n ' ;
@@ -1029,8 +1051,7 @@ EmitMatcherList(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
1029
1051
}
1030
1052
1031
1053
void 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) {
1034
1055
if (Preds.empty ())
1035
1056
return ;
1036
1057
@@ -1040,7 +1061,7 @@ void MatcherTableEmitter::EmitNodePredicatesFunction(
1040
1061
OS << " default: llvm_unreachable(\" Invalid predicate in table?\" );\n " ;
1041
1062
for (unsigned i = 0 , e = Preds.size (); i != e; ++i) {
1042
1063
// Emit the predicate code corresponding to this pattern.
1043
- const TreePredicateFn PredFn = Preds[i];
1064
+ TreePredicateFn PredFn ( Preds[i]) ;
1044
1065
assert (!PredFn.isAlwaysTrue () && " No code in this predicate" );
1045
1066
std::string PredFnCodeStr = PredFn.getCodeToRunOnSDNode ();
1046
1067
0 commit comments