Commit Graph

73 Commits

Author SHA1 Message Date
Erik Eckstein b33ddf2df7 FunctionSignatureOptimization: fix wrong error type when creating a thunk
If the specialized function is generic, the optimization derived the wrong error type when creating a thunk for the specialized function.

Fixes a compiler crash
https://github.com/swiftlang/swift/issues/89617
rdar://178484080
2026-06-08 12:28:58 +02:00
Pavel Yaskevich 60ea598e7f [SIL] Set actor isolation when constructing/initializing SILFunction
Prevents situations when actor isolation ends up not being set
un-intentionally i.e. when cloning, specializating, or creating
thunks.

The thunks get `unspecified` isolation at the moment.
2026-04-21 16:03:35 -07:00
Pavel Yaskevich 883d4ce45b [SIL] Drop optional from SILFunction::getActorIsolation
SIL functions should always have actor isolation set, otherwise
it could lead to wrong deductions in optimization passes like
`SendNonSendable` or `OptimizeHopToExecutor`.

This is a first step to move isolation assignment into
`SILFunction::create`.
2026-04-21 12:21:01 -07:00
Pavel Yaskevich f01d91f079 [SILOptimizer] Make sure that cloning also transfers the actor isolation
There are passes that rely on the isolation being present after
specialization and other optmizations i.e. `SendNonSendable` which
means the clones need to always preserve the isolation of the
original function.
2026-04-13 17:41:57 -07:00
Slava Pestov 819738c83e AST: Rename mapTypeIntoContext() => mapTypeIntoEnvironment(), mapTypeOutOfContext() => mapTypeOutOfEnvironment() 2025-11-12 14:48:19 -05:00
Arnold Schwaighofer 25a071efc8 Add experimental feature @inline(always)
The intent for `@inline(always)` is to act as an optimization control.
The user can rely on inlining to happen or the compiler will emit an error
message.

Because function values can be dynamic (closures, protocol/class lookup)
this guarantee can only be upheld for direct function references.

In cases where the optimizer can resolve dynamic function values the
attribute shall be respected.

