To ensure that dependent values have a persistent-enough memory representation
to point into, when an immutable binding is referenced as an addressable
argument to a call, have SILGen retroactively emit a stack allocation and
materialization that covers the binding's scope.
To ensure that dependent values have a persistent-enough memory representation
to point into, when an immutable binding is referenced as an addressable
argument to a call, have SILGen retroactively emit a stack allocation and
materialization that covers the binding's scope.
This PR contains changes that ensure the following:
* Global accessor linkage is kept hidden if its decl is resilient.
- LinkageLimit::Never is returned for Global Accessor if its decl is resilient.
- Since it's kept hidden, the use site should not expect a call to a global accessor
if the static var decl being accessed is resilient. The bypassing resilience logic
in AbstractStorageDecl::isResilient(accessingModule, decl) has been removed; to be
addressed in Package CMO optimization pass.
* sil_global linkage is kept private if its decl is resilient.
Resolves rdar://129829925
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
[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
Optionally, the dependency to the initialization of the global can be specified with a dependency token `depends_on <token>`.
This is usually a `builtin "once"` which calls the initializer for the global variable.
As a follow up to https://github.com/apple/swift/pull/69841, clarify the
possible states that initializer expression of a pattern can be in. The
possible states are not checked, checked, and "checked and contextualized"
(which is the new state that was introduced and requestified in the previous
PR). This refactoring encodes the states more explicitly and renames a few
compiler APIs to better align with the new naming. NFC.
Allow initializer expressions to be emitted during SILGen when
`-experimental-lazy-typecheck` is specified by introducing a new request that
fully typechecks the init expressions of pattern binding declarations
on-demand.
There are still a few rough edges, like missing support for wrapped properties
and incomplete handling of subsumed initializers. Fixing these issues is not an
immediate priority because in the short term `-experimental-lazy-typecheck`
will always be accompanied by `-enable-library-evolution` and
`-experimental-skip-non-exportable-decls`. This means that only the
initializers of properties on `@frozen` types will need to be emitted and
property wrappers are not yet fully supported on properties belonging to
`@frozen` types.
Resolves rdar://117448868
When -experimental-skip-non-exportable-decls is specified, the SIL for the
initializers and unsafe mutable addressors of global variables is unneeded and
should be skipped.
Moving the query implementation up to the AST library from SIL will allow
conveniences to be written on specific AST element classes. For instance, this
will allow `EnumDecl` to expose a convenience that enumerates element decls
that are available during lowering.
Also, improve naming and documentation for these queries.
Attribute @_silgen_name is today only allowed to be used on functions, this change allows usage on globals as well. The motivation for that is to be able to "forward declare" globals just like it's today possible to do with functions (for the cases where it's not practical or convenient to use a bridging header).
Separately, this change also adds a @_silgen_name(raw: ...) syntax, which simply avoids mangling the name (by using the \01 name prefix that LLVM uses). The motivation for that is to be able to reference the "magic Darwin linker symbols" that can be used to look up section bounds (in the current dylib/module) -- those symbols don't use the underscore prefix in their mangled names.
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.
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.
This patch replaces the stateful generation of SILScope information in
SILGenFunction with data derived from the ASTScope hierarchy, which should be
100% in sync with the scopes needed for local variables. The goal is to
eliminate the surprising effects that the stack of cleanup operations can have
on the current state of SILBuilder leading to a fully deterministic (in the
sense of: predictible by a human) association of SILDebugScopes with
SILInstructions. The patch also eliminates the need to many workarounds. There
are still some accomodations for several Sema transformation passes such as
ResultBuilders, which don't correctly update the source locations when moving
around nodes. If these were implemented as macros, this problem would disappear.
This necessary rewrite of the macro scope handling included in this patch also
adds proper support nested macro expansions.
This fixes
rdar://88274783
and either fixes or at least partially addresses the following:
rdar://89252827
rdar://105186946
rdar://105757810
rdar://105997826
rdar://105102288
As part of this I also had to change how we emit global_addr in
SILGenLValue. Specifically, only for noncopyable types, we no longer emit a
single global_addr at the beginning of the function (in a sense auto-CSEing) and
instead always emit a new global_addr for each access. The reason why we do this
is that otherwise, access base visitor will consider all accesses to the global
to be for the same single access. In contrast, by always emitting the
global_addr each time, we provide a new base for each access allowing us to emit
the diagnostics that we want to.
rdar://102794400
`Builtin.once` has type `(Builtin.RawPointer, (Builtin.RawPointer) -> ())`
at Swift level, but lazy global init passes its initializer as `() -> ()`,
so their callee and caller signatures doesn't match.
Some globals, like static stored properties, are lazily initialized.
For situations where we do a direct access to that property,
we will first call a function that tries to initialize the var if needed,
before returning the address of the global to perform the direct access.
In this specific case, we were not on the right actor when invoking
that function.
fixes rdar://83411416
My goal was to reduce the size of SILLocation. It now contains only of a storage union, which is basically a pointer and a bitfield containing the Kind, StorageKind and flags. By far, most locations are only single pointers to an AST node. For the few cases where more data needs to be stored, this data is allocated separately: with the SILModule's bump pointer allocator.
While working on this, I couldn't resist to do a major refactoring to simplify the code:
* removed unused stuff
* The term "DebugLoc" was used for 3 completely different things:
- for `struct SILLocation::DebugLoc` -> renamed it to `FilePosition`
- for `hasDebugLoc()`/`getDebugSourceLoc()` -> renamed it to `hasASTNodeForDebugging()`/`getSourceLocForDebugging()`
- for `class SILDebugLocation` -> kept it as it is (though, `SILScopedLocation` would be a better name, IMO)
* made SILLocation more "functional", i.e. replaced some setters with corresponding constructors
* replaced the hand-written bitfield `KindData` with C bitfields
* updated and improved comments
VarPattern is today used to implement both 'let' and 'var' pattern bindings, so
today is already misleading. The reason why the name Var was chosen was done b/c
it is meant to represent a pattern that performs 'variable binding'. Given that
I am going to add a new 'inout' pattern binding to this, it makes sense to
give it now a better fitting name before I make things more confusing.
Removes duplicated logic from the implementations of
FileUnit::lookupValue, and simplifies the interface to
ModuleDecl::lookupValue, where everyone was passing an empty
(non-filtering) access path anyway /except/ during actual lookup from
source code. No functionality change.
Dynamic replacements are currently written in extensions as
extension ExtendedType {
@_dynamicReplacement(for: replacedFun())
func replacement() { }
}
The runtime implementation allows an implementation in the future where
dynamic replacements are gather in a scope and can be dynamically
enabled and disabled.
For example:
dynamic_extension_scope CollectionOfReplacements {
extension ExtentedType {
func replacedFun() {}
}
extension ExtentedType2 {
func replacedFun() {}
}
}
CollectionOfReplacements.enable()
CollectionOfReplacements.disable()
Previously, TBDGen skipped emitting lazy initializers for globals that
appeared in any file with an entry point. This breaks, however on files
that have an NSApplicationMain/UIApplicationMain class in them, where
the entry point is synthesized but top-level globals are not locally
scoped. This change re-uses SILGen's check and only skips variable
declarations that appear at top level in a script mode file.
Resolves rdar://43549749
* [runtime] Clean up symbols in error machinery.
* [runtime] Clean up symbols in Foundation overlay.
* [runtime] Clean up symbols in collections and hashing.
* [runtime] Remove symbol controls from the Linux definition of swift_allocError.
* [tests] Add more stub functions for tests that link directly to the runtime.
Except GenericEnvironment.h, because you can't meaningfully use a
GenericEnvironment without its signature. Lots less depends on
GenericSignature.h now. NFC
- SILSerializeAll flag is now stored in the SILOptions and passed around as part of it
- Explicit SILSerializeAll/wholeModuleSerialized/makeModuleFragile API parameters are removed in many places
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.
A lot of files transitively include Expr.h, because it was
included from SILInstruction.h, SILLocation.h and SILDeclRef.h.
However in reality most of these files don't do anything
with Exprs, especially not anything in IRGen or the SILOptimizer.
Now we're down to 171 files in the frontend which depend on
Expr.h, which is still a lot but much better than before.