Skip to content

Commit 01ebc93

Browse files
committed
AST: Only build request dependency graph if frontend is run with -build-request-dependency-graph
This adds a measurable amount of runtime overhead, but it's only needed for debugging.
1 parent 4a10427 commit 01ebc93

File tree

8 files changed

+39
-13
lines changed

8 files changed

+39
-13
lines changed

include/swift/AST/Evaluator.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ class Evaluator {
187187
/// Whether to dump detailed debug info for cycles.
188188
bool debugDumpCycles;
189189

190+
/// Whether we're building a request dependency graph.
191+
bool buildDependencyGraph;
192+
190193
/// Used to report statistics about which requests were evaluated, if
191194
/// non-null.
192195
UnifiedStatsReporter *stats = nullptr;
@@ -237,7 +240,9 @@ class Evaluator {
237240
public:
238241
/// Construct a new evaluator that can emit cyclic-dependency
239242
/// diagnostics through the given diagnostics engine.
240-
Evaluator(DiagnosticEngine &diags, bool debugDumpCycles=false);
243+
Evaluator(DiagnosticEngine &diags,
244+
bool debugDumpCycles,
245+
bool buildDependencyGraph);
241246

242247
/// Emit GraphViz output visualizing the request graph.
243248
void emitRequestEvaluatorGraphViz(llvm::StringRef graphVizPath);
@@ -370,7 +375,8 @@ class Evaluator {
370375
getResultUncached(const Request &request) {
371376
// Clear out the dependencies on this request; we're going to recompute
372377
// them now anyway.
373-
dependencies.find_as(request)->second.clear();
378+
if (buildDependencyGraph)
379+
dependencies.find_as(request)->second.clear();
374380

375381
PrettyStackTraceRequest<Request> prettyStackTrace(request);
376382

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,10 @@ namespace swift {
173173

174174
/// Whether to dump debug info for request evaluator cycles.
175175
bool DebugDumpCycles = false;
176-
176+
177+
/// Whether to build a request dependency graph for debugging.
178+
bool BuildRequestDependencyGraph = false;
179+
177180
/// Enable SIL type lowering
178181
bool EnableSubstSILFunctionTypesForFunctionValues = false;
179182

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ def debug_forbid_typecheck_prefix : Separate<["-"], "debug-forbid-typecheck-pref
246246

247247
def debug_cycles : Flag<["-"], "debug-cycles">,
248248
HelpText<"Print out debug dumps when cycles are detected in evaluation">;
249+
def build_request_dependency_graph : Flag<["-"], "build-request-dependency-graph">,
250+
HelpText<"Build request dependency graph">;
249251
def output_request_graphviz : Separate<["-"], "output-request-graphviz">,
250-
HelpText<"Emit GraphViz output visualizing the request graph">;
252+
HelpText<"Emit GraphViz output visualizing the request dependency graph">;
251253

252254
def debug_time_compilation : Flag<["-"], "debug-time-compilation">,
253255
HelpText<"Prints the time taken by each compilation phase">;

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,9 @@ ASTContext::ASTContext(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
530530
: LangOpts(langOpts),
531531
TypeCheckerOpts(typeckOpts),
532532
SearchPathOpts(SearchPathOpts), SourceMgr(SourceMgr), Diags(Diags),
533-
evaluator(Diags, langOpts.DebugDumpCycles),
533+
evaluator(Diags,
534+
langOpts.DebugDumpCycles,
535+
langOpts.BuildRequestDependencyGraph),
534536
TheBuiltinModule(createBuiltinModule(*this)),
535537
StdlibModuleName(getIdentifier(STDLIB_NAME)),
536538
SwiftShimsModuleName(getIdentifier(SWIFT_SHIMS_NAME)),

lib/AST/Evaluator.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,12 @@ void Evaluator::registerRequestFunctions(
6262
requestFunctionsByZone.push_back({zoneID, functions});
6363
}
6464

65-
Evaluator::Evaluator(DiagnosticEngine &diags, bool debugDumpCycles)
66-
: diags(diags), debugDumpCycles(debugDumpCycles) { }
65+
Evaluator::Evaluator(DiagnosticEngine &diags,
66+
bool debugDumpCycles,
67+
bool buildDependencyGraph)
68+
: diags(diags),
69+
debugDumpCycles(debugDumpCycles),
70+
buildDependencyGraph(buildDependencyGraph) { }
6771

6872
void Evaluator::emitRequestEvaluatorGraphViz(llvm::StringRef graphVizPath) {
6973
std::error_code error;
@@ -72,9 +76,11 @@ void Evaluator::emitRequestEvaluatorGraphViz(llvm::StringRef graphVizPath) {
7276
}
7377

7478
bool Evaluator::checkDependency(const AnyRequest &request) {
75-
// If there is an active request, record it's dependency on this request.
76-
if (!activeRequests.empty())
77-
dependencies[activeRequests.back()].push_back(request);
79+
if (buildDependencyGraph) {
80+
// If there is an active request, record it's dependency on this request.
81+
if (!activeRequests.empty())
82+
dependencies[activeRequests.back()].push_back(request);
83+
}
7884

7985
// Record this as an active request.
8086
if (activeRequests.insert(request)) {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
390390
if (Args.getLastArg(OPT_debug_cycles))
391391
Opts.DebugDumpCycles = true;
392392

393+
if (Args.getLastArg(OPT_build_request_dependency_graph))
394+
Opts.BuildRequestDependencyGraph = true;
395+
393396
if (const Arg *A = Args.getLastArg(OPT_output_request_graphviz)) {
394397
Opts.RequestEvaluatorGraphVizPath = A->getValue();
395398
}

test/decl/class/circular_inheritance.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: rm -rf %t/stats-dir
22
// RUN: mkdir -p %t/stats-dir
33
// RUN: %target-typecheck-verify-swift
4-
// RUN: not %target-swift-frontend -typecheck -debug-cycles %s -output-request-graphviz %t.dot -stats-output-dir %t/stats-dir 2> %t.cycles
4+
// RUN: not %target-swift-frontend -typecheck -debug-cycles %s -build-request-dependency-graph -output-request-graphviz %t.dot -stats-output-dir %t/stats-dir 2> %t.cycles
55
// RUN: %FileCheck %s < %t.cycles
66
// RUN: %FileCheck -check-prefix CHECK-DOT %s < %t.dot
77

unittests/AST/ArithmeticEvaluator.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,9 @@ TEST(ArithmeticEvaluator, Simple) {
210210

211211
SourceManager sourceMgr;
212212
DiagnosticEngine diags(sourceMgr);
213-
Evaluator evaluator(diags);
213+
Evaluator evaluator(diags,
214+
/*debugDumpCycles=*/false,
215+
/*buildDependencyGraph=*/true);
214216
evaluator.registerRequestFunctions(Zone::ArithmeticEvaluator,
215217
arithmeticRequestFunctions);
216218

@@ -333,7 +335,9 @@ TEST(ArithmeticEvaluator, Cycle) {
333335

334336
SourceManager sourceMgr;
335337
DiagnosticEngine diags(sourceMgr);
336-
Evaluator evaluator(diags);
338+
Evaluator evaluator(diags,
339+
/*debugDumpCycles=*/false,
340+
/*buildDependencyGraph=*/false);
337341
evaluator.registerRequestFunctions(Zone::ArithmeticEvaluator,
338342
arithmeticRequestFunctions);
339343

0 commit comments

Comments
 (0)