rdar://148608854
2025-09-30 08:36:26 -07:00
Kuba Mracek 6f4ae28520 [ASTMangler] Pass ASTContext to all instantiations of ASTMangler 2024-12-02 15:01:04 -08:00
Alejandro Alonso 9906db37c7 Fix closures capturing value generics 2024-09-04 15:13:50 -07:00
Tim Kientzle 1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
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)
2024-06-05 19:37:30 -07:00
Ellie Shin 5ccc4cd394 SIL function can be serialized with different kinds: [serialized] or
[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
2024-05-23 15:53:02 -07:00
Ben Barham 9779c18da3 Rename startswith to starts_with
LLVM is presumably moving towards `std::string_view` -
`StringRef::startswith` is deprecated on tip. `SmallString::startswith`
was just renamed there (maybe with some small deprecation inbetween, but
if so, we've missed it).

The `SmallString::startswith` references were moved to
`.str().starts_with()`, rather than adding the `starts_with` on
`stable/20230725` as we only had a few of them. Open to switching that
over if anyone feels strongly though.
2024-03-13 22:25:47 -07:00
Pavel Yaskevich f9ec3b1d7e Merge pull request #71796 from xedin/make-dist-new-requirements-conditionally-available
[Distributed] Make new protocol requirements conditionally available
2024-02-22 15:18:52 -08:00
Pavel Yaskevich 65d164a9c3 Revert "[SIL] Distributed: Remove logic related to ad-hoc requirements from SILFunction"
This reverts commit 1909b12370.
2024-02-21 13:29:47 -08:00
Ben Barham ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Pavel Yaskevich 1909b12370 [SIL] Distributed: Remove logic related to ad-hoc requirements from SILFunction
Ad-hoc requirements are now obsolete by making `remoteCall`,
`record{Argument, ReturnType}`, `decodeNextArgument` protocols
requirements and injecting witness tables for `SerializationRequirement`
conformances during IRGen.
2024-02-12 14:26:30 -08:00
Pavel Yaskevich a6a2a74c9b [SILOptimizer] Distributed: Suppress signature specialization for witnesses with ad-hoc serialization requirement 2024-02-12 14:26:30 -08:00
Doug Gregor 9f890004dd [SIL] Disable optimizations that aren't ready for indirect error results 2023-11-08 13:10:25 -08:00
Yuta Saito c5314bd3af Centralize KeyPath accessor calling convention logic to IRGen
KeyPath's getter/setter/hash/equals functions have their own calling
convention, which receives generic arguments and embedded indices from a
given KeyPath argument buffer.
The convention was previously implemented by:
1. Accepting an argument buffer as an UnsafeRawPointer and casting it to
   indices tuple pointer in SIL.
2. Bind generic arguments info from the given argument buffer while emitting
   prologue in IRGen by creating a new forwarding thunk.

This 2-phase lowering approach was not ideal, as it blocked KeyPath
projection optimization [^1], and also required having a target arch
specific signature lowering logic in SIL-level [^2].

This patch centralizes the KeyPath accessor calling convention logic to
IRGen, by introducing `@convention(keypath_accessor_XXX)` convention in
SIL and lowering it in IRGen. This change unblocks the KeyPath projection
optimization while capturing subscript indices, and also makes it easier
to support WebAssembly target.

[^1]: https://github.com/apple/swift/pull/28799
[^2]: https://forums.swift.org/t/wasm-support/16087/21
2023-09-20 11:25:39 -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
Pavel Yaskevich 3fb69b3c3c [SIL] SILFunction: Add runtime accessible function attribute
This attribute indicates that the given SILFunction has to be
added to "accessible functions" section and could be looked up
at runtime using a special API.
2022-12-20 09:33:44 -08:00
Michael Gottesman 9e44011e4d [sil] Add a new attribute called @closureCaptured to SILFunctionArguments that are closure capture arguments.
I am adding this to make it easy to determine if a SILFunction that is not inout
aliasable is captured. This is useful when emitting certain types of
diagnostics like I need to emit with move only.
2022-12-14 15:16:43 -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
Erik Eckstein ecbcacdecf SIL Analysis: Rename InvalidationKind::FunctionData to InvalidationKind::Effects
This invalidation kind is used when a compute-effects pass changes function effects.
Also, let optimization passes which don't change effects only invalidate the `FunctionBody` and not `Everything`.
2022-10-20 09:20:28 +02:00
Josh Soref 730b16c569 Spelling siloptimizer
* access
* accessed
* accesses
* accessor
* acquiring
* across
* activated
* additive
* address
* addresses'
* aggregated
* analysis
* and
* appropriately
* archetype
* argument
* associated
* availability
* barriers
* because
* been
* beginning
* belongs
* beneficial
* blocks
* borrow
* builtin
* cannot
* canonical
* canonicalize
* clazz
* cleanup
* coalesceable
* coalesced
* comparisons
* completely
* component
* computed
* concrete
* conjunction
* conservatively
* constituent
* construct
* consuming
* containing
* covered
* creates
* critical
* dataflow
* declaration
* defined
* defining
* definition
* deinitialization
* deliberately
* dependencies
* dependent
* deserialized
* destroy
* deterministic
* deterministically
* devirtualizes
* diagnostic
* diagnostics
* differentiation
* disable
* discipline
* dominate
* dominates
* don't
* element
* eliminate
* eliminating
* elimination
* embedded
* encounter
* epilogue
* epsilon
* escape
* escaping
* essential
* evaluating
* evaluation
* evaluator
* executing
* existential
* existentials
* explicit
* expression
* extended
* extension
* extract
* for
* from
* function
* generic
* guarantee
* guaranteed
* happened
* heuristic
* however
* identifiable
* immediately
* implementation
* improper
* include
* infinite
* initialize
* initialized
* initializer
* inside
* instruction
* interference
* interferes
* interleaved
* internal
* intersection
* intractable
* intrinsic
* invalidates
* irreducible
* irrelevant
* language
* lifetime
* literal
* looks
* materialize
* meaning
* mergeable
* might
* mimics
* modification
* modifies
* multiple
* mutating
* necessarily
* necessary
* needsmultiplecopies
* nonetheless
* nothing
* occurred
* occurs
* optimization
* optimizing
* original
* outside
* overflow
* overlapping
* overridden
* owned
* ownership
* parallel
* parameter
* paths
* patterns
* pipeline
* plottable
* possible
* potentially
* practically
* preamble
* precede
* preceding
* predecessor
* preferable
* preparation
* probably
* projection
* properties
* property
* protocol
* reabstraction
* reachable
* recognized
* recursive
* recursively
* redundant
* reentrancy
* referenced
* registry
* reinitialization
* reload
* represent
* requires
* response
* responsible
* retrieving
* returned
* returning
* returns
* rewriting
* rewritten
* sample
* scenarios
* scope
* should
* sideeffects
* similar
* simplify
* simplifycfg
* somewhat
* spaghetti
* specialization
* specializations
* specialized
* specially
* statistically
* substitute
* substitution
* succeeds
* successful
* successfully
* successor
* superfluous
* surprisingly
* suspension
* swift
* targeted
* that
* that our
* the
* therefore
* this
* those
* threshold
* through
* transform
* transformation
* truncated
* ultimate
* unchecked
* uninitialized
* unlikely
* unmanaged
* unoptimized key
* updataflow
* usefulness
* utilities
* villain
* whenever
* writes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-10-03 18:31:33 -04:00
Nate Chandler 5d14610043 [SILOptimizer] Preserve arg attrs at cloning.
Arguments are copied into new cloned functions in a number of places.
Wherever that happens, be sure to transfer the attributes as well.
2022-09-26 16:55:50 -07:00
Pavel Yaskevich 41a4ceae15 [Distributed] SILOpt: Make sure that ad-hoc function does not get eliminated as unused 2022-04-18 16:53:47 -07:00
zoecarver 036361d1e4 [cxx-interop] Add SIL function representation cxx_method; Support extending C++ types.
There are three major changes here:
    1. The addition of "SILFunctionTypeRepresentation::CXXMethod".
    2. C++ methods are imported with their members *last*. Then the arguments are switched when emitting the IR for an application of the function.
    3. Clang decls are now marked as foreign witnesses.

These are all steps towards being able to have C++ protocol conformance.
2022-01-06 14:26:47 -08:00
Pavel Yaskevich 4860f90fd7 [SIL] Add new flag to SILFunction - IsDistributed
Determines whether given SILFunction represents a distributed
method or its thunk.
2021-12-17 10:52:52 -08:00
Erik Eckstein b7351780f7 SIL: move all the block-list modifying APIs to SILFunction.
... and remove SILFunction::getBlocks().

It's just a cleanup, NFC.
2021-01-14 17:35:31 +01:00
Michael Gottesman c026e95cce [ownership] Extract out SILOwnershipKind from ValueOwnershipKind into its own type and rename Invalid -> Any.
This makes it easier to understand conceptually why a ValueOwnershipKind with
Any ownership is invalid and also allowed me to explicitly document the lattice
that relates ownership constraints/value ownership kinds.
2020-11-10 14:29:11 -08:00
Nate Chandler 94b5f76654 Revert "[SIL] Add SILFunctionType flag for async."
This reverts commit 9b8828848d.
2020-08-25 13:37:26 -07:00
Nate Chandler 9b8828848d [SIL] Add SILFunctionType flag for async. 2020-08-19 11:29:58 -07:00
Michael Gottesman 6049ce629c [fso] Do not try to specialize pseudo-generic functions today.
This is just fixing an assert violation. I also needed to add support for
target-sil-opt(mock-sdk: ...) so I added support to lit for that here.

<rdar://problem/62262811>
2020-05-21 15:48:55 -07:00
Arnold Schwaighofer 147144baa6 SIL: Thread type expansion context through to function convention apis
This became necessary after recent function type changes that keep
substituted generic function types abstract even after substitution to
correctly handle automatic opaque result type substitution.

Instead of performing the opaque result type substitution as part of
substituting the generic args the underlying type will now be reified as
part of looking at the parameter/return types which happens as part of
the function convention apis.

rdar://62560867
2020-05-04 13:53:30 -07:00
Andrew Trick 80d502c8ef Move the FSO bailout to the beginning of the pass.
This way we catch the DeadFunctionArgs optimization too, which is a
separate sub-pass.
2020-03-17 23:35:02 -07:00
John McCall ceff414820 Distinguish invocation and pattern substitutions on SILFunctionType.
In order to allow this, I've had to rework the syntax of substituted function types; what was previously spelled `<T> in () -> T for <X>` is now spelled `@substituted <T> () -> T for <X>`.  I think this is a nice improvement for readability, but it did require me to churn a lot of test cases.

Distinguishing the substitutions has two chief advantages over the existing representation.  First, the semantics seem quite a bit clearer at use points; the `implicit` bit was very subtle and not always obvious how to use.  More importantly, it allows the expression of generic function types that must satisfy a particular generic abstraction pattern, which was otherwise impossible to express.

As an example of the latter, consider the following protocol conformance:

```
protocol P { func foo() }
struct A<T> : P { func foo() {} }
```

The lowered signature of `P.foo` is `<Self: P> (@in_guaranteed Self) -> ()`.  Without this change, the lowered signature of `A.foo`'s witness would be `<T> (@in_guaranteed A<T>) -> ()`, which does not preserve information about the conformance substitution in any useful way.  With this change, the lowered signature of this witness could be `<T> @substituted <Self: P> (@in_guaranteed Self) -> () for <A<T>>`, which nicely preserves the exact substitutions which relate the witness to the requirement.

When we adopt this, it will both obviate the need for the special witness-table conformance field in SILFunctionType and make it far simpler for the SILOptimizer to devirtualize witness methods.  This patch does not actually take that step, however; it merely makes it possible to do so.

As another piece of unfinished business, while `SILFunctionType::substGenericArgs()` conceptually ought to simply set the given substitutions as the invocation substitutions, that would disturb a number of places that expect that method to produce an unsubstituted type.  This patch only set invocation arguments when the generic type is a substituted type, which we currently never produce in type-lowering.

My plan is to start by producing substituted function types for accessors.  Accessors are an important case because the coroutine continuation function is essentially an implicit component of the function type which the current substitution rules simply erase the intended abstraction of.  They're also used in narrower ways that should exercise less of the optimizer.
2020-03-07 16:25:59 -05:00
Michael Gottesman df47eb2c1f [sil] Use SILNodes.def to define ARGKIND##ArrayRef instead of hard coding names.
I also changed all of the places that vended these to use SILNodes.def as well
so that when new argument kinds are added, things just work.
2019-12-02 14:39:02 -08:00
Arnold Schwaighofer 8aaa7b4dc1 SILOptimizer: Pipe through TypeExpansionContext 2019-11-11 14:21:52 -08:00
Brent Royal-Gordon 17169fc1fe Merge pull request #27950 from brentdax/dumpster-fire
[NFC] Standardize dump() methods in frontend
2019-10-31 20:36:26 -07:00
Brent Royal-Gordon 99faa033fc [NFC] Standardize dump() methods in frontend
By convention, most structs and classes in the Swift compiler include a `dump()` method which prints debugging information. This method is meant to be called only from the debugger, but this means they’re often unused and may be eliminated from optimized binaries. On the other hand, some parts of the compiler call `dump()` methods directly despite them being intended as a pure debugging aid. clang supports attributes which can be used to avoid these problems, but they’re used very inconsistently across the compiler.

This commit adds `SWIFT_DEBUG_DUMP` and `SWIFT_DEBUG_DUMPER(<name>(<params>))` macros to declare `dump()` methods with the appropriate set of attributes and adopts this macro throughout the frontend. It does not pervasively adopt this macro in SILGen, SILOptimizer, or IRGen; these components use `dump()` methods in a different way where they’re frequently called from debugging code. Nor does it adopt it in runtime components like swiftRuntime and swiftReflection, because I’m a bit worried about size.

Despite the large number of files and lines affected, this change is NFC.
2019-10-31 18:37:42 -07:00
Robert Widmann 37e82a6133 [NFC] getWitnessMethodConformanceOrNone -> getWitnessMethodConformanceOrInvalid 2019-10-29 16:56:20 -07:00
Robert Widmann 3e1a61f425 [NFC] Fold The Tri-State In Optional<ProtocolConformanceRef>
ProtocolConformanceRef already has an invalid state.  Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it.  Mechanically
translate all of the callers and callsites to use this new
representation.
2019-10-29 16:55:56 -07:00
Joe Groff dc0f770364 remove todo warnings, oops 2019-10-26 10:49:47 -07:00
Joe Groff 03c7919b4a SIL: Add fields to SILFunctionType for substituted function types.
https://forums.swift.org/t/improving-the-representation-of-polymorphic-interfaces-in-sil-with-substituted-function-types/29711

This prepares SIL to be able to more accurately preserve the calling convention of
polymorphic generic interfaces by letting the type system represent "substituted function types".
We add a couple of fields to SILFunctionType to support this:

- A substitution map, accessed by `getSubstitutions()`, which maps the generic signature
  of the function to its concrete implementation. This will allow, for instance, a protocol
  witness for a requirement of type `<Self: P> (Self, ...) -> ...` for a concrete conforming
  type `Foo` to express its type as `<Self: P> (Self, ...) -> ... for <Foo>`, preserving the relation
  to the protocol interface without relying on the pile of hacks that is the `witness_method`
  protocol.

- A bool for whether the generic signature of the function is "implied" by the substitutions.
  If true, the generic signature isn't really part of the calling convention of the function.
  This will allow closure types to distinguish a closure being passed to a generic function, like
  `<T, U> in (*T, *U) -> T for <Int, String>`, from the concrete type `(*Int, *String) -> Int`,
  which will make it easier for us to differentiate the representation of those as types, for
  instance by giving them different pointer authentication discriminators to harden arm64e
  code.

This patch is currently NFC, it just introduces the new APIs and takes a first pass at updating
code to use them. Much more work will need to be done once we start exercising these new
fields.

This does bifurcate some existing APIs:

- SILFunctionType now has two accessors to get its generic signature.
  `getSubstGenericSignature` gets the generic signature that is used to apply its
  substitution map, if any. `getInvocationGenericSignature` gets the generic signature
  used to invoke the function at apply sites. These differ if the generic signature is
  implied.
- SILParameterInfo and SILResultInfo values carry the unsubstituted types of the parameters
  and results of the function. They now have two APIs to get that type. `getInterfaceType`
  returns the unsubstituted type of the generic interface, and
  `getArgumentType`/`getReturnValueType` produce the substituted type that is used at
  apply sites.
2019-10-25 13:38:51 -07:00
Andrew Trick bddc69c8a6 Organize SILOptimizer/Utils headers. Remove Local.h.
The XXOptUtils.h convention is already established and parallels
the SIL/XXUtils convention.

New:
- InstOptUtils.h
- CFGOptUtils.h
- BasicBlockOptUtils.h
- ValueLifetime.h

Removed:
- Local.h
- Two conflicting CFG.h files

This reorganization is helpful before I introduce more
utilities for block cloning similar to SinkAddressProjections.

Move the control flow utilies out of Local.h, which was an
unreadable, unprincipled mess. Rename it to InstOptUtils.h, and
confine it to small APIs for working with individual instructions.
These are the optimizer's additions to /SIL/InstUtils.h.

Rename CFG.h to CFGOptUtils.h and remove the one in /Analysis. Now
there is only SIL/CFG.h, resolving the naming conflict within the
swift project (this has always been a problem for source tools). Limit
this header to low-level APIs for working with branches and CFG edges.

Add BasicBlockOptUtils.h for block level transforms (it makes me sad
that I can't use BBOptUtils.h, but SIL already has
BasicBlockUtils.h). These are larger APIs for cloning or removing
whole blocks.
2019-10-02 11:34:54 -07:00
Robert Widmann 5a8d0744c3 [NFC] Adopt TypeBase-isms for GenericSignature
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase.  In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
2019-09-30 14:04:36 -07:00
Nate Chandler 9567bd4341 [SILOptimizer] Alter FSO arg explosion heuristic.
The new rule is that an argument will be exploded if one of the
following sets of conditions hold:

(1) (a) Specializing the function will result in a thunk.  That is, the
        thunk that is generated cannot be inlined everywhere.
    (b) The argument has dead non-trivial leaves.
    (c) The argument has fewer than three live leaves.

(2) (a) Specializing the function will not result in a thunk.  That is,
        the thunk that is generated will be inlined everywhere and
        eliminated as dead code.
    (b) The argument has dead potentially trivial leaves.
    (c) The argument has fewer than six live leaves.

This change is based heavily on @gottesm's
https://github.com/apple/swift/pull/16756 .

rdar://problem/39957093
2019-09-24 15:59:28 -07:00
Nate Chandler c99f12ff40 [SILOptimizer] Added option to force FSO for uncalled functions.
The new flag -sil-fso-optimize-if-not-called forced function signature
optimization to run even on functions which are not called.  Doing so is
helpful for tests to alleviate the burden of writing code to actually
call a function in whose function signature optimization we are
interested.
2019-09-20 10:12:02 -07:00
Nate Chandler 003876158c [Gardening] Made FSOEnableGenerics option static.
The command-line option for sil-fso-enable-generics was previously
visible outside the FunctionSignatureOpts translation unit.  It is not
any longer.
2019-09-20 10:08:46 -07:00