@@ -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
0 commit comments