Commit Graph

1155 Commits

Author SHA1 Message Date
Ben Barham
6269643b4d [Index] Prevent re-indexing system modules repeatedly
If a module was first read using the adjacent swiftmodule and then
reloaded using the swiftinterface, we would do an up to date check on
the adjacent module but write out the unit using the swiftinterface.
This would cause the same modules to be indexed repeatedly for the first
invocation using a new SDK. On the next run we would instead raad the
swiftmodule from the cache and thus the out of date check would match
up.

The impact of this varies depending on the size of the module graph in
the initial compilation and the number of jobs started at the same time.
Each SDK dependency is re-indexed *and* reloaded, which is a drain on
both CPU and memory. Thus, if many jobs are initially started and
they're all going down this path, it can cause the system to run out of
memory very quickly.

Resolves rdar://103119964.
2023-02-09 11:49:13 -08:00
Alexis Laferrière
39fb1c5f55 [ModuleInterface] Intro export-as for Swift modules
Introduce a new flag `-export-as` to specify a name used to identify the
target module in swiftinterfaces. This provides an analoguous feature
for Swift module as Clang's `export_as` feature.

In practice it should be used when a lower level module `MyKitCore` is
desired to be shown publicly as a downstream module `MyKit`. This should
be used in conjunction with `@_exported import MyKitCore` from `MyKit`
that allows clients to refer to all services as being part of `MyKit`,
while the new `-export-as MyKit` from `MyKitCore` will ensure that the
clients swiftinterfaces also use the `MyKit` name for all services.

