Skip to content

Commit a337b67

Browse files
committed
Stage In Flags To Fall Back To Manual Tracking
Request-based incremental dependencies are enabled by default. For the time being, add a flag that will turn them off and switch back to manual dependency tracking.
1 parent 3f8f3a8 commit a337b67

File tree

11 files changed

+92
-18
lines changed

11 files changed

+92
-18
lines changed

include/swift/AST/SourceFile.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,19 @@ class SourceFile final : public FileUnit {
480480
return RequestReferencedNames ? RequestReferencedNames.getPointer() : nullptr;
481481
}
482482

483+
/// Creates and installs the referenced name trackers in this source file.
484+
///
485+
/// This entrypoint must be called before incremental compilation can proceed,
486+
/// else reference dependencies will not be registered.
483487
void createReferencedNameTracker();
484488

489+
/// Retrieves the name tracker instance corresponding to
490+
/// \c EnableRequestBasedIncrementalDependencies
491+
///
492+
/// If incremental dependencies tracking is not enabled or \c createReferencedNameTracker()
493+
/// has not been invoked on this source file, the result is \c nullptr.
494+
const ReferencedNameTracker *getConfiguredReferencedNameTracker() const;
495+
485496
/// The buffer ID for the file that was imported, or None if there
486497
/// is no associated buffer.
487498
Optional<unsigned> getBufferID() const {

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ namespace swift {
334334
/// Enable verification when every SubstitutionMap is constructed.
335335
bool VerifyAllSubstitutionMaps = false;
336336

337+
/// If set to \c false, fall back to the legacy manual reference name tracking code.
338+
bool EnableRequestBasedIncrementalDependencies = true;
339+
337340
/// Sets the target we are building for and updates platform conditions
338341
/// to match.
339342
///

include/swift/Frontend/DiagnosticVerifier.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class SourceManager;
2828
class SourceFile;
2929

3030
// MARK: - DependencyVerifier
31+
3132
bool verifyDependencies(SourceManager &SM, const DependencyTracker &DT,
3233
ArrayRef<FileUnit *> SFs);
3334
bool verifyDependencies(SourceManager &SM, const DependencyTracker &DT,
@@ -99,6 +100,7 @@ class DiagnosticVerifier : public DiagnosticConsumer {
99100

100101
void printRemainingDiagnostics() const;
101102
};
102-
}
103+
104+
} // end namespace swift
103105

104106
#endif

include/swift/Option/Options.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,16 @@ def disable_parser_lookup : Flag<["-"], "disable-parser-lookup">,
10331033
Flags<[FrontendOption]>,
10341034
HelpText<"Disable parser lookup & use ast scope lookup only (experimental)">;
10351035

1036+
def enable_request_based_incremental_dependencies : Flag<["-"],
1037+
"enable-request-based-incremental-dependencies">,
1038+
Flags<[FrontendOption]>,
1039+
HelpText<"Enable request-based name tracking">;
1040+
1041+
def disable_request_based_incremental_dependencies : Flag<["-"],
1042+
"disable-request-based-incremental-dependencies">,
1043+
Flags<[FrontendOption]>,
1044+
HelpText<"Disable request-based name tracking">;
1045+
10361046
def index_file : Flag<["-"], "index-file">,
10371047
HelpText<"Produce index data for a source file">, ModeOpt,
10381048
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>;

lib/AST/FrontendSourceFileDepGraphFactory.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,8 @@ DependencyKey DependencyKey::createDependedUponKey(StringRef mangledHolderName,
282282

283283
bool fine_grained_dependencies::emitReferenceDependencies(
284284
DiagnosticEngine &diags, SourceFile *const SF,
285-
const DependencyTracker &depTracker, StringRef outputPath,
285+
const DependencyTracker &depTracker,
286+
StringRef outputPath,
286287
const bool alsoEmitDotFile) {
287288

288289
// Before writing to the dependencies file path, preserve any previous file
@@ -292,7 +293,7 @@ bool fine_grained_dependencies::emitReferenceDependencies(
292293

293294
SourceFileDepGraph g = FrontendSourceFileDepGraphFactory(
294295
SF, outputPath, depTracker, alsoEmitDotFile)
295-
.construct();
296+
.construct();
296297

297298
const bool hadError =
298299
withOutputFile(diags, outputPath, [&](llvm::raw_pwrite_stream &out) {
@@ -563,7 +564,7 @@ void FrontendSourceFileDepGraphFactory::addAllUsedDecls() {
563564
DependencyKey::createKeyForWholeSourceFile(DeclAspect::implementation,
564565
swiftDeps);
565566

566-
SF->getReferencedNameTracker()->enumerateAllUses(
567+
SF->getConfiguredReferencedNameTracker()->enumerateAllUses(
567568
includePrivateDeps, depTracker,
568569
[&](const fine_grained_dependencies::NodeKind kind, StringRef context,
569570
StringRef name, const bool isCascadingUse) {

lib/AST/Module.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,7 +2565,18 @@ void SourceFile::setTypeRefinementContext(TypeRefinementContext *Root) {
25652565

25662566
void SourceFile::createReferencedNameTracker() {
25672567
assert(!ReferencedNames && "This file already has a name tracker.");
2568+
assert(!RequestReferencedNames && "This file already has a name tracker.");
25682569
ReferencedNames.emplace(ReferencedNameTracker());
2570+
RequestReferencedNames.emplace(ReferencedNameTracker());
2571+
}
2572+
2573+
const ReferencedNameTracker *
2574+
SourceFile::getConfiguredReferencedNameTracker() const {
2575+
if (getASTContext().LangOpts.EnableRequestBasedIncrementalDependencies) {
2576+
return getRequestBasedReferencedNameTracker();
2577+
} else {
2578+
return getReferencedNameTracker();
2579+
}
25692580
}
25702581

25712582
ArrayRef<OpaqueTypeDecl *> SourceFile::getOpaqueReturnTypeDecls() {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,10 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
402402
}
403403

404404
Opts.DisableParserLookup |= Args.hasArg(OPT_disable_parser_lookup);
405+
Opts.EnableRequestBasedIncrementalDependencies =
406+
Args.hasFlag(OPT_enable_request_based_incremental_dependencies,
407+
OPT_disable_request_based_incremental_dependencies,
408+
Opts.EnableRequestBasedIncrementalDependencies);
405409
Opts.EnableASTScopeLookup =
406410
Args.hasFlag(options::OPT_enable_astscope_lookup,
407411
options::OPT_disable_astscope_lookup, Opts.EnableASTScopeLookup) ||

lib/Frontend/DependencyVerifier.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ bool DependencyVerifier::parseExpectations(
427427

428428
bool DependencyVerifier::constructObligations(const SourceFile *SF,
429429
ObligationMap &Obligations) {
430-
auto *tracker = SF->getReferencedNameTracker();
430+
auto *tracker = SF->getConfiguredReferencedNameTracker();
431431
assert(tracker && "Constructed source file without referenced name tracker!");
432432

433433
auto &Ctx = SF->getASTContext();
@@ -490,7 +490,7 @@ bool DependencyVerifier::constructObligations(const SourceFile *SF,
490490
bool DependencyVerifier::verifyObligations(
491491
const SourceFile *SF, const std::vector<Expectation> &ExpectedDependencies,
492492
ObligationMap &OM, llvm::StringMap<Expectation> &NegativeExpectations) {
493-
auto *tracker = SF->getReferencedNameTracker();
493+
auto *tracker = SF->getConfiguredReferencedNameTracker();
494494
assert(tracker && "Constructed source file without referenced name tracker!");
495495
auto &diags = SF->getASTContext().Diags;
496496
for (auto &expectation : ExpectedDependencies) {

lib/FrontendTool/FrontendTool.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ static void countStatsPostSema(UnifiedStatsReporter &Stats,
686686
}
687687

688688
for (auto SF : Instance.getPrimarySourceFiles()) {
689-
if (auto *R = SF->getReferencedNameTracker()) {
689+
if (auto *R = SF->getConfiguredReferencedNameTracker()) {
690690
C.NumReferencedTopLevelNames += R->getTopLevelNames().size();
691691
C.NumReferencedDynamicNames += R->getDynamicLookupNames().size();
692692
C.NumReferencedMemberNames += R->getUsedMembers().size();
@@ -941,16 +941,18 @@ static void emitReferenceDependenciesForAllPrimaryInputsIfNeeded(
941941
Invocation.getReferenceDependenciesFilePathForPrimary(
942942
SF->getFilename());
943943
if (!referenceDependenciesFilePath.empty()) {
944-
if (Invocation.getLangOptions().EnableFineGrainedDependencies)
944+
auto LangOpts = Invocation.getLangOptions();
945+
if (LangOpts.EnableFineGrainedDependencies) {
945946
(void)fine_grained_dependencies::emitReferenceDependencies(
946947
Instance.getASTContext().Diags, SF,
947-
*Instance.getDependencyTracker(), referenceDependenciesFilePath,
948-
Invocation.getLangOptions()
949-
.EmitFineGrainedDependencySourcefileDotFiles);
950-
else
948+
*Instance.getDependencyTracker(),
949+
referenceDependenciesFilePath,
950+
LangOpts.EmitFineGrainedDependencySourcefileDotFiles);
951+
} else {
951952
(void)emitReferenceDependencies(Instance.getASTContext().Diags, SF,
952953
*Instance.getDependencyTracker(),
953954
referenceDependenciesFilePath);
955+
}
954956
}
955957
}
956958
}

lib/FrontendTool/ReferenceDependencies.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ class ReferenceDependenciesEmitter {
6161
///
6262
/// \return true on error
6363
static bool emit(DiagnosticEngine &diags, SourceFile *SF,
64-
const DependencyTracker &depTracker, StringRef outputPath);
64+
const DependencyTracker &depTracker,
65+
StringRef outputPath);
6566

6667
/// Emit the dependencies.
6768
static void emit(SourceFile *SF, const DependencyTracker &depTracker,
@@ -488,12 +489,12 @@ void DependsEmitter::emit(const SourceFile *SF,
488489
}
489490

490491
void DependsEmitter::emit() const {
491-
const ReferencedNameTracker *const tracker = SF->getReferencedNameTracker();
492-
assert(tracker && "Cannot emit reference dependencies without a tracker");
492+
const auto *nameTracker = SF->getConfiguredReferencedNameTracker();
493+
assert(nameTracker && "Cannot emit reference dependencies without a tracker");
493494

494-
emitTopLevelNames(tracker);
495+
emitTopLevelNames(nameTracker);
495496

496-
auto &memberLookupTable = tracker->getUsedMembers();
497+
auto &memberLookupTable = nameTracker->getUsedMembers();
497498
std::vector<MemberTableEntryTy> sortedMembers{
498499
memberLookupTable.begin(), memberLookupTable.end()
499500
};
@@ -519,7 +520,7 @@ void DependsEmitter::emit() const {
519520

520521
emitMembers(sortedMembers);
521522
emitNominalTypes(sortedMembers);
522-
emitDynamicLookup(tracker);
523+
emitDynamicLookup(nameTracker);
523524
emitExternal(depTracker);
524525
}
525526

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Some types, such as StringLiteralType, used to be cached in the TypeChecker.
2+
// Consequently, the second primary file (in batch mode) to use that type would
3+
// hit in the cache and no dependency would be recorded.
4+
// This test ensures that this bug stays fixed.
5+
//
6+
// RUN: %empty-directory(%t)
7+
// RUN: %empty-directory(%t/request-based)
8+
// RUN: %empty-directory(%t/manual)
9+
//
10+
// Create two identical inputs, each needing StringLiteralType:
11+
//
12+
// RUN: echo 'fileprivate var v: String { return "\(x)" }; fileprivate let x = "a"' >%t/1.swift
13+
// RUN: echo 'fileprivate var v: String { return "\(x)" }; fileprivate let x = "a"' >%t/2.swift
14+
//
15+
// RUN: %target-swift-frontend -enable-fine-grained-dependencies -typecheck -primary-file %t/1.swift -primary-file %t/2.swift -emit-reference-dependencies-path %t/request-based/1.swiftdeps -emit-reference-dependencies-path %t/request-based/2.swiftdeps
16+
// RUN: %target-swift-frontend -enable-fine-grained-dependencies -typecheck -primary-file %t/1.swift -primary-file %t/2.swift -emit-reference-dependencies-path %t/manual/1.swiftdeps -emit-reference-dependencies-path %t/manual/2.swiftdeps -disable-request-based-incremental-dependencies
17+
//
18+
// Sequence numbers can vary
19+
// RUN: sed -e 's/[0-9][0-9]*/N/g' -e 's/N, //g' -e '/^ *$/d' <%t/request-based/1.swiftdeps | sort >%t/request-based/1-processed.swiftdeps
20+
// RUN: sed -e 's/[0-9][0-9]*/N/g' -e 's/N, //g' -e '/^ *$/d' <%t/request-based/2.swiftdeps | sort >%t/request-based/2-processed.swiftdeps
21+
// RUN: sed -e 's/[0-9][0-9]*/N/g' -e 's/N, //g' -e '/^ *$/d' <%t/manual/1.swiftdeps | sort >%t/manual/1-processed.swiftdeps
22+
// RUN: sed -e 's/[0-9][0-9]*/N/g' -e 's/N, //g' -e '/^ *$/d' <%t/manual/2.swiftdeps | sort >%t/manual/2-processed.swiftdeps
23+
24+
// Check that manual matches manual and request-based matches request-based.
25+
// Unfortunately, the remaining two cross-configuration tests will not pass
26+
// because request-based dependencies capture strictly more dependency edges
27+
// than the manual name tracker.
28+
// RUN: cmp -s %t/request-based/1-processed.swiftdeps %t/request-based/2-processed.swiftdeps
29+
// RUN: cmp -s %t/manual/1-processed.swiftdeps %t/manual/2-processed.swiftdeps

0 commit comments

Comments
 (0)