Skip to content

[Dependency Scanning] Adapt to changes in dependenncy scanner to capture initial PCM arguments #848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Sources/CSwiftScan/include/swiftscan_header.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ typedef struct {
(*swiftscan_clang_detail_get_context_hash)(swiftscan_module_details_t);
swiftscan_string_set_t *
(*swiftscan_clang_detail_get_command_line)(swiftscan_module_details_t);
swiftscan_string_set_t *
(*swiftscan_clang_detail_get_captured_pcm_args)(swiftscan_module_details_t);

//=== Batch Scan Input Functions ------------------------------------------===//
swiftscan_batch_scan_input_t *
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ internal extension Driver {
return moduleInfos
}.reduce([], +)

guard !batchScanInputList.isEmpty else {
// If no new re-scans are needed, we are done here.
return
}

// Batch scan all clang modules for each discovered new, unique set of PCMArgs, per module
let moduleVersionedGraphMap: [ModuleDependencyId: [InterModuleDependencyGraph]] =
try performBatchDependencyScan(moduleInfos: batchScanInputList)
Expand Down Expand Up @@ -142,7 +147,7 @@ private extension InterModuleDependencyGraph {
// captured in the described dependencies of this module. Only re-scan at PCMArgs not
// already captured.
let alreadyCapturedPCMArgs =
clangModuleDetails.dependenciesCapturedPCMArgs ?? Set<[String]>()
clangModuleDetails.capturedPCMArgs ?? Set<[String]>()
let newPCMArgSet = pathPCMArtSet.filter { !alreadyCapturedPCMArgs.contains($0) }
// Add current path's PCMArgs to the SetMap and stop traversal
if pcmArgSetMap[moduleId] != nil {
Expand Down Expand Up @@ -183,10 +188,10 @@ private extension InterModuleDependencyGraph {
throw Driver.Error.malformedModuleDependency(moduleId.moduleName,
"no Clang `details` object")
}
if clangModuleDetails.dependenciesCapturedPCMArgs == nil {
clangModuleDetails.dependenciesCapturedPCMArgs = Set<[String]>()
if clangModuleDetails.capturedPCMArgs == nil {
clangModuleDetails.capturedPCMArgs = Set<[String]>()
}
newPCMArgs.forEach { clangModuleDetails.dependenciesCapturedPCMArgs!.insert($0) }
newPCMArgs.forEach { clangModuleDetails.capturedPCMArgs!.insert($0) }
modules[moduleId]!.details = .clang(clangModuleDetails)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ extension InterModuleDependencyGraph {

// As far as their dependencies go, these module infos are identical
if firstInfo.directDependencies == secondInfo.directDependencies,
firstDetails.dependenciesCapturedPCMArgs == secondDetails.dependenciesCapturedPCMArgs,
firstDetails.capturedPCMArgs == secondDetails.capturedPCMArgs,
firstInfo.sourceFiles == secondInfo.sourceFiles {
return firstInfo
}
Expand All @@ -198,15 +198,15 @@ extension InterModuleDependencyGraph {
let secondModuleDependencies = secondInfo.directDependencies ?? []
let combinedDependencies = Array(Set(firstModuleDependencies + secondModuleDependencies))

let firstModuleCapturedPCMArgs = firstDetails.dependenciesCapturedPCMArgs ?? Set<[String]>()
let secondModuleCapturedPCMArgs = secondDetails.dependenciesCapturedPCMArgs ?? Set<[String]>()
let firstModuleCapturedPCMArgs = firstDetails.capturedPCMArgs ?? Set<[String]>()
let secondModuleCapturedPCMArgs = secondDetails.capturedPCMArgs ?? Set<[String]>()
let combinedCapturedPCMArgs = firstModuleCapturedPCMArgs.union(secondModuleCapturedPCMArgs)

let combinedModuleDetails =
ClangModuleDetails(moduleMapPath: firstDetails.moduleMapPath,
dependenciesCapturedPCMArgs: combinedCapturedPCMArgs,
contextHash: firstDetails.contextHash,
commandLine: firstDetails.commandLine)
commandLine: firstDetails.commandLine,
capturedPCMArgs: combinedCapturedPCMArgs)

return ModuleInfo(modulePath: firstInfo.modulePath,
sourceFiles: combinedSourceFiles,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,24 +151,24 @@ public struct ClangModuleDetails: Codable {
/// The path to the module map used to build this module.
public var moduleMapPath: TextualVirtualPath

/// Set of PCM Arguments of depending modules which
/// are covered by the directDependencies info of this module
public var dependenciesCapturedPCMArgs: Set<[String]>?

/// clang-generated context hash
public var contextHash: String

/// Options to the compile command
public var commandLine: [String] = []

/// Set of PCM Arguments of depending modules which
/// are covered by the directDependencies info of this module
public var capturedPCMArgs: Set<[String]>?

public init(moduleMapPath: TextualVirtualPath,
dependenciesCapturedPCMArgs: Set<[String]>?,
contextHash: String,
commandLine: [String]) {
commandLine: [String],
capturedPCMArgs: Set<[String]>?) {
self.moduleMapPath = moduleMapPath
self.dependenciesCapturedPCMArgs = dependenciesCapturedPCMArgs
self.contextHash = contextHash
self.commandLine = commandLine
self.capturedPCMArgs = capturedPCMArgs
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public class InterModuleDependencyOracle {
guard let swiftScan = swiftScanLibInstance else {
fatalError("Attempting to serialize scanner cache with no scanner instance.")
}
if swiftScan.canLoadStoreScannerCache() {
if swiftScan.canLoadStoreScannerCache {
swiftScan.serializeScannerCache(to: path)
}
}
Expand All @@ -96,7 +96,7 @@ public class InterModuleDependencyOracle {
guard let swiftScan = swiftScanLibInstance else {
fatalError("Attempting to load scanner cache with no scanner instance.")
}
if swiftScan.canLoadStoreScannerCache() {
if swiftScan.canLoadStoreScannerCache {
return swiftScan.loadScannerCache(from: path)
}
return false
Expand All @@ -106,7 +106,7 @@ public class InterModuleDependencyOracle {
guard let swiftScan = swiftScanLibInstance else {
fatalError("Attempting to reset scanner cache with no scanner instance.")
}
if swiftScan.canLoadStoreScannerCache() {
if swiftScan.canLoadStoreScannerCache {
swiftScan.resetScannerCache()
}
}
Expand Down
14 changes: 12 additions & 2 deletions Sources/SwiftDriver/SwiftScan/DependencyGraphBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,20 @@ private extension SwiftScan {
using: api.swiftscan_clang_detail_get_command_line,
fieldName: "clang_detail.commandLine")

let capturedPCMArgs : Set<[String]>?
if clangDetailsHaveCapturedPCMArgs {
let capturedArgs = try getStringArrayDetail(from: moduleDetailsRef,
using: api.swiftscan_clang_detail_get_captured_pcm_args,
fieldName: "clang_detail.capturedPCMArgs")
capturedPCMArgs = [capturedArgs]
} else {
capturedPCMArgs = nil
}

return ClangModuleDetails(moduleMapPath: moduleMapPath,
dependenciesCapturedPCMArgs: nil,
contextHash: contextHash,
commandLine: commandLine)
commandLine: commandLine,
capturedPCMArgs: capturedPCMArgs)
}
}

Expand Down
16 changes: 12 additions & 4 deletions Sources/SwiftDriver/SwiftScan/SwiftScan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,14 @@ internal final class SwiftScan {
return resultGraphMap
}

@_spi(Testing) public func canLoadStoreScannerCache() -> Bool {
return api.swiftscan_scanner_cache_load != nil &&
api.swiftscan_scanner_cache_serialize != nil &&
api.swiftscan_scanner_cache_reset != nil
@_spi(Testing) public var canLoadStoreScannerCache : Bool {
api.swiftscan_scanner_cache_load != nil &&
api.swiftscan_scanner_cache_serialize != nil &&
api.swiftscan_scanner_cache_reset != nil
}

@_spi(Testing) public var clangDetailsHaveCapturedPCMArgs : Bool {
api.swiftscan_clang_detail_get_captured_pcm_args != nil
}

func serializeScannerCache(to path: AbsolutePath) {
Expand Down Expand Up @@ -289,6 +293,10 @@ private extension swiftscan_functions_t {
self.swiftscan_scanner_cache_reset =
try loadOptional("swiftscan_scanner_cache_reset")

// Clang dependency captured PCM args
self.swiftscan_clang_detail_get_captured_pcm_args =
try loadOptional("swiftscan_clang_detail_get_captured_pcm_args")

// MARK: Required Methods
func loadRequired<T>(_ symbol: String) throws -> T {
guard let sym: T = dlsym(swiftscan, symbol: symbol) else {
Expand Down