In the current implementation, the export-as name is used in the
module's clients and not in the declarer's swiftinterface (e.g.
`MyKitCore`'s swiftinterface still uses the `MyKitCore` module name).
This way the module swiftinterface can be verified. In the future, we
may want a similar behavior for other modules in between `MyKitCore` and
`MyKit` as verifying a swiftinterface referencing `MyKit` without it
being imported would fail.

rdar://103888618
2023-01-26 14:27:31 -08: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
Ellie Shin
7323d32ea4 Merge pull request #62700 from apple/es-pkg1
Add -package-name flag and de/serialize package name in module binary
Resoles rdar://103531218, rdar://103531208
2022-12-19 23:43:37 -08:00
Ellie Shin
72ee150982 Add -package-name flag
De/serialize package name in module binary
Resoles rdar://103531218, rdar://103531208
2022-12-19 14:33:44 -08:00
Artem Chikin
1230966e80 [Dependency Scanner] Rename 'ModuleDependenceis' -> 'ModuleDependencyInfo' 2022-12-15 14:18:29 -08:00
Artem Chikin
3db767843e [Dependency Scanning] Record whether discovered binary Swift modules are frameworks
Part of rdar://102824777
2022-12-13 10:44:37 -08:00
Adrian Prantl
a5e1786a99 Expose Swift search paths in validateSerializedAST
This is for the benefit of LLDB, which currently does an expensive import of all
modules to get to the same information.

rdar://40097459
2022-12-01 13:14:08 -08:00
Xi Ge
afbc4a5ffd Merge pull request #62251 from nkcsgexi/allowable-serialization
serialization: encode allowable client names in binary module format
2022-11-28 18:12:43 -08:00
Alexis Laferrière
c266e9dce5 Merge pull request #62185 from xymus/improve-rmodule-loading
Improve `-Rmodule-loading` to show both the path to the source and to the cached file actually loaded
2022-11-28 14:25:15 -08:00
Xi Ge
67bbab7e02 serialization: encode allowable client names in binary module format 2022-11-25 18:43:40 -08:00
Alexis Laferrière
319d49816d [Frontend] -Rmodule-loading shows both source path and cached path 2022-11-18 15:28:16 -08:00
Artem Chikin
729ad402df [Dependency Scanning] Produce canonical output path for Swift binary modules.
Instead of relying on the client (driver) to perform its own computation of the matching output path.
2022-11-15 11:08:13 -08:00
Alexis Laferrière
47b29b68db Merge pull request #61649 from xymus/index-swiftinterfaces
[Index] Force indexing of system modules to read only from swiftinterfaces
2022-10-31 14:18:45 -07:00
Alexis Laferrière
730497e9a3 [Serialization] Add control over adding a loaded module to the in-memory cache 2022-10-31 10:58:57 -07:00
Allan Shortlidge
af032afb9d Serialization: Break the cycle between Serialization and SymbolGraphGen.
Push the top level logic for writing out swiftmodules and associated files into the frontend library which has access to all the necessary dependencies.
2022-10-29 21:37:09 -07:00
Alexis Laferrière
2854c1b3cb [Serialization] Write in the swiftmodule if it's built from a swiftinterface
This information will allow us to distinguish swiftmodule built from
source vs swiftinterface.
2022-10-27 18:51:28 -07:00
Adrian Prantl
3cc2831608 Don't require a strict revision match in LLDB.
For release-management purposes during development, LLDB's embedded Swift
compiler's version number can sometimes be off-by-one in the last digit
compared to the Swift compiler.

This patch restores the old behavior from before 17183629e4.

rdar://101299168
2022-10-19 09:03:13 -07:00
Michael Gottesman
c54acc83e2 [move-only] Add the ability to specify a deinit at the SIL level for a move only type.
Specifically, we get an additional table like thing called sil_moveonlydeinit. It looks as follows:

sil_moveonlydeinit TYPE {
  @FUNC_NAME
}

It always has a single entry.
2022-09-20 15:19:31 -07:00
Allan Shortlidge
bbf189c8ab AST: Make the versioned variants of #if canImport() more reliable and consistent.
Previously, when evaluating a `#if canImport(Module, _version: 42)` directive the compiler could diagnose and ignore the directive under the following conditions:

- The associated binary module is corrupt/bogus.
- The .tbd for an underlying Clang module is missing a current-version field.

This behavior is surprising when there is a valid `.swiftinterface` available and it only becomes apparent when building against an SDK with an old enough version of the module that the version in the `.swiftinterface` is too low, making this failure easy to miss. Some modules have different versioning systems for their Swift and Clang modules and it can also be intentional for a distributed binary `.swiftmodule` to contain bogus data (to force the compiler to recompile the `.swiftinterface`) so we need to handle both of these cases gracefully and predictably.

Now the compiler will enumerate all module loaders, ask each of them to attempt to parse the module version and then consistently use the parsed version from a single source. The `.swiftinterface` is preferred if present, then the binary module if present, and then finally the `.tbd`. The `.tbd` is still always used exclusively for the `_underlyingVersion` variant of `canImport()`.

Resolves rdar://88723492
2022-09-07 14:18:05 -07:00
swift-ci
55000f53be Merge remote-tracking branch 'origin/main' into rebranch 2022-06-17 10:15:14 -07:00
Becca Royal-Gordon
9b5f89963b [NFC] Serialize ObjC selectors for protocols
The ObjCMethodLookupTable for protocols was not being serialized and rebuilt on load, so NominalTypeDecl::lookupDirect() on selectors was not working correctly for deserialized types. Correct this oversight.
2022-06-16 14:07:49 -07:00
swift-ci
f6cdcc736d Merge remote-tracking branch 'origin/main' into rebranch 2022-05-18 15:18:15 -07:00
Alexis Laferrière
c8059a09e9 [Serialization] Soft-reject swiftmodules built against a different SDK
Change the way swiftmodules built against a different SDK than their
clients are rejected. This makes them silently ignored when the module
can be rebuilt from their swiftinterface, instead of reporting a hard
error.

rdar://93257769
2022-05-16 13:22:35 -07:00
Ben Barham
427a689a96 [next] Convert const char * fields to StringRef
llvm/llvm-project d0262c2394f46bb7da2a75529413d625c70908e5 added a new
default bool param to the two constructors in `SmallVectorMemoryBuffer`.
Since `options.OutputPath` is a `const char *` and that can be promoted
to a `bool`, the constructor being called was changed to the first
constructor (with a default buffer name) - promotion is preferred over
conversion.

Convert the various output paths to a `StringRef` - all their uses
converted to `StringRef` anyway. Also specify the default parameter in
order to maintain the old behaviour, which didn't require a null
terminator.
2022-05-11 17:06:29 -07:00
Josh Soref
203b9ce33f Spelling serialization (#42515)
* spelling: absolute

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: ambiguous

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: attempting

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: attrs

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: dependency

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: extract

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: function

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interface

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: mandatory

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: nonexistent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: particular

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: related

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: signature

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specifies

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: that

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: without

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-25 12:58:35 -07:00
Erik Eckstein
6a020f8f15 Stabilize and simplify SIL linkage and serialization
The main point of this change is to make sure that a shared function always has a body: both, in the optimizer pipeline and in the swiftmodule file.
This is important because the compiler always needs to emit code for a shared function. Shared functions cannot be referenced from outside the module.
In several corner cases we missed to maintain this invariant which resulted in unresolved-symbol linker errors.

As side-effect of this change we can drop the shared_external SIL linkage and the IsSerializable flag, which simplifies the serialization and linkage concept.
2022-03-09 15:28:05 +01:00
Xi Ge
e1aaee4fec Frontend: add a frontend flag to generate empty ABI descriptors to workaround deserialization issues
ABI descriptors should always be emitted as sidecars for library-evolution-enabled modules.
However, generating these files requires traversing the entire module (like indexing), which may
hit additional deserialization issues. To unblock builds, this patch introduces a flag to skip
the traversing logic so that we emit an empty ABI descriptor file. The empty file serves as
a placeholder so that build system doesn't need to know the details.
2022-02-23 23:18:20 -08:00
Victoria Mitchell
cab1669e09 only recurse getDisplayDecls in SymbolGraphGen 2022-02-19 10:32:29 -07:00
ApolloZhu
683d469fcd Extends canImport to check for submodule availability 2021-12-28 22:54:47 -08:00
Alex Hoppen
fe7878ecce [Serialization] Improve module loading performance
When looking for a Swift module on disk, we were scanning all module search paths if they contain the module we are searching for. In a setup where each module is contained in its own framework search path, this scaled quadratically with the number of modules being imported. E.g. a setup with 100 modules being imported form 100 module search paths could cause on the order of 10,000 checks of `FileSystem::exists`. While these checks are fairly fast (~10µs), they add up to ~100ms.

To improve this, perform a first scan of all module search paths and list the files they contain. From this, create a lookup map that maps filenames to the search paths they can be found in. E.g. for
```
searchPath1/
  Module1.framework

searchPath2/
  Module1.framework
  Module2.swiftmodule
```
we create the following lookup table
```
Module1.framework -> [searchPath1, searchPath2]
Module2.swiftmodule -> [searchPath2]
```
2021-12-14 12:44:13 +01:00
Xi Ge
6377c3a742 Revert "Revert "serialization: obfuscate the serialized search paths"" 2021-12-02 13:21:04 -08:00
Saleem Abdulrasool
11d5d6d4ca Revert "serialization: obfuscate the serialized search paths" 2021-12-02 08:18:23 -08:00
Xi Ge
0047d81f9a serialization: obfuscate the serialized search paths
We noticed some Swift clients rely on the serialized search paths in the module to
find dependencies and droping these paths altogether can lead to build failures like
rdar://85840921.

This change teaches the serialization to obfuscate the search paths and the deserialization
to recover them. This allows clients to keep accessing these paths without exposing
them when shipping the module to other users.
2021-12-01 11:47:41 -08:00
Kuba (Brecka) Mracek
c89eca6c34 Enforce consistent usage of -experimental-hermetic-seat-at-link flag (#39986)
We've recently added the -experimental-hermetic-seal-at-link compiler flag,
which turns on aggressive dead-stripping optimizations and assumes that library
code can be optimized against client code because all users of the library
code/types are present at link/LTO time. This means that any module that's
built with -experimental-hermetic-seal-at-link requires all clients of this
module to also use -experimental-hermetic-seal-at-link. This PR enforces that
by storing a bit in the serialized module, and checking the bit when importing
modules.
2021-11-30 10:44:58 -08:00
Victoria Mitchell
156e58d69a use symbol graph opts instead of serialization opts for SGFs 2021-10-21 17:12:49 -06:00
swift-ci
3f8fea8508 Merge remote-tracking branch 'origin/main' into rebranch 2021-10-06 10:17:29 -07:00
Richard Howell
140c02466a Add -prefix-serialized-debugging-options (#39555)
This commit adds a new frontend flag that applies debug path prefixing to the
paths serialized in swiftmodule files. This makes it possible to use swiftmodule
files that have been built on different machines by applying the inverse map
when debugging, in a similar fashion to source path prefixing.

The inverse mapping in LLDB will be handled in a follow up PR.

Second pass at #39138

Tests updated to handle windows path separators.

This reverts commit f5aa95b381.
2021-10-04 22:41:32 -07:00
Meghana Gupta
f458d9b490 Fix unnecessary one-time recompile of stdlib with -enable-ossa-flag (#39516)
* Fix unnecessary one-time recompile of stdlib with -enable-ossa-flag

This includes a bit in the module format to represent if the module was
compiled with -enable-ossa-modules flag. When compiling a client module
with -enable-ossa-modules flag, all dependent modules are checked for this bit,
if not on, recompilation is triggered with -enable-ossa-modules.

* Updated tests
2021-10-04 18:46:40 -07:00
Saleem Abdulrasool
f5aa95b381 Revert "Add -prefix-serialized-debugging-options" (#39544)
Reverts #39138

This is causing a failure on Windows: https://ci-external.swift.org/job/oss-swift-windows-x86_64-vs2019/6659/consoleText
2021-10-01 11:19:44 -07:00
swift-ci
c51550f30e Merge remote-tracking branch 'origin/main' into rebranch 2021-09-30 15:11:41 -07:00
Richard Howell
ce6b4b3ee0 Add -prefix-serialized-debugging-options
This commit adds the `-prefix-serialized-debugging-options` flag,
which is used to apply the debug prefix map to serialized debugging
options embedded in the swiftmodule files.
2021-09-30 08:18:03 -07:00
swift-ci
f8df0dc8a2 Merge remote-tracking branch 'origin/main' into rebranch 2021-09-21 19:53:25 -07:00
Xi Ge
fef225c272 Merge pull request #39387 from nkcsgexi/emit-module-emit-abi
Frontend: teach -emit-module and -merge-modules to emit ABI descriptor files
2021-09-21 19:49:39 -07:00
swift-ci
4ec5df9a2a Merge remote-tracking branch 'origin/main' into rebranch 2021-09-21 16:53:46 -07:00
Xi Ge
f97653ef37 Frontend: teach -emit-module and -merge-modules to emit ABI descriptor files 2021-09-21 16:51:52 -07:00
Alexis Laferrière
5c2122a08c [Serialization] Restrict resilient swiftmodules to the compiler that built them
Introduce a new loading restriction that is more strict than the serialization
version check on swiftmodules. Tagged compilers will only load
library-evolution enabled swiftmodules that are produced by a compiler with the
exact same revision id. This will be more reliable in production
environments than using the serialization version which we forgot to
update from time to time. This shouldn't affect development compilers that
will still load any module with a compatible serialization version.

rdar://83105234
2021-09-20 18:06:35 -07:00
adrian-prantl
fcc77a67df Merge pull request #39032 from adrian-prantl/79462915-5.5
Disable resilience for modules imported by the MemoryBuffer loader.
2021-09-20 16:45:19 -07:00
Alexis Laferrière
c38d1773d2 [Serialization] Restrict loading swiftmodule files to the builder's SDK
Serialize the canonical name of the SDK used when building a swiftmodule
file and use it to ensure that the swiftmodule file is loaded only with
the same SDK. The SDK name must be passed down from the frontend.

This will report unsupported configurations like:

- Installing roots between incompatible SDKs without deleting the
swiftmodule files.
- Having multiple targets in the same project using different SDKs.
- Loading a swiftmodule created with a newer SDK (and stdlib) with an
older SDK.

All of these lead to hard to investigate deserialization failures and
this change should detect them early, before reaching a deserialization
failure.

rdar://78048939
2021-09-13 16:44:08 -07:00
Artem Chikin
1b7d55582d Do not build Swift interface files into binary modules when performing a canImport query.
We should hold off actually building the binary module file until it is imported.
`canImport` queries can happen, for example, during dependency scanning, when we do not wish to have the scanner tool execute any module builds.

Resolves rdar://82603098
2021-09-02 12:09:57 -07:00