Commit Graph

120 Commits

Author SHA1 Message Date
Steven Wu
9607e9dec1 Merge pull request #71497 from cachemeifyoucan/eng/PR-122423965
[Caching] Use subInvocation to verify interface
2024-02-13 09:18:40 -08:00
Steven Wu
3986937e03 [Caching][NFC] Restructure CASOption in swift. NFC
Clean up how CASOptions are kept and passed inside swift to make the
code more readable. Also avoid a copy of CAS configuration in
ClangImporter.
2024-02-11 14:08:09 -08:00
Artem Chikin
f45db99c04 [Dependency Scanning] Improve the cycle-detection diagnostic for Swift overlay dependencies
Add tracing of the underlying Clang module for an overlay dependency if said overlay dependency forms a cycle
2024-02-08 08:54:14 -08:00
Artem Chikin
7e9fee08df Merge pull request #71399 from artemcm/DependencyScanningToolIsolation
[DependencyScanning] Isolate `DependencyScanningTool` reset operations
2024-02-05 18:32:17 -08:00
Artem Chikin
0046165dad [DependencyScanning] Isolate 'DependencyScanningTool' reset operations
Guard 'resetCache' and 'resetDiagnostics' as critical sections using 'DependencyScanningToolStateLock'. Otherwise there's a chance that one thread in the scanner is doing a reset on the diagnostic consumer, while some other thread is adding this diagnostic consumer to another scan instance which may also be populating said consumer at the time. Similarly, for resetting 'ScanningService' though it is much more unlikely to be reset while in-use by other scanning actions.
2024-02-05 16:00:39 -08:00
Allan Shortlidge
8846f4e691 [SE-0364] Handle retroactive conformance for types and protocols from underlying modules.
SE-0364 was implemented to discourage "retroactive" conformances that might
conflict with conformances that could be introduced by other modules in the
future. These diagnostics should not apply to conformances that involve types
and protocols imported from the underlying clang module of a Swift module since
the two modules are assumed to be developed in tandem by the same owners,
despite technically being separate modules from the perspective of the
compiler.

The diagnostics implemented in https://github.com/apple/swift/pull/36068 were
designed to take underlying clang modules into account. However, the
implementation assumed that `ModuleDecl::getUnderlyingModuleIfOverlay()` would
behave as expected when called on the Swift module being compiled.
Unfortunately, it would always return `nullptr` and thus conformances involving
the underlying clang module are being diagnosed unexpectedly.

The fix is to make `ModuleDecl::getUnderlyingModuleIfOverlay()` behave as
expected when it is made up of `SourceFile`s.

Resolves rdar://121478556
2024-02-01 10:43:53 -08:00
Artem Chikin
33e09f9e87 Merge pull request #70211 from artemcm/ParallelScanFixes
[Dependency Scanning] Remove/move mutable state from parallel scanner workers
2023-12-15 11:14:16 -08:00
Steven Wu
cbf2bfb6d3 [Caching] Fix a typo in legacy layout file name
Fix a typo in the name of legacy layout file name that causes the legacy
layouts are not ingested into the CASFS for cached compilation.

