@@ -82,45 +82,9 @@ void RewriteSystem::initialize(
82
82
Protos = protos;
83
83
WrittenRequirements = std::move (writtenRequirements);
84
84
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));
124
88
}
125
89
126
90
// / Reduce a term by applying all rewrite rules until fixed point.
@@ -330,6 +294,75 @@ bool RewriteSystem::addExplicitRule(MutableTerm lhs, MutableTerm rhs,
330
294
return added;
331
295
}
332
296
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
+
333
366
// / Delete any rules whose left hand sides can be reduced by other rules.
334
367
// /
335
368
// / Must be run after the completion procedure, since the deletion of
0 commit comments