[serialized_for_package] if Package CMO is enabled. The latter kind
allows a function to be serialized even if it contains loadable types,
if Package CMO is enabled. Renamed IsSerialized_t as SerializedKind_t.
The tri-state serialization kind requires validating inlinability
depending on the serialization kinds of callee vs caller; e.g. if the
callee is [serialized_for_package], the caller must be _not_ [serialized].
Renamed `hasValidLinkageForFragileInline` as `canBeInlinedIntoCaller`
that takes in its caller's SerializedKind as an argument. Another argument
`assumeFragileCaller` is also added to ensure that the calle sites of
this function know the caller is serialized unless it's called for SIL
inlining optimization passes.
The [serialized_for_package] attribute is allowed for SIL function, global var,
v-table, and witness-table.
Resolves rdar://128406520
package-wide resilience domain if Package CMO is enabled.
The purpose of the attribute includes:
- Indicates that certain types such as loadable types are
allowed in serialized functions in resiliently built module
if the optimization is enabled, which are otherwise disallowed.
- Used during SIL deserialization to determine whether such
functions are allowed.
- Used to determine if a callee can be inlined into a caller
that's serialized without package-cmo, e.g. with an explicit
annotation like @inlinable, where the callee was serialized
due to package-cmo.
Resolves rdar://127870822
enabled. If two modules are in the same package and package cmo is enabled,
v-table or witness-table calls should not be generated at the use site in the
client module. Modified conformance serialization check to allow serializing
witness thunks.
Also reordered SIL functions bottom-up so the most nested referenced functions
can be serialized first. Allowed serializing a function if a shared definition
(e.g. function `print`). Added a check for resilient mode wrt struct instructions.
Added tests for SIL tables and resilient mode on/off.
rdar://124632670
* Add a new flag -experimental-package-cmo that requires -experimental-allow-non-resilient-access.
* Support serializing package decls for CMO in package if enabled.
* Only applies to default mode CMO.
* Unlike the existing CMO, package CMO can be built with -enable-library-evolution as package
modules are required to be built together in the same project.
* Create hasPublicOrPackageVisibility to opt in for package decls; needed for CMO, SILVerifier,
and other call sites that verify or determine codegen.
Resolves rdar://121976014
Decls with a package access level are currently set to public SIL
linkages. This limits the ability to have more fine-grained control
and optimize around resilience and serialization.
This PR introduces a separate SIL linkage and FormalLinkage for
package decls, pipes them down to IRGen, and updates linkage checks
at call sites to include package linkage.
Resolves rdar://121409846
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.
This was a relict from the -sil-serialize-all days. This linkage doesn't make any sense because a private function cannot be referenced from another module (or file, in case of non-wmo compilation).
SILType and SILDeclRef do not actually need anything from SIL/*.h. Also,
a few dependencies can be pushed out of the headers into cpp files to
speed up incremental rebuilds.
We have a hack to handle "public" declarations in extensions to internal protcols that are
intended as default implementations for a public protocol that the internal protocol refines.
This hack failed to trigger for synthesized declarations with shared linkage, such as
automatically generated `read` coroutines, causing a visibility assertion failure where we would
try to refer to the non-serializable synthesized declaration from the witness thunk we would
normally consider serialized. Fixes rdar://problem/55846638.
* SILModule::isVisibleExternally utility for VarDecls.
* Fix the SIL parser so it doesn't drop global variable decls.
This information was getting lost in SIL printing/parsing.
Some passes rely on it. Regardless of whether passes should rely on it,
it is totally unacceptable for the SIL passes to have subtle differences
in behavior depending on the frontend mode. So, if we don't want passes
to rely on global variable decls, that needs to be enforced by the API
independent of how the frontend is invoked or how SIL is serialized.
* Use custom DemangleOptions to lookup global variable identifiers.
This is going to be used for "always emit into client" functions,
such as default argument generators and stored property
initializers.
- In dead function elimination, these functions behave identically to
public functions, serving as "anchors" for the mark-and-sweep
analysis.
- There is no external variant of this linkage, because external
declarations can use HiddenExternal linkage -- the definition should
always be emitted by another translation unit in the same Swift
module.
- When deserialized, they receive shared linkage, because we want the
linker to coalesce multiple copies of the same deserialized
definition if it was deserialized from multiple translation units
in the same Swift module.
- When IRGen emits a definition with this linkage, it receives the
same LLVM-level linkage as a hidden definition, ensuring it does not
have a public entry point.
Another cleanup before I add a new SILLinkage kind.
This operation is difficult to reason about and was only used by
the SIL verifier. Replace the SIL verifier checks with simpler
operations.
I still need to revisit and uncomment the default witness table
visibility check. Right now we serialize default witness tables,
but default witness thunks have private linkage, which is
clearly wrong.
"Accessibility" has a different meaning for app developers, so we've
already deliberately excised it from our diagnostics in favor of terms
like "access control" and "access level". Do the same in the compiler
now that we aren't constantly pulling things into the release branch.
Rename AccessibilityAttr to AccessControlAttr and
SetterAccessibilityAttr to SetterAccessAttr, then track down the last
few uses of "accessibility" that don't have to do with
NSAccessibility. (I left the SourceKit XPC API alone because that's
supposed to be more stable.)
Also, add a third [serializable] state for functions whose bodies we
*can* serialize, but only do so if they're referenced from another
serialized function.
This will be used for bodies synthesized for imported definitions,
such as init(rawValue:), etc, and various thunks, but for now this
change is NFC.
The SIL serializer can decide not to serialize the body of functions in the SIL
module, and only emit a declaration. If we keep the original linkage kind
(public, private, etc) then the deserialized module won't pass verification
because we do not allow internal functions to have external declarations. This
commit changes the linkage kind for the functions that the serializer decides to
emit as a declaration (without a body).
rdar://21989088
This re-applies commit r31763 with a change to the predicate we
use for determining the linkage of a definition. It turns out we
could have definitions with a Clang body that were still public,
so instead of checking for a Clang body just check if the Clang
declaration is externally visible or not.
Swift SVN r31777
If an external SIL function has a Clang-generated body, I think this
means we have a static function, and we want to use Shared linkage,
not Public.
Add a new flag to SILFunction for this and plumb it through to
appease assertions from SILVerifier.
Swift SVN r31763
This is controlled by a new isWholeModule() attribute in SILModule.
It gives about 9% code size reduction on the benchmark executables.
For test-suite reasons it is currently not done for the stdlib.
Swift SVN r22491
Now the SILLinkage for functions and global variables is according to the swift visibility (private, internal or public).
In addition, the fact whether a function or global variable is considered as fragile, is kept in a separate flag at SIL level.
Previously the linkage was used for this (e.g. no inlining of less visible functions to more visible functions). But it had no effect,
because everything was public anyway.
For now this isFragile-flag is set for public transparent functions and for everything if a module is compiled with -sil-serialize-all,
i.e. for the stdlib.
For details see <rdar://problem/18201785> Set SILLinkage correctly and better handling of fragile functions.
The benefits of this change are:
*) Enable to eliminate unused private and internal functions
*) It should be possible now to use private in the stdlib
*) The symbol linkage is as one would expect (previously almost all symbols were public).
More details:
Specializations from fragile functions (e.g. from the stdlib) now get linkonce_odr,default
linkage instead of linkonce_odr,hidden, i.e. they have public visibility.
The reason is: if such a function is called from another fragile function (in the same module),
then it has to be visible from a third module, in case the fragile caller is inlined but not
the specialized function.
I had to update lots of test files, because many CHECK-LABEL lines include the linkage, which has changed.
The -sil-serialize-all option is now handled at SILGen and not at the Serializer.
This means that test files in sil format which are compiled with -sil-serialize-all
must have the [fragile] attribute set for all functions and globals.
The -disable-access-control option doesn't help anymore if the accessed module is not compiled
with -sil-serialize-all, because the linker will complain about unresolved symbols.
A final note: I tried to consider all the implications of this change, but it's not a low-risk change.
If you have any comments, please let me know.
Swift SVN r22215
*NOTE* This linkage is different from {Public,Hidden}External in that it has no
extra semantic meaning beyond shared.
The use of this linkage is to ensure that we do not serialize deserialized
shared functions. Those shared functions can always be re-deserialized from the
original module. This prevents a whole class of bugs related to the
creation of module cross references since all references to the shared
item go straight to the original module.
<rdar://problem/17772847>
Swift SVN r20375
We now enforce via an assert that each witness table is unique and that
every protocol conformance that is referenceable from SIL must have a
witness table matched to it.
Also, I taught the linker that it should deserialize witness tables for
InitExistentialRefInst instructions, something that was missed before.
Swift SVN r17283
*NOTE* This is only to keep any less visible items from being exposed by
the inliner. Whether or not the callee has the proper linkage is for the
frontend/etc to ascertain.
Swift SVN r14824
In general, this forces SILGen and IRGen code that's grabbing
a declaration to state whether it's doing so to define it.
Change SIL serialization to serialize the linkage of functions
and global variables, which means also serializing declarations.
Change the deserializer to use this stored linkage, even when
only deserializing a declaration, and to call a callback to
inform the client that it has deserialized a new entity.
Take advantage of that callback in the linking pass to alter
the deserialized linkage as appropriate for the fact that we
imported the declaration. This computation should really take
advantage of the relationship between modules, but currently
it does not.
Swift SVN r12090