rdar://119622429
2023-12-13 10:59:52 -08:00
Artem Chikin
ff63a900aa [Dependency Scanning] Remove 'overlaySharedFilesystemCacheForCompilation' from the scanner. It overlays a non-thread-safe filesystem on shared compilation instances and is no longer valid with parallel scanning. 2023-12-04 12:34:41 -08:00
Artem Chikin
6da6a7bd3f Remove OptimizeArgs = true on the ClangDependencyScanningService init (#70145)
* Remove 'OptimizeArgs = true' on the ClangDependencyScanningService init

With the new API this is no longer a boolean and the new default value of 'ScanningOptimizations::Default' matches the behavior we had prior to this change.
2023-12-01 08:41:23 -08:00
Artem Chikin
9c58b9f5f5 [Dependency Scanning] Detect and ignore (and warn about) tautological imports
This matches the current behavior in `ImportResolution`. The change refactors an existing utility function to do this check from `UnboundImport` to a common utility used now also in the scanner.
2023-11-01 06:46:42 -07:00
Artem Chikin
4a0a2f3607 [Dependency Scanning] Special-case imports of the 'Builtin' module not referencing an "actual" module
Otherwise the scanner will attempt to locate such a module on the filesystem and fail, because it does not exist.
2023-10-25 15:01:13 -07:00
Artem Chikin
9615729d0b [Dependency Scanning] Handle binary module dependencies' Swift overlay dependencies
The code, previously, only properly handled such dependencies being a distinct category for Swift source and Swift textual dependency infos. Swift binary module dependencies must handle this similarly and this change adds the missing support for them. Recent refactor of the scanner also means that now Swift binary dependencies with Swift overlay dependencies may crash the scanner, and this change resolves this as well.

Resolves rdar://117088840
2023-10-18 09:46:34 -07:00
Steven Wu
7b89afbb6e [DepScan] Teach dependency scanner to remap path for canonicalization
Allow DependencyScanner to canonicalize path using a prefix map. When
option `-scanner-prefix-map` option is used, dependency scanner will
remap all the input paths in following:
* all the paths in the CAS file system or clang include tree
* all the paths related to input on the command-line returned by scanner

This allows all the input paths to be canonicalized so cache key can be
computed reguardless of the exact on disk path.

The sourceFile field is not remapped so build system can track the exact
file as on the local file system.
2023-09-26 12:36:43 -07:00
Artem Chikin
b4dfb6baa1 [Dependency Scanning] Implement parallel imported module resolution
'ModuleDependencyScanner' maintains a Thread Pool along with a pool of workers
which are capable of executing a filesystem lookup of a named module dependency.
When resolving imports of a given Swift module, each import's resolution
operation can be issued asunchronously.
2023-09-22 14:11:26 -07:00
Artem Chikin
6e3f896962 [Dependency Scanning] Refactor primary scan operations into 'ModuleDependencyScanner' class
From being a scattered collection of 'static' methods in ScanDependencies.cpp
and member methods of ASTContext. This makes 'ScanDependencies.cpp' much easier
to read, and abstracts the actual scanning logic away to a place with common
state which will make it easier to reason about in the future.
2023-09-22 14:09:45 -07:00
Artem Chikin
4610a83bdf [Dependency Scanning] Remove Swift Overlay dependencies from the set of direct
dependencies

It is valuable for clients to be able to distinguish which dependencies of a
Swift module originated from 'import' statements, and which ones are implicit
dependency Swift overlays of imported Clang modules.
2023-08-17 11:38:09 -07:00
Artem Chikin
6ef79c4ba0 [Dependency Scanning] Specify Explicit Module output path to the scanner explicitly
Instead of the code querying the compiler's built-in Clang instance, refactor the
dependency scanner to explicitly keep track of module output path. It is still
set according to '-module-cache-path' as it has been prior to this change, but
now the scanner can use a different module cache for scanning PCMs, as specified
with '-clang-scanner-module-cache-path', without affecting module output path.

Resolves rdar://113222853
2023-08-10 11:11:05 -07:00
Steven Wu
c470c81b9c Merge pull request #66940 from cachemeifyoucan/eng/PR-dep-sharing-serivce-issue
[CAS][DependencyScanning] Don't keep a shared state of common file deps
2023-06-30 11:56:14 -07:00
Steven Wu
bed01ade89 [CAS][DependencyScanning] Don't keep a shared state of common file deps
Unlike `swift-frontend -scan-dependencies` option, when dependency
scanner is used as a library by swift driver, the SwiftScanningService
is shared for multiple driver invocations. It can't keep states (like
common file dependencies) that can change from one invocation to
another.

Instead, the clang/SDK file dependencies are computed from each driver
invocations to avoid out-of-date information when scanning service is
reused.

The test case for a shared Service will be added to swift-driver repo
since there is no tool to test it within swift compiler.
2023-06-27 09:50:26 -07:00
Evan Wilde
250082df25 [NFC] Reformat all the LLVMs
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
2023-06-27 09:03:52 -07:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Steven Wu
284eb2a264 [NFC] Cleanup deprecated Optional API usage in depscan 2023-06-26 10:34:27 -07:00
Steven Wu
b78b569450 [CAS] Consolidate compile cache flags
Rename `-enable-cas` to `-compile-cache-job` to align with clang option
names and promote that to a new driver only flag.

Few other additions to driver flag for caching behaviors:
* `-compile-cache-remarks`: now cache hit/miss remarks are guarded behind
  this flag
* `-compile-cache-skip`: skip replaying from the cache. Useful as a
  debugging tool to do the compilation using CAS inputs even the output
  is a hit from the cache.
