Skip to content

Commit bad60da

Browse files
authored
Merge pull request #476 from artemcm/CacheHashedPCMNames
[Explciti Module Builds] Cache the computation of Clang module dependency PCM names.
2 parents 6278aa4 + 0c996e6 commit bad60da

File tree

4 files changed

+164
-89
lines changed

4 files changed

+164
-89
lines changed

Sources/SwiftDriver/ExplicitModuleBuilds/ExplicitDependencyBuildPlanner.swift

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,17 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
3939
private let integratedDriver: Bool
4040
private let mainModuleName: String?
4141

42+
/// Clang PCM names contain a hash of the command-line arguments that were used to build them.
43+
/// We avoid re-running the hash computation with the use of this cache
44+
private var hashedModuleNameCache: [String: String] = [:]
45+
4246
public init(dependencyGraph: InterModuleDependencyGraph,
4347
toolchain: Toolchain,
44-
integratedDriver: Bool = true,
45-
mainModuleName: String? = nil) throws {
48+
integratedDriver: Bool = true) throws {
4649
self.dependencyGraph = dependencyGraph
4750
self.toolchain = toolchain
4851
self.integratedDriver = integratedDriver
49-
self.mainModuleName = mainModuleName
52+
self.mainModuleName = dependencyGraph.mainModuleName
5053
self.reachabilityMap = try dependencyGraph.computeTransitiveClosure()
5154
}
5255

