Skip to content

Commit fb487f8

Browse files
committed
RequirementMachine: Factor out RewriteSystem::addRules() from RewriteSystem::initialize()
1 parent c25cd24 commit fb487f8

File tree

2 files changed

+76
-39
lines changed

2 files changed

+76
-39
lines changed

lib/AST/RequirementMachine/RewriteSystem.cpp

Lines changed: 72 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -82,45 +82,9 @@ void RewriteSystem::initialize(
8282
Protos = protos;
8383
WrittenRequirements = std::move(writtenRequirements);
8484

85-
// Pre-populate our rules vector with the list of imported rules, and note
86-
// the position of the first local (not imported) rule.
87-
Rules = std::move(importedRules);
88-
FirstLocalRule = Rules.size();
89-
90-
// Add the imported rules to the trie.
91-
for (unsigned newRuleID : indices(Rules)) {
92-
const auto &newRule = Rules[newRuleID];
93-
// Skip simplified rules. At the very least we need to skip RHS-simplified
94-
// rules since their left hand sides might duplicate existing rules; the
95-
// others are skipped purely as an optimization.
96-
if (newRule.isLHSSimplified() ||
97-
newRule.isRHSSimplified() ||
98-
newRule.isSubstitutionSimplified())
99-
continue;
100-
101-
auto oldRuleID = Trie.insert(newRule.getLHS().begin(),
102-
newRule.getLHS().end(),
103-
newRuleID);
104-
if (oldRuleID) {
105-
llvm::errs() << "Imported rules have duplicate left hand sides!\n";
106-
llvm::errs() << "New rule #" << newRuleID << ": " << newRule << "\n";
107-
const auto &oldRule = getRule(*oldRuleID);
108-
llvm::errs() << "Old rule #" << *oldRuleID << ": " << oldRule << "\n\n";
109-
dump(llvm::errs());
110-
abort();
111-
}
112-
}
113-
114-
// Now add our own rules.
115-
for (const auto &rule : permanentRules)
116-
addPermanentRule(rule.first, rule.second);
117-
118-
for (const auto &rule : requirementRules) {
119-
auto lhs = std::get<0>(rule);
120-
auto rhs = std::get<1>(rule);
121-
auto requirementID = std::get<2>(rule);
122-
addExplicitRule(lhs, rhs, requirementID);
123-
}
85+
addRules(std::move(importedRules),
86+
std::move(permanentRules),
87+
std::move(requirementRules));
12488
}
12589

12690
/// Reduce a term by applying all rewrite rules until fixed point.
@@ -330,6 +294,75 @@ bool RewriteSystem::addExplicitRule(MutableTerm lhs, MutableTerm rhs,
330294
return added;
331295
}
332296

297+
/// Add a set of rules from a RuleBuilder.
298+
///
299+
/// This is used when building a rewrite system in initialize() above.
300+
///
301+
/// It is also used when conditional requirement inference pulls in additional
302+
/// protocols after the fact.
303+
void RewriteSystem::addRules(
304+
std::vector<Rule> &&importedRules,
305+
std::vector<std::pair<MutableTerm, MutableTerm>> &&permanentRules,
306+
std::vector<std::tuple<MutableTerm, MutableTerm, Optional<unsigned>>> &&requirementRules) {
307+
unsigned ruleCount = Rules.size();
308+
309+
if (ruleCount == 0) {
310+
// Fast path if this is called from initialization; just steal the
311+
// underlying storage of the imported rule vector.
312+
Rules = std::move(importedRules);
313+
}
314+
else {
315+
// Otherwise, copy the imported rules in.
316+
Rules.insert(Rules.end(), importedRules.begin(), importedRules.end());
317+
}
318+
319+
// If this is the initial call, note the first non-imported rule so that
320+
// we can skip over imported rules later.
321+
if (ruleCount == 0)
322+
FirstLocalRule = Rules.size();
323+
324+
// Add the imported rules to the trie.
325+
for (unsigned newRuleID = ruleCount, e = Rules.size();
326+
newRuleID < e; ++newRuleID) {
327+
const auto &newRule = Rules[newRuleID];
328+
// Skip simplified rules. At the very least we need to skip RHS-simplified
329+
// rules since their left hand sides might duplicate existing rules; the
330+
// others are skipped purely as an optimization.
331+
if (newRule.isLHSSimplified() ||
332+
newRule.isRHSSimplified() ||
333+
newRule.isSubstitutionSimplified())
334+
continue;
335+
336+
auto oldRuleID = Trie.insert(newRule.getLHS().begin(),
337+
newRule.getLHS().end(),
338+
newRuleID);
339+
if (oldRuleID) {
340+
llvm::errs() << "Imported rules have duplicate left hand sides!\n";
341+
llvm::errs() << "New rule #" << newRuleID << ": " << newRule << "\n";
342+
const auto &oldRule = getRule(*oldRuleID);
343+
llvm::errs() << "Old rule #" << *oldRuleID << ": " << oldRule << "\n\n";
344+
dump(llvm::errs());
345+
abort();
346+
}
347+
}
348+
349+
// Now add our own rules.
350+
for (const auto &rule : permanentRules)
351+
addPermanentRule(rule.first, rule.second);
352+
353+
for (const auto &rule : requirementRules) {
354+
auto lhs = std::get<0>(rule);
355+
auto rhs = std::get<1>(rule);
356+
auto requirementID = std::get<2>(rule);
357+
358+
// When this is called while adding conditional requirements, there
359+
// shouldn't be any new structural requirement IDs.
360+
assert(ruleCount == 0 || !requirementID.hasValue());
361+
362+
addExplicitRule(lhs, rhs, requirementID);
363+
}
364+
}
365+
333366
/// Delete any rules whose left hand sides can be reduced by other rules.
334367
///
335368
/// Must be run after the completion procedure, since the deletion of

lib/AST/RequirementMachine/RewriteSystem.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ class RewriteSystem final {
173173
bool addExplicitRule(MutableTerm lhs, MutableTerm rhs,
174174
Optional<unsigned> requirementID);
175175

176+
void addRules(std::vector<Rule> &&importedRules,
177+
std::vector<std::pair<MutableTerm, MutableTerm>> &&permanentRules,
178+
std::vector<std::tuple<MutableTerm, MutableTerm, Optional<unsigned>>> &&requirementRules);
179+
176180
bool simplify(MutableTerm &term, RewritePath *path=nullptr) const;
177181

178182
Optional<unsigned>

0 commit comments

Comments
 (0)