2023-06-26 10:34:27 -07:00
Steven Wu
744e01ea47 [CAS] Allow SwiftDependencyScanningService be shared
When the CASOptions are the same, SwiftDependencyScanningService can be
shared with multiple swift driver invocation for scanning.
2023-06-26 10:34:26 -07:00
Steven Wu
2b7d38dc16 [CAS] Improve swift cas options
Using the same CASOption from clang to communicate CAS configurations so
it is easier to exchange CAS configuration between them.
2023-06-26 10:34:26 -07:00
Steven Wu
07a35e9bd3 [CAS] Workaround the missing file system dependency from clang importer 2023-06-20 14:04:01 -07:00
Steven Wu
b1f99b8e93 [CAS] swift dependency scanning using CAS for compiler caching (#66366)
Teach swift dependency scanner to use CAS to capture the full dependencies for a build and construct build commands with immutable inputs from CAS.

This allows swift compilation caching using CAS.
2023-06-12 10:55:53 -07:00
Artem Chikin
5ca91786ec [Dependency Scanning] Break out Swift overlay dependencies into separate output category
Instead of being a part of 'directDependencies' on a module dependency info, make them a separate array of dependency IDs for Swift Source and Textual modules.

This will allow clients to still distinguish direct module dependencies imported from a given module, versus dependencies added because direct/transitive Clang module dependencies have Swift overlays.

This change does *not* remove overlay dependencies from 'directDependencies' yet, just adds them as a separate field on the module details info. A followup change will remove overlay and bridging header dependencies from 'directDependencies' once the clients have had a chance to adopt to this change.
2023-05-19 14:47:43 -07:00
Artem Chikin
6fcd8be072 [Dependency Scanning] Pull optional dependencies from the adjacent binary module for direct interface dependencies
For a `@Testable` import in program source, if a Swift interface dependency is discovered, and has an adjacent binary `.swiftmodule`, open up the module, and pull in its optional dependencies. If an optional dependency cannot be resolved on the filesystem, fail silently without raising a diagnostic.
2023-04-17 14:47:46 -07:00
Artem Chikin
10fb324d1f [Dependency Scanning] Keep track of which direct dependencies are '@testable' for a Source dependency 2023-04-17 13:37:08 -07:00
Artem Chikin
e0eeb6339b [Dependency Scanning] Teach dependency scanner to resolve optional dependencies of a module 2023-04-17 13:36:53 -07:00
Artem Chikin
e8895f721a [Dependency Scanning] Do not track source module dependencies separately in SwiftDependencyScanningService
Instead, treat them like any other module that is specific to the scanning context hash of the scan it originates from.
Otherwise we may actually have simultaneous scans happening for the same source module but with different context hashes, and the current scheme leads to collisions.
2023-03-30 11:27:08 -07:00
Artem Chikin
3d110f8c74 [Dependency Scanning] Isolate shared dependency scanner state
Using mutual exclusion, ensuring that multiple threads executing dependency scans do not encounter data races on shared mutable state.

There are two layers with shared state where we need to be careful:
- `DependencyScanningTool`, as the main entity that scanning clients interact with. This tool instantiates compiler instances for individual scans, computing a scanning invocation hash. It needs to remember those instances for future use, and when creating instances it needs to reset LLVM argument processor's global state, meaning all uses of argument processing must be in a critical section.

- `SwiftDependencyScanningService`, as the main cache where dependency scanning results are stored. Each individual scan instantiates a `ModuleDependenciesCache`, which uses the scanning service as the underlying storage. The services' storage is segmented to storing dependencies discovered in a scan with a given context hash, which means two different scanning invocations running at the same time will be accessing different locations in its storage, thus not requiring synchronization. But the service still has some shared state that must be protected, such as the collection of discovered source modules, and the map used to query context-hash-specific underlying cache storage.
2023-03-27 10:29:10 -07:00
Artem Chikin
4ed874c276 [Dependency Scanning] Do not add extra search paths to the Clang's explicit PCM prebuild commands
Clang dependency scanner's output will be complete here w.r.t. the required search paths.

Resolves rdar://107018240
2023-03-22 09:36:17 -07:00
Ben Langmuir
7b460fb4ca [Dependency Scanner] Update for clang API change
* Service takes a CAS parameter now
* Also remove a flag that has been removed for a while now (the flags
  are OptimizeArgs and EagerLoad now).
2023-03-14 20:06:17 -07:00
Artem Chikin
b1707ef534 Merge pull request #63201 from artemcm/ScannerNoPriorSourceDeps
[Dependency Scanner] Do not re-use prior source dependencies in successive scans
2023-01-26 08:57:00 -08:00
Artem Chikin
e2eb8c8f47 [Dependency Scanner] Do not re-use prior source dependencies in successive scans
If a scanner instance is used for multiple scans, the `SwiftDependencyScanningService` will have collected prior scans' main source modules' dependency info.
Suppose the scanner first scans a source module `A` and records its dependencies. If a successive scan of some source module `B` finds that it depends on `A`, it would get a cache hit on the source module from a prior scan and re-use dependency information. This change no longer allows such re-use of the prior source module scan dependencies. Said prior scan may have had an entirely different context and therefore different set of dependencies on `A` than may be visible otherwise. Instead, all scanning actions must rely on such modules being re-discovered on the filesystem.
2023-01-25 16:47:38 -08:00
Erik Eckstein
7d8bf37e5e change to the new llvm::Optional APIs
This is a follow-up of https://github.com/apple/swift/pull/62217
2023-01-25 09:18:36 +01:00
Artem Chikin
12477b7b79 [Dependency Scanning] Refactor the scanner to resolve unqualified module imports
This changes the scanner's behavior to "resolve" a discovered module's dependencies to a set of Module IDs: module name + module kind (swift textual, swift binary, clang, etc.).

The 'ModuleDependencyInfo' objects that are stored in the dependency scanner's cache now carry a set of kind-qualified ModuleIDs for their dependencies, in addition to unqualified imported module names of their dependencies.

Previously, the scanner's internal state would cache a module dependnecy as having its own set of dependencies which were stored as names of imported modules. This led to a design where any time we needed to process the dependency downstream from its discovery (e.g. cycle detection, graph construction), we had to query the ASTContext to resolve this dependency's imports, which shouldn't be necessary. Now, upon discovery, we "resolve" a discovered dependency by executing a lookup for each of its imported module names (this operation happens regardless of this patch) and store a fully-resolved set of dependencies in the dependency module info.

Moreover, looking up a given module dependency by name (via `ASTContext`'s `getModuleDependencies`) would result in iterating over the scanner's module "loaders" and querying each for the module name. The corresponding modules would then check the scanner's cache for a respective discovered module, and if no such module is found the "loader" would search the filesystem.

This meant that in practice, we searched the filesystem on many occasions where we actually had cached the required dependency, as follows:
Suppose we had previously discovered a Clang module "foo" and cached its dependency info.
-> ASTContext.getModuleDependencies("foo")
--> (1) Swift Module "Loader" checks caches for a Swift module "foo" and doesn't find one, so it searches the filesystem for "foo" and fails to find one.
--> (2) Clang Module "Loader" checks caches for a Clang module "foo", finds one and returns it to the client.

This means that we were always searching the filesystem in (1) even if we knew that to be futile.
With this change, queries to `ASTContext`'s `getModuleDependencies` will always check all the caches first, and only delegate to the scanner "loaders" if no cached dependency is found. The loaders are then no longer in the business of checking the cached contents.

To handle cases in the scanner where we must only lookup either a Swift-only module or a Clang-only module, this patch splits 'getModuleDependencies' into an alrady-existing 'getSwiftModuleDependencies' and a newly-added 'getClangModuleDependencies'.
2023-01-05 11:44:06 -08:00
Artem Chikin
a59db26a55 [Dependency Scanner] Rename 'GlobalModuleDependenciesCache' -> 'SwiftDependencyScanningService' 2022-12-19 11:08:50 -08:00
Artem Chikin
1230966e80 [Dependency Scanner] Rename 'ModuleDependenceis' -> 'ModuleDependencyInfo' 2022-12-15 14:18:29 -08:00
Artem Chikin
44a8f99d19 [DependencyScanning] Count target variant, clang target, and sdk versions as components of scanning context hash
Resolves rdar://103093122
2022-12-09 09:24:44 -08:00
Artem Chikin
9f62b19058 [Dependency Scanning] Use persistent dependency scanning filesystem in the Swift dependency scanner
Adopts Clang's 'DependencyScanningWorkerFilesystem' for use by the scanner, with the persistent
scanner instance keeping a 'DependencyScanningFilesystemSharedCache'.
2022-12-08 11:41:20 -08:00
Artem Chikin
f39c6385df [Dependency Scanning] Do not disambiguate 'GlobalModuleDependenciesCache' by search path set
This is no longer necessary since the cache is always configured for the current scanning context hash, which includes the search path set.
2022-12-06 14:15:39 -08:00
Artem Chikin
990b95e9d8 [Dependency Scanning] Key into a global (shared) dependency scanning cache via context hash
Introduces a concept of a dependency scanning action context hash, which is used to select an instance of a global dependency scanning cache which gets re-used across dependency scanning actions.
2022-12-06 08:26:28 -08:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01:00
Artem Chikin
11cd472f14 [Dependency Scanning] Configure the Clang dependency scanner to generate PCM output paths
Using the convention of : <Module_Cache_Path> + "/" + <Module_Name> + "-" + <Context_Hash> + ".pcm"
2022-11-09 09:49:35 -08:00
Artem Chikin
b426757eda [Dependency Scanning] Share the Clang Dependency Scanning service among scanner invocations.
It was recently moved to the ModuleDependenciesCache. This is undesireable, instead this should live in the GlobalModuleDependenciesCache so that we benefit from the filesystem caching it performs across diferent scanning actions.
2022-09-29 16:06:56 -07:00
Artem Chikin
96a82cdf9a [Dependency Scanner] Clean up/Gardening on 'ClangModuleDependencyScanner'
Move clangScanningTool and clangScanningService to be parts of 'ModuleDependenciesCache' state, getting rid of the 'ClangModuleDependenciesCacheImpl', which is no-longer needed since we moved moved to by-name lookup of Clang modules.
2022-09-12 15:10:43 -07:00