@@ -82,7 +85,7 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
8285
/// module's target version (PCM Args).
8386
/// 2. Generate jobs for all Clang modules, now that we have each module's set of PCM versions it must be
8487
/// built against.
85-
public func generateExplicitModuleDependenciesBuildJobs() throws -> [Job] {
88+
public mutating func generateExplicitModuleDependenciesBuildJobs() throws -> [Job] {
8689
let mainModuleId: ModuleDependencyId = .swift(dependencyGraph.mainModuleName)
8790
guard let mainModuleDependencies = reachabilityMap[mainModuleId] else {
8891
fatalError("Expected reachability information for the main module.")
@@ -104,9 +107,9 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
104107
}
105108

106109
/// Generate a build job for each Swift module in the set of supplied `dependencies`
107-
private func generateSwiftDependenciesBuildJobs(for dependencies: Set<ModuleDependencyId>,
108-
clangPCMSetMap:
109-
inout [ModuleDependencyId : Set<[String]>])
110+
private mutating func generateSwiftDependenciesBuildJobs(for dependencies: Set<ModuleDependencyId>,
111+
clangPCMSetMap:
112+
inout [ModuleDependencyId : Set<[String]>])
110113
throws -> [Job] {
111114
var jobs: [Job] = []
112115
let swiftDependencies = dependencies.filter {
@@ -174,9 +177,9 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
174177

175178
/// Generate a build job for each Clang module in the set of supplied `dependencies`. Once per each required
176179
/// PCMArgSet as queried from the supplied `clangPCMSetMap`
177-
private func generateClangDependenciesBuildJobs(for dependencies: Set<ModuleDependencyId>,
178-
using clangPCMSetMap:
179-
[ModuleDependencyId : Set<[String]>])
180+
private mutating func generateClangDependenciesBuildJobs(for dependencies: Set<ModuleDependencyId>,
181+
using clangPCMSetMap:
182+
[ModuleDependencyId : Set<[String]>])
180183
throws -> [Job] {
181184
var jobs: [Job] = []
182185
let clangDependencies = dependencies.filter {
@@ -210,9 +213,8 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
210213

211214
// Encode the target triple pcm args into the output `.pcm` filename
212215
let targetEncodedModulePath =
213-
try ExplicitDependencyBuildPlanner
214-
.targetEncodedClangModuleFilePath(for: moduleInfo,
215-
hashParts: getPCMHashParts(pcmArgs: pcmArgs))
216+
try targetEncodedClangModuleFilePath(for: moduleInfo,
217+
hashParts: getPCMHashParts(pcmArgs: pcmArgs))
216218
outputs.append(TypedVirtualPath(file: targetEncodedModulePath, type: .pcm))
217219
commandLine.appendFlags("-emit-pcm", "-module-name", moduleId.moduleName,
218220
"-o", targetEncodedModulePath.description)
@@ -239,9 +241,9 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
239241

240242
/// For the specified module, update the given command line flags and inputs
241243
/// to use explicitly-built module dependencies.
242-
private func resolveExplicitModuleDependencies(moduleId: ModuleDependencyId, pcmArgs: [String],
243-
inputs: inout [TypedVirtualPath],
244-
commandLine: inout [Job.ArgTemplate]) throws {
244+
private mutating func resolveExplicitModuleDependencies(moduleId: ModuleDependencyId, pcmArgs: [String],
245+
inputs: inout [TypedVirtualPath],
246+
commandLine: inout [Job.ArgTemplate]) throws {
245247
// Prohibit the frontend from implicitly building textual modules into binary modules.
246248
commandLine.appendFlags("-disable-implicit-swift-modules", "-Xcc", "-Xclang", "-Xcc",
247249
"-fno-implicit-modules")
@@ -286,9 +288,9 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
286288

287289
/// Add a specific module dependency as an input and a corresponding command
288290
/// line flag.
289-
private func addModuleDependencies(moduleId: ModuleDependencyId, pcmArgs: [String],
290-
clangDependencyArtifacts: inout [ClangModuleArtifactInfo],
291-
swiftDependencyArtifacts: inout [SwiftModuleArtifactInfo]
291+
private mutating func addModuleDependencies(moduleId: ModuleDependencyId, pcmArgs: [String],
292+
clangDependencyArtifacts: inout [ClangModuleArtifactInfo],
293+
swiftDependencyArtifacts: inout [SwiftModuleArtifactInfo]
292294
) throws {
293295
guard let moduleDependencies = reachabilityMap[moduleId] else {
294296
fatalError("Expected reachability information for the module: \(moduleId.moduleName).")
@@ -313,9 +315,8 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
313315
let dependencyClangModuleDetails =
314316
try dependencyGraph.clangModuleDetails(of: dependencyId)
315317
let clangModulePath =
316-
try ExplicitDependencyBuildPlanner
317-
.targetEncodedClangModuleFilePath(for: dependencyInfo,
318-
hashParts: getPCMHashParts(pcmArgs: pcmArgs))
318+
try targetEncodedClangModuleFilePath(for: dependencyInfo,
319+
hashParts: getPCMHashParts(pcmArgs: pcmArgs))
319320
// Accumulate the requried information about this dependency
320321
clangDependencyArtifacts.append(
321322
ClangModuleArtifactInfo(name: dependencyId.moduleName,
@@ -359,8 +360,8 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
359360

360361
/// Resolve all module dependencies of the main module and add them to the lists of
361362
/// inputs and command line flags.
362-
public func resolveMainModuleDependencies(inputs: inout [TypedVirtualPath],
363-
commandLine: inout [Job.ArgTemplate]) throws {
363+
public mutating func resolveMainModuleDependencies(inputs: inout [TypedVirtualPath],
364+
commandLine: inout [Job.ArgTemplate]) throws {
364365
let mainModuleId: ModuleDependencyId = .swift(dependencyGraph.mainModuleName)
365366
try resolveExplicitModuleDependencies(moduleId: mainModuleId,
366367
pcmArgs:
@@ -401,8 +402,8 @@ public typealias ExternalBuildArtifacts = (ExternalTargetModulePathMap, ModuleIn
401402
extension ExplicitDependencyBuildPlanner {
402403
/// Compute a full path to the resulting .pcm file for a given Clang module, with the
403404
/// target triple encoded in the name.
404-
public static func targetEncodedClangModuleFilePath(for moduleInfo: ModuleInfo,
405-
hashParts: [String]) throws -> VirtualPath {
405+
public mutating func targetEncodedClangModuleFilePath(for moduleInfo: ModuleInfo,
406+
hashParts: [String]) throws -> VirtualPath {
406407
let plainModulePath = moduleInfo.modulePath.path
407408
let targetEncodedBaseName =
408409
try targetEncodedClangModuleName(for: plainModulePath.basenameWithoutExt,
@@ -416,9 +417,15 @@ extension ExplicitDependencyBuildPlanner {
416417

417418
/// Compute the name of a given Clang module, along with a hash of extra PCM build arguments it
418419
/// is to be constructed with.
419-
public static func targetEncodedClangModuleName(for moduleName: String,
420-
hashParts: [String]) throws -> String {
420+
@_spi(Testing) public mutating func targetEncodedClangModuleName(for moduleName: String,
421+
hashParts: [String])
422+
throws -> String {
421423
let hashInput = hashParts.sorted().joined()
424+
// Hash based on "moduleName + hashInput"
425+
let cacheQuery = moduleName + hashInput
426+
if let previouslyHashsedName = hashedModuleNameCache[cacheQuery] {
427+
return previouslyHashsedName
428+
}
422429
let hashedArguments: String
423430
#if os(macOS)
424431
if #available(macOS 10.15, iOS 13, *) {
@@ -429,7 +436,9 @@ extension ExplicitDependencyBuildPlanner {
429436
#else
430437
hashedArguments = SHA256().hash(hashInput).hexadecimalRepresentation
431438
#endif
432-
return moduleName + hashedArguments
439+
let resultingName = moduleName + hashedArguments
440+
hashedModuleNameCache[cacheQuery] = resultingName
441+
return resultingName
433442
}
434443
}
435444

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ extension Driver {
446446
/// to inputs and command line arguments of a compile job.
447447
func addExplicitModuleBuildArguments(inputs: inout [TypedVirtualPath],
448448
commandLine: inout [Job.ArgTemplate]) throws {
449-
guard let dependencyPlanner = explicitDependencyBuildPlanner else {
449+
guard var dependencyPlanner = explicitDependencyBuildPlanner else {
450450
fatalError("No dependency planner in Explicit Module Build mode.")
451451
}
452452
try dependencyPlanner.resolveMainModuleDependencies(inputs: &inputs, commandLine: &commandLine)

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,7 @@ extension Driver {
484484
explicitDependencyBuildPlanner =
485485
try ExplicitDependencyBuildPlanner(dependencyGraph: dependencyGraph,
486486
toolchain: toolchain,
487-
integratedDriver: integratedDriver,
488-
mainModuleName: moduleOutputInfo.name)
487+
integratedDriver: integratedDriver)
489488

490489
return try explicitDependencyBuildPlanner!.generateExplicitModuleDependenciesBuildJobs()
491490
}

0 commit comments

Comments
 (0)