Skip to content

Commit 0766c1c

Browse files
committed
RequirementMachine: Use a trie to speed up merged associated types pass
1 parent af05377 commit 0766c1c

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

lib/AST/RequirementMachine/RewriteSystemCompletion.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ void RewriteSystem::processMergedAssociatedTypes() {
199199
const auto &lhs = pair.first;
200200
const auto &rhs = pair.second;
201201

202-
// If we have X.[P1:T] => Y.[P2:T], add a new pair of rules:
202+
// If we have X.[P2:T] => Y.[P1:T], add a new pair of rules:
203203
// X.[P1:T] => X.[P1&P2:T]
204204
// X.[P2:T] => X.[P1&P2:T]
205205
if (DebugMerge) {
@@ -216,18 +216,19 @@ void RewriteSystem::processMergedAssociatedTypes() {
216216
MutableTerm mergedTerm = lhs;
217217
mergedTerm.back() = mergedSymbol;
218218

219-
// Add the rule X.[P1:T] => X.[P1&P2:T].
220-
addRule(lhs, mergedTerm);
221-
222219
// Add the rule X.[P1:T] => X.[P1&P2:T].
223220
addRule(rhs, mergedTerm);
224221

225-
// Collect new rules here so that we're not adding rules while iterating
226-
// over the rules list.
222+
// Add the rule X.[P2:T] => X.[P1&P2:T].
223+
addRule(lhs, mergedTerm);
224+
225+
// Collect new rules here so that we're not adding rules while traversing
226+
// the trie.
227227
SmallVector<std::pair<MutableTerm, MutableTerm>, 2> inducedRules;
228228

229229
// Look for conformance requirements on [P1:T] and [P2:T].
230-
for (const auto &otherRule : Rules) {
230+
auto visitRule = [&](unsigned ruleID) {
231+
const auto &otherRule = Rules[ruleID];
231232
const auto &otherLHS = otherRule.getLHS();
232233
if (otherLHS.size() == 2 &&
233234
otherLHS[1].getKind() == Symbol::Kind::Protocol) {
@@ -260,7 +261,13 @@ void RewriteSystem::processMergedAssociatedTypes() {
260261
inducedRules.emplace_back(newLHS, newRHS);
261262
}
262263
}
263-
}
264+
};
265+
266+
// Visit rhs first to preserve the ordering of protocol requirements in the
267+
// the property map. This is just for aesthetic purposes in the debug dump,
268+
// it doesn't change behavior.
269+
Trie.findAll(rhs.back(), visitRule);
270+
Trie.findAll(lhs.back(), visitRule);
264271

265272
// Now add the new rules.
266273
for (const auto &pair : inducedRules)

lib/AST/RequirementMachine/Trie.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,25 @@ class Trie {
136136
}
137137
}
138138

139+
/// Find all keys that begin with the given symbol. Fn must take a single
140+
/// argument of type ValueType.
141+
template<typename Fn>
142+
void findAll(Symbol symbol, Fn fn) {
143+
auto found = Root.Entries.find(symbol);
144+
if (found == Root.Entries.end())
145+
return;
146+
147+
const auto &entry = found->second;
148+
149+
if (entry.Value)
150+
fn(*entry.Value);
151+
152+
if (entry.Children == nullptr)
153+
return;
154+
155+
visitChildren(entry.Children, fn);
156+
}
157+
139158
/// Find all keys that either match a prefix of [begin,end), or where
140159
/// [begin,end) matches a prefix of the key. Fn must take a single
141160
/// argument of type ValueType.

0 commit comments

Comments
 (0)