Skip to content

Commit 2e11874

Browse files
[Caching] Update swift-driver to reflect the frontend caching configuration
Re-unify caching availability check behind swift feature query and adjust the default caching build configuration changes.
1 parent 8b3926b commit 2e11874

File tree

8 files changed

+45
-117
lines changed

8 files changed

+45
-117
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,13 @@ public struct Driver {
274274
let enableCaching: Bool
275275
let useClangIncludeTree: Bool
276276

277-
var cas: SwiftScanCAS?
277+
/// CAS instance used for compilation.
278+
public var cas: SwiftScanCAS? = nil
279+
280+
/// Is swift caching enabled.
281+
lazy var isCachingEnabled: Bool = {
282+
return enableCaching && isFeatureSupported(.cache_compile_job)
283+
}()
278284

279285
/// Scanner prefix mapping.
280286
let scannerPrefixMap: [AbsolutePath: AbsolutePath]
@@ -418,6 +424,7 @@ public struct Driver {
418424
@_spi(Testing)
419425
public enum KnownCompilerFeature: String {
420426
case emit_abi_descriptor = "emit-abi-descriptor"
427+
case cache_compile_job = "cache-compile-job"
421428
}
422429

423430
lazy var sdkPath: VirtualPath? = {
@@ -477,14 +484,6 @@ public struct Driver {
477484
return supportedFrontendFeatures.contains(feature.rawValue)
478485
}
479486

480-
@_spi(Testing)
481-
public func getCAS() throws -> SwiftScanCAS {
482-
guard let cas = self.cas else {
483-
throw DependencyScanningError.casError("CAS is not initialized but requested")
484-
}
485-
return cas
486-
}
487-
488487
@_spi(Testing)
489488
public static func findBlocklists(RelativeTo execDir: AbsolutePath) throws -> [AbsolutePath] {
490489
// Expect to find all blocklists in such dir:
@@ -638,7 +637,7 @@ public struct Driver {
638637

639638
let cachingEnableOverride = parsedOptions.hasArgument(.driverExplicitModuleBuild) && env.keys.contains("SWIFT_ENABLE_CACHING")
640639
self.enableCaching = parsedOptions.hasArgument(.cacheCompileJob) || cachingEnableOverride
641-
self.useClangIncludeTree = enableCaching && env.keys.contains("SWIFT_CACHING_USE_INCLUDE_TREE")
640+
self.useClangIncludeTree = !parsedOptions.hasArgument(.noClangIncludeTree) && !env.keys.contains("SWIFT_CACHING_USE_CLANG_CAS_FS")
642641
self.scannerPrefixMap = try Self.computeScanningPrefixMapper(&parsedOptions)
643642
if let sdkMapping = parsedOptions.getLastArgument(.scannerPrefixMapSdk)?.asSingle {
644643
self.scannerPrefixMapSDK = try AbsolutePath(validating: sdkMapping)

Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyOracle.swift

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -146,20 +146,6 @@ public class InterModuleDependencyOracle {
146146
return swiftScan.supportsBinaryModuleHeaderDependencies
147147
}
148148

149-
@_spi(Testing) public func supportsCaching() throws -> Bool {
150-
guard let swiftScan = swiftScanLibInstance else {
151-
fatalError("Attempting to query supported scanner API with no scanner instance.")
152-
}
153-
return swiftScan.supportsCaching
154-
}
155-
156-
@_spi(Testing) public func supportsCacheReplay() throws -> Bool {
157-
guard let swiftScan = swiftScanLibInstance else {
158-
fatalError("Attempting to query supported scanner API with no scanner instance.")
159-
}
160-
return swiftScan.supportsCacheReplay
161-
}
162-
163149
@_spi(Testing) public func supportsBridgingHeaderPCHCommand() throws -> Bool {
164150
guard let swiftScan = swiftScanLibInstance else {
165151
fatalError("Attempting to query supported scanner API with no scanner instance.")

Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ public extension Driver {
119119
commandLine.appendPath(dependencyPlaceholderMapFile)
120120
}
121121

122-
try commandLine.appendLast(.clangIncludeTree, from: &parsedOptions)
123122
if isFrontendArgSupported(.clangScannerModuleCachePath) {
124123
try commandLine.appendLast(.clangScannerModuleCachePath, from: &parsedOptions)
125124
}
@@ -173,7 +172,7 @@ public extension Driver {
173172
diagnosticEngine.emit(.warn_scanner_frontend_fallback())
174173
}
175174
}
176-
if !fallbackToFrontend && enableCaching {
175+
if !fallbackToFrontend && isCachingEnabled {
177176
self.cas = try interModuleDependencyOracle.createCAS(pluginPath: try getCASPluginPath(),
178177
onDiskPath: try getOnDiskCASPath(),
179178
pluginOptions: try getCASPluginOptions())

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ extension Driver {
318318
try commandLine.appendLast(.enableBuiltinModule, from: &parsedOptions)
319319
}
320320

321-
if !useClangIncludeTree, let workingDirectory = workingDirectory {
321+
if !(isCachingEnabled && useClangIncludeTree), let workingDirectory = workingDirectory {
322322
// Add -Xcc -working-directory before any other -Xcc options to ensure it is
323323
// overridden by an explicit -Xcc -working-directory, although having a
324324
// different working directory is probably incorrect.
@@ -359,7 +359,7 @@ extension Driver {
359359
}
360360

361361
// CAS related options.
362-
if enableCaching {
362+
if isCachingEnabled {
363363
commandLine.appendFlag(.cacheCompileJob)
364364
if let casPath = try getOnDiskCASPath() {
365365
commandLine.appendFlag(.casPath)
@@ -371,16 +371,16 @@ extension Driver {
371371
}
372372
try commandLine.appendAll(.casPluginOption, from: &parsedOptions)
373373
try commandLine.appendLast(.cacheRemarks, from: &parsedOptions)
374+
if !useClangIncludeTree {
375+
commandLine.appendFlag(.noClangIncludeTree)
376+
}
374377
}
375378
addCacheReplayMapping(to: &commandLine)
376-
if useClangIncludeTree {
377-
commandLine.appendFlag(.clangIncludeTree)
378-
}
379379

380380
// Pass through any subsystem flags.
381381
try commandLine.appendAll(.Xllvm, from: &parsedOptions)
382382

383-
if !useClangIncludeTree {
383+
if !(isCachingEnabled && useClangIncludeTree) {
384384
try commandLine.appendAll(.Xcc, from: &parsedOptions)
385385
}
386386

@@ -446,7 +446,7 @@ extension Driver {
446446

447447
mutating func addBridgingHeaderPCHCacheKeyArguments(commandLine: inout [Job.ArgTemplate],
448448
pchCompileJob: Job?) throws {
449-
guard let pchJob = pchCompileJob, enableCaching else { return }
449+
guard let pchJob = pchCompileJob, isCachingEnabled else { return }
450450

451451
// The pch input file (the bridging header) is added as last inputs to the job.
452452
guard let inputFile = pchJob.inputs.last else { assertionFailure("no input files from pch job"); return }
@@ -701,7 +701,7 @@ extension Driver {
701701
} else {
702702
entryInput = inputFiles[0].fileHandle
703703
}
704-
let inputEntry = enableCaching ? remapPath(VirtualPath.lookup(entryInput)).intern() : entryInput
704+
let inputEntry = isCachingEnabled ? remapPath(VirtualPath.lookup(entryInput)).intern() : entryInput
705705
entries[inputEntry, default: [:]][output.type] = output.fileHandle
706706
}
707707

@@ -771,7 +771,7 @@ extension Driver {
771771

772772
/// Helper function to add path to commandLine. Function will validate the path, and remap the path if needed.
773773
public mutating func addPathArgument(_ path: VirtualPath, to commandLine: inout [Job.ArgTemplate], remap: Bool = true) throws {
774-
guard remap && enableCaching else {
774+
guard remap && isCachingEnabled else {
775775
commandLine.appendPath(path)
776776
return
777777
}
@@ -813,7 +813,7 @@ extension Driver {
813813
}
814814

815815
public mutating func addCacheReplayMapping(to commandLine: inout [Job.ArgTemplate]) {
816-
if enableCaching && isFrontendArgSupported(.scannerPrefixMap) {
816+
if isCachingEnabled && isFrontendArgSupported(.scannerPrefixMap) {
817817
for (key, value) in prefixMapping {
818818
commandLine.appendFlag("-cache-replay-prefix-map")
819819
commandLine.appendFlag(value.pathString + "=" + key.pathString)

Sources/SwiftDriver/Jobs/VerifyModuleInterfaceJob.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extension Driver {
1616
assert(interfaceKind == .swiftInterface || interfaceKind == .privateSwiftInterface,
1717
"only expect interface output kind")
1818
let isNeeded = emitModuleJob.outputs.contains { $0.type == interfaceKind }
19-
guard enableCaching && isNeeded else { return nil }
19+
guard isCachingEnabled && isNeeded else { return nil }
2020

2121
// Assume swiftinterface file is always the supplementary output for first input file.
2222
let key = try computeOutputCacheKey(commandLine: emitModuleJob.commandLine,

Sources/SwiftDriver/SwiftScan/SwiftScan.swift

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -294,36 +294,6 @@ internal extension swiftscan_diagnostic_severity_t {
294294
#endif
295295
}
296296

297-
@_spi(Testing) public var supportsCacheReplay : Bool {
298-
#if os(Windows)
299-
// Caching is currently not supported on Windows hosts.
300-
return false
301-
#else
302-
return supportsCaching &&
303-
api.swiftscan_cache_query != nil &&
304-
api.swiftscan_cache_query_async != nil &&
305-
api.swiftscan_cache_action_cancel != nil &&
306-
api.swiftscan_cache_cancellation_token_dispose != nil &&
307-
api.swiftscan_cached_compilation_get_num_outputs != nil &&
308-
api.swiftscan_cached_compilation_get_output != nil &&
309-
api.swiftscan_cached_compilation_make_global_async != nil &&
310-
api.swiftscan_cached_compilation_is_uncacheable != nil &&
311-
api.swiftscan_cached_compilation_dispose != nil &&
312-
api.swiftscan_cached_output_load != nil &&
313-
api.swiftscan_cached_output_load_async != nil &&
314-
api.swiftscan_cached_output_is_materialized != nil &&
315-
api.swiftscan_cached_output_get_casid != nil &&
316-
api.swiftscan_cached_output_get_name != nil &&
317-
api.swiftscan_cached_output_dispose != nil &&
318-
api.swiftscan_cache_replay_instance_create != nil &&
319-
api.swiftscan_cache_replay_instance_dispose != nil &&
320-
api.swiftscan_cache_replay_result_get_stdout != nil &&
321-
api.swiftscan_cache_replay_result_get_stderr != nil &&
322-
api.swiftscan_cache_replay_result_dispose != nil &&
323-
api.swiftscan_cache_replay_compilation != nil
324-
#endif
325-
}
326-
327297
@_spi(Testing) public var supportsBridgingHeaderPCHCommand : Bool {
328298
return api.swiftscan_swift_textual_detail_get_bridging_pch_command_line != nil
329299
}

Sources/SwiftOptions/Options.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extension Option {
3333
public static let analyzeRequirementMachine: Option = Option("-analyze-requirement-machine", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Print out requirement machine statistics at the end of the compilation job")
3434
public static let apiDiffDataDir: Option = Option("-api-diff-data-dir", .separate, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild, .argumentIsPath], metaVar: "<path>", helpText: "Load platform and version specific API migration data files from <path>. Ignored if -api-diff-data-file is specified.")
3535
public static let apiDiffDataFile: Option = Option("-api-diff-data-file", .separate, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild, .argumentIsPath], metaVar: "<path>", helpText: "API migration data is from <path>")
36+
public static let enableAppExtensionLibrary: Option = Option("-application-extension-library", .flag, attributes: [.frontend, .noInteractive], helpText: "Restrict code to those available for App Extension Libraries")
3637
public static let enableAppExtension: Option = Option("-application-extension", .flag, attributes: [.frontend, .noInteractive], helpText: "Restrict code to those available for App Extensions")
3738
public static let AssertConfig: Option = Option("-assert-config", .separate, attributes: [.frontend, .moduleInterface], helpText: "Specify the assert_configuration replacement. Possible values are Debug, Release, Unchecked, DisableReplacement.")
3839
public static let AssumeSingleThreaded: Option = Option("-assume-single-threaded", .flag, attributes: [.helpHidden, .frontend], helpText: "Assume that code will be executed in a single-threaded environment")
@@ -79,7 +80,6 @@ extension Option {
7980
public static let clangHeaderExposeDecls: Option = Option("-clang-header-expose-decls=", .joined, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "all-public|has-expose-attr", helpText: "Which declarations should be exposed in the generated clang header.")
8081
public static let clangHeaderExposeModule: Option = Option("-clang-header-expose-module", .separate, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "<imported-module-name>=<generated-header-name>", helpText: "Allow the compiler to assume that APIs from the specified module are exposed to C/C++/Objective-C in another generated header, so that APIs in the current module that depend on declarations from the specified module can be exposed in the generated header.")
8182
public static let clangIncludeTreeRoot: Option = Option("-clang-include-tree-root", .separate, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "<cas-id>", helpText: "Clang Include Tree CASID")
82-
public static let clangIncludeTree: Option = Option("-clang-include-tree", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Use clang include tree")
8383
public static let clangScannerModuleCachePath: Option = Option("-clang-scanner-module-cache-path", .separate, attributes: [.frontend, .doesNotAffectIncrementalBuild, .argumentIsPath], helpText: "Specifies the Clang dependency scanner module cache path")
8484
public static let clangTarget: Option = Option("-clang-target", .separate, attributes: [.frontend], helpText: "Separately set the target we should use for internal Clang instance")
8585
public static let codeCompleteCallPatternHeuristics: Option = Option("-code-complete-call-pattern-heuristics", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Use heuristics to guess whether we want call pattern completions")
@@ -114,7 +114,6 @@ extension Option {
114114
public static let debugForbidTypecheckPrefix: Option = Option("-debug-forbid-typecheck-prefix", .separate, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Triggers llvm fatal_error if typechecker tries to typecheck a decl with the provided prefix name")
115115
public static let debugGenericSignatures: Option = Option("-debug-generic-signatures", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Debug generic signatures")
116116
public static let debugInfoFormat: Option = Option("-debug-info-format=", .joined, attributes: [.frontend], helpText: "Specify the debug info format type to either 'dwarf' or 'codeview'")
117-
public static let dwarfVersion: Option = Option("-dwarf-version=", .joined, attributes: [.frontend], helpText: "DWARF debug info version to produce if requested")
118117
public static let debugInfoStoreInvocation: Option = Option("-debug-info-store-invocation", .flag, attributes: [.frontend], helpText: "Emit the compiler invocation in the debug info.")
119118
public static let debugMapping: Option = Option("-debug-mapping", .flag, attributes: [.noDriver], helpText: "Dumping information for debug purposes")
120119
public static let debugMapping_: Option = Option("--debug-mapping", .flag, alias: Option.debugMapping, attributes: [.noDriver], helpText: "Dumping information for debug purposes")
@@ -278,6 +277,7 @@ extension Option {
278277
public static let dumpTypeRefinementContexts: Option = Option("-dump-type-refinement-contexts", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Type-check input file(s) and dump type refinement contexts(s)", group: .modes)
279278
public static let dumpTypeWitnessSystems: Option = Option("-dump-type-witness-systems", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enables dumping type witness systems from associated type inference")
280279
public static let dumpUsr: Option = Option("-dump-usr", .flag, attributes: [.frontend, .noInteractive], helpText: "Dump USR for each declaration reference")
280+
public static let dwarfVersion: Option = Option("-dwarf-version=", .joined, attributes: [.frontend], metaVar: "<version>", helpText: "DWARF debug info version to produce if requested")
281281
public static let D: Option = Option("-D", .joinedOrSeparate, attributes: [.frontend], helpText: "Marks a conditional compilation flag as true")
282282
public static let embedBitcodeMarker: Option = Option("-embed-bitcode-marker", .flag, attributes: [.frontend, .noInteractive], helpText: "Embed placeholder LLVM IR data as a marker")
283283
public static let embedBitcode: Option = Option("-embed-bitcode", .flag, attributes: [.frontend, .noInteractive], helpText: "Embed LLVM IR bitcode as data")
@@ -584,6 +584,7 @@ extension Option {
584584
public static let module: Option = Option("-module", .separate, attributes: [.noDriver], metaVar: "<name>", helpText: "Names of modules")
585585
public static let module_: Option = Option("--module", .separate, alias: Option.module, attributes: [.noDriver], metaVar: "<name>", helpText: "Names of modules")
586586
public static let newDriverPath: Option = Option("-new-driver-path", .separate, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "<path>", helpText: "Path of the new driver to be used")
587+
public static let noClangIncludeTree: Option = Option("-no-clang-include-tree", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Do not use clang include tree, fallback to use CAS filesystem to build clang modules")
587588
public static let noClangModuleBreadcrumbs: Option = Option("-no-clang-module-breadcrumbs", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Don't emit DWARF skeleton CUs for imported Clang modules. Use this when building a redistributable static archive.")
588589
public static let noColorDiagnostics: Option = Option("-no-color-diagnostics", .flag, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Do not print diagnostics in color")
589590
public static let noEmitModuleSeparatelyWMO: Option = Option("-no-emit-module-separately-wmo", .flag, attributes: [.helpHidden], helpText: "Force emitting the swiftmodule in the same job in wmo builds")
@@ -615,7 +616,7 @@ extension Option {
615616
public static let O: Option = Option("-O", .flag, attributes: [.frontend, .moduleInterface], helpText: "Compile with optimizations", group: .O)
616617
public static let o: Option = Option("-o", .joinedOrSeparate, attributes: [.frontend, .noInteractive, .autolinkExtract, .moduleWrap, .indent, .argumentIsPath, .cacheInvariant], metaVar: "<file>", helpText: "Write output to <file>")
617618
public static let packageDescriptionVersion: Option = Option("-package-description-version", .separate, attributes: [.helpHidden, .frontend, .moduleInterface], metaVar: "<vers>", helpText: "The version number to be applied on the input for the PackageDescription availability kind")
618-
public static let packageName: Option = Option("-package-name", .separate, attributes: [.frontend], helpText: "Name of the package the module belongs to")
619+
public static let packageName: Option = Option("-package-name", .separate, attributes: [.frontend, .moduleInterface], helpText: "Name of the package the module belongs to")
619620
public static let parallelScan: Option = Option("-parallel-scan", .flag, attributes: [.frontend, .noDriver], helpText: "Perform dependency scanning in-parallel.")
620621
public static let parseAsLibrary: Option = Option("-parse-as-library", .flag, attributes: [.frontend, .noInteractive], helpText: "Parse the input file(s) as libraries, not scripts")
621622
public static let parseSil: Option = Option("-parse-sil", .flag, attributes: [.frontend, .noInteractive], helpText: "Parse the input file as SIL code, not Swift source")
@@ -854,6 +855,7 @@ extension Option {
854855
Option.analyzeRequirementMachine,
855856
Option.apiDiffDataDir,
856857
Option.apiDiffDataFile,
858+
Option.enableAppExtensionLibrary,
857859
Option.enableAppExtension,
858860
Option.AssertConfig,
859861
Option.AssumeSingleThreaded,
@@ -900,7 +902,6 @@ extension Option {
900902
Option.clangHeaderExposeDecls,
901903
Option.clangHeaderExposeModule,
902904
Option.clangIncludeTreeRoot,
903-
Option.clangIncludeTree,
904905
Option.clangScannerModuleCachePath,
905906
Option.clangTarget,
906907
Option.codeCompleteCallPatternHeuristics,
@@ -935,7 +936,6 @@ extension Option {
935936
Option.debugForbidTypecheckPrefix,
936937
Option.debugGenericSignatures,
937938
Option.debugInfoFormat,
938-
Option.dwarfVersion,
939939
Option.debugInfoStoreInvocation,
940940
Option.debugMapping,
941941
Option.debugMapping_,
@@ -1099,6 +1099,7 @@ extension Option {
10991099
Option.dumpTypeRefinementContexts,
11001100
Option.dumpTypeWitnessSystems,
11011101
Option.dumpUsr,
1102+
Option.dwarfVersion,
11021103
Option.D,
11031104
Option.embedBitcodeMarker,
11041105
Option.embedBitcode,
@@ -1405,6 +1406,7 @@ extension Option {
14051406
Option.module,
14061407
Option.module_,
14071408
Option.newDriverPath,
1409+
Option.noClangIncludeTree,
14081410
Option.noClangModuleBreadcrumbs,
14091411
Option.noColorDiagnostics,
14101412
Option.noEmitModuleSeparatelyWMO,

0 commit comments

Comments
 (0)