Skip to content

Commit efae2bf

Browse files
committed
RequirementMachine: Completion depth limit
1 parent f69b883 commit efae2bf

File tree

3 files changed

+45
-9
lines changed

3 files changed

+45
-9
lines changed

include/swift/AST/RewriteSystem.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ class Rule final {
192192
deleted = true;
193193
}
194194

195+
unsigned getDepth() const {
196+
return LHS.size();
197+
}
198+
195199
void dump(llvm::raw_ostream &out) const;
196200
};
197201

@@ -212,7 +216,15 @@ class RewriteSystem final {
212216

213217
bool simplify(Term &term) const;
214218

215-
void computeConfluentCompletion(unsigned maxIterations);
219+
enum class CompletionResult {
220+
Success,
221+
MaxIterations,
222+
MaxDepth
223+
};
224+
225+
CompletionResult computeConfluentCompletion(
226+
unsigned maxIterations,
227+
unsigned maxDepth);
216228

217229
void dump(llvm::raw_ostream &out) const;
218230
};

lib/AST/RequirementMachine.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,10 @@ RequirementMachine::~RequirementMachine() {
338338
void RequirementMachine::addGenericSignature(CanGenericSignature sig) {
339339
PrettyStackTraceGenericSignature debugStack("building rewrite system for", sig);
340340

341+
auto *Stats = Context.Stats;
342+
343+
FrontendStatsTracer(Stats, "build-rewrite-system");
344+
341345
if (Context.LangOpts.DebugRequirementMachine) {
342346
llvm::dbgs() << "Adding generic signature " << sig << " {\n";
343347
}
@@ -351,7 +355,24 @@ void RequirementMachine::addGenericSignature(CanGenericSignature sig) {
351355
Impl->System.addRule(rule.first, rule.second);
352356

353357
// FIXME: Add command line flag
354-
Impl->System.computeConfluentCompletion(10000);
358+
auto result = Impl->System.computeConfluentCompletion(5000, 10);
359+
360+
switch (result) {
361+
case RewriteSystem::CompletionResult::Success:
362+
break;
363+
364+
case RewriteSystem::CompletionResult::MaxIterations:
365+
llvm::errs() << "Generic signature " << sig
366+
<< " exceeds maximum completion step count\n";
367+
break;
368+
// abort();
369+
370+
case RewriteSystem::CompletionResult::MaxDepth:
371+
llvm::errs() << "Generic signature " << sig
372+
<< " exceeds maximum completion depth\n";
373+
break;
374+
// abort();
375+
}
355376

356377
markComplete();
357378

lib/AST/RewriteSystem.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ bool RewriteSystem::simplify(Term &term) const {
246246
return changed;
247247
}
248248

249-
void RewriteSystem::computeConfluentCompletion(
250-
unsigned maxIterations) {
249+
RewriteSystem::CompletionResult
250+
RewriteSystem::computeConfluentCompletion(
251+
unsigned maxIterations,
252+
unsigned maxDepth) {
251253
SmallVector<std::pair<unsigned, unsigned>, 16> worklist;
252254

253255
for (unsigned i : indices(Rules)) {
@@ -286,15 +288,14 @@ void RewriteSystem::computeConfluentCompletion(
286288
if (!addRule(first, second))
287289
continue;
288290

289-
if (maxIterations == 0) {
290-
dump(llvm::errs());
291-
llvm::errs() << "Completion procedure exceeded max iteration count\n";
292-
abort();
293-
}
291+
if (maxIterations == 0)
292+
return CompletionResult::MaxIterations;
294293

295294
maxIterations--;
296295

297296
const auto &newRule = Rules[i];
297+
if (newRule.getDepth() > maxDepth)
298+
return CompletionResult::MaxDepth;
298299

299300
for (unsigned j : indices(Rules)) {
300301
if (i == j)
@@ -317,6 +318,8 @@ void RewriteSystem::computeConfluentCompletion(
317318
rule.markDeleted();
318319
}
319320
}
321+
322+
return CompletionResult::Success;
320323
}
321324

322325
void RewriteSystem::dump(llvm::raw_ostream &out) const {

0 commit comments

Comments
 (0)