Commit Graph

1556 Commits

Author SHA1 Message Date
Andrew Trick
bed80eed72 [NFC] LifetimeDependence computeAddressRange comments and test case 2025-10-03 20:48:07 -07:00
Andrew Trick
ac31a2f619 LifetimeDependenceDiagnostics: extend temp alloc to unreachable.
When a non-Escapable value depends on the address of a trivial value, we use a
special computeAddressableRange analysis to compute the trivial value's
scope. Extend that analysis to include unreachable paths.

Fixes this pattern:

    inlineStorage.span.withUnsafeBytes

where inlineStorage is a trivial type defined in the user module. This
does not reproduce directly with InlineArray, but it is a problem for
user modules that have their own trivial wrapper around an InlineArray.

Fixes rdar://161630684 (Incorrect diagnostic: lifetime-dependent value escapes its scope)
2025-10-03 20:47:59 -07:00
Andrew Trick
7197f63ce2 Comment LifetimeDependenceScopeFixup. Explain unreachable paths. 2025-10-03 20:44:17 -07:00
Erik Eckstein
171607afa7 DeadStoreElimination: fix a corner case of storing a trivial case of a non-trivial enum
Storing a trivial enum case in a non-trivial enum must be treated like a non-trivial init or assign, e.g.
```
  %1 = enum $Optional<String>, #Optional.none!enumelt
  store %1 to [trivial] %0  // <- cannot delete this store!
  store %2 to [assign] %0
```
2025-10-02 19:20:35 +02:00
nate-chandler
5945606067 Merge pull request #84577 from nate-chandler/rdar161433604
[Optimizer] Use valid inst range to broadcast inlining changes.
2025-10-01 14:08:52 -07:00
Arnold Schwaighofer
7853ba0a7f Merge pull request #84178 from aschwaighofer/inline_always
Add experimental feature `@inline(always)`
2025-10-01 07:23:24 -07: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
Erik Eckstein
b527020364 LoopInvariantCodeMotion: bail on split load [take]
We currently don't support split `load [take]`, i.e. `load [take]` which does _not_ load all non-trivial fields of the initial value.
2025-09-30 10:39:51 +02:00
Erik Eckstein
fc6302e3e9 LoopInvariantCodeMotion: correctly handle load [copy]
When moving loads and stores out of a loop, a `load [copy]` must be replaced by a `copy_value`.
2025-09-30 10:39:51 +02:00
Erik Eckstein
a6fb1876ef LoopInvariantCodeMotion: correctly create projections for owned values
Owned structs and tuples must be projected by `destructure_struct` and `destructure_tuple`, respectively.

rdar://161467837
2025-09-30 10:39:51 +02:00
Erik Eckstein
7bbe5c6fe2 LoopInvariantCodeMotion: don't hoist loads and stores if the memory location is not initialized at loop exits.
If the memory is not initialized at all exits, it would be wrong to insert stores at exit blocks.
2025-09-30 10:39:51 +02:00
Nate Chandler
07d75186ba [Optimizer] Don't walk to deleted.
During inlining, some instructions in the caller may be deleted.  So
when publishing this best effort list of instructions which were
"changed" during inlining, don't start from a deleted instruction.
Instead just don't publish, as already happens in other cases.

Without actually addressing
```
// TODO: get a list of cloned instructions from the `inlineFunction`
```
this is somewhat better than checking for having reached the end of the
function during the walk because that will result in falsely
broadcasting that some unchanged instructions have changed whereas this
change only results in not broadcasting which is already being done in
some cases (e.g. when a `begin_apply` is immediately followed by an
`end_apply`).
2025-09-29 20:52:18 -07:00
Nate Chandler
b62798381e [Optimizer] Don't walk from deleted.
During inlining, the apply is deleted.  So when publishing this best
effort list of which instructions were "changed" during inlining, start
from the instruction before the deleted apply.
2025-09-29 20:52:18 -07:00
Nate Chandler
36205d90d2 [Gardening] Detypo'd "inlining". 2025-09-29 13:56:29 -07:00
Erik Eckstein
273874cd59 ConstantCapturePropagation: don't propagate keypaths with multiple uses in non-OSSA
We cannot do this because we don't know where to insert the compensating release after the propagated `partial_apply`.
A required `strong_retain` may have been moved over the `partial_apply`.
Then we would release the keypath too early.

Fixes a mis-compile
rdar://161321614
2025-09-29 18:42:39 +02:00
Erik Eckstein
12626475c3 ConstantCapturePropagation: refactor Value.isConstant 2025-09-29 18:42:39 +02:00
Erik Eckstein
e3055673f4 ConstantCapturePropagation: support sub-pass bisecting 2025-09-29 18:42:39 +02:00
Kavon Farvardin
32263bb9b8 ManualOwnership: add workaround for vars
For a proof-of-concept quality feature,
we can just skip the pass causing problems until
a proper solution is implemented.
2025-09-25 15:53:18 -07:00
eeckstein
16ce6b85ea Merge pull request #84511 from eeckstein/fix-init-static-globals
InitializeStaticGlobals : reapply support of non-loadable enums with a fix
2025-09-25 18:46:16 +02:00
eeckstein
9412e192c1 Merge pull request #84482 from eeckstein/smallprojectionpath-tests
SIL: use `Test` for the SmallProjectionPath's unit tests
2025-09-25 17:37:04 +02:00
Erik Eckstein
d590b94109 InitializeStaticGlobals: fix handling of nested non-loadable enums
Fixes a compiler crash
rdar://160880083
2025-09-25 10:11:18 +02:00
Anthony Latsis
3d898f71e5 SwiftCompilerSources/SIL: More robust IntegerLiteralInst construction
ac619010e3 backfired when building the
stdlib on rebranch. This time the problem is reversed: we should be
interpreting an integer as unsigned where we no longer do, here:
8f7af45115/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyLoad.swift (L78).

Rather than treating integers as signed by default, make
`Builder.createIntegerLiteral` accept a generic `FixedWidthInteger`, and
manipulate the value based on the generic type argument's signedness.

This doesn't entirely define away unintentional sign extensions, but
makes this mistake of humouring the parameter type less likely.
2025-09-25 08:05:57 +01:00
Erik Eckstein
648aa411a7 Reapply "InitializeStaticGlobals: support non-loadable enums"
This reverts commit 586f8a4694.
2025-09-25 08:22:26 +02:00
Anthony Latsis
275deaf154 Merge pull request #84052 from swiftlang/jepa-main2
SwiftCompilerSources/SIL: Fix APInt assertion failure on rebranch
2025-09-24 17:39:04 +01:00
Jakub Florek
aebebd9ee2 Merge pull request #84463 from MAJKFL/fix-licm-missing-earlier-materializable-projection-check
LICM fix missing materializable projection check
2025-09-24 17:19:39 +01:00
Jakub Florek
6788017cfb Add earlier check before load projection that bails when it's not materializable. 2025-09-24 11:49:59 +01:00
Erik Eckstein
39b9969049 SIL: use Test for the SmallProjectionPath's unit tests
Now that we have `Test` available in the SIL module, we can use it for the SmallProjectionPath's unit tests and get rid of the RunUnitTests pass.
2025-09-24 11:46:34 +02:00
Anthony Latsis
ac619010e3 SwiftCompilerSources/SIL: Fix APInt assertion failure on rebranch
The assertion is hit through `TypeValueInst.simplify` when constructing
an integer literal instruction with a negative 64-bit `Swift.Int` and a
bit width of 32 (the target pointer bit width for arm64_32 watchOS).
This happens because we tell the `llvm::APInt` constructor to treat the
input integer as unsigned by default in `getAPInt`, and a negative
64-bit signed integer does not fit into 32 bits when interpreted as
unsigned.

Fix this by flipping the default signedness assumption for the Swift API
and introducing a convenience method for constructing a 1-bit integer
literal instruction, where the correct signedness assumption depends on
whether you want to use 1 or -1 for 'true'.

In the context of using an integer to construct an `llvm::APInt`, there
are 2 other cases where signedness matters that come to mind:
1. A non-decimal integer literal narrower than 64 bits, such as
   `0xABCD`, is used.
2. The desired bit width is >64, since `llvm::APInt` can either
   zero-extend or sign-extend the 64-bit integer it accepts.

Neither of these appear to be exercised in SwiftCompilerSources, and
if we ever do, the caller should be responsible for either (1)
appropriately extending the literal manually, e.g.
`Int(Int16(bitPattern: 0xABCD))`, or (2) passing along the appropriate
signedness.
2025-09-24 09:37:42 +01:00
Erik Eckstein
935e5ecd7a SIL: fix Builder.emitDestroy(of:)
Do nothing for values with address types.

Fixes a crash in ConstantCapturePropagation
rdar://160816390
2025-09-23 10:50:26 +02:00
eeckstein
6557efc81d Merge pull request #84437 from eeckstein/fix-smallprojectionpath
fix handling of large indices in SmallProjectionPath
2025-09-23 07:13:31 +02:00
Jakub Florek
bf16a4248c Merge pull request #84398 from MAJKFL/bring-back-licm-ownership
Reintroduce licm support for ownership
2025-09-22 17:57:15 +01:00
Erik Eckstein
da17c26bae fix handling of large indices in SmallProjectionPath
* Fix the right shift operator which didn't work if the number of bits is exactly 64
* Detect overflow when combining indices

Such large indices usually don't appear in real code, except in internal String operations where (potentially large) integer values are treated as pointers.

Fixes a compiler crash
https://github.com/swiftlang/swift/issues/84372
rdar://160863199
2025-09-22 18:49:24 +02:00
Jakub Florek
b12e0ef554 Don't hoist scoped instructions in dead end loops. 2025-09-22 12:12:19 +01:00
Jakub Florek
38f28c1049 Reapply "Merge pull request #84045 from MAJKFL/new-sil-licm-pass-copy-ownership"
This reverts commit d2cd281d4c.
2025-09-19 16:06:35 +01:00
nate-chandler
d7d4ba391a Merge pull request #84378 from nate-chandler/rdar160742150
[AllocBoxToStack] Fix missing [nothrow] of apply.
2025-09-18 21:27:23 -07:00
Kavon Farvardin
84cf0a3551 Merge pull request #81858 from kavon/kavon/manual-ownership
introduce @_manualOwnership performance attribute
2025-09-18 16:15:20 -07:00
Nate Chandler
30098ad3e0 [AllocBoxToStack] Fix missing [nothrow] of apply.
When specializing an apply which is annotated `[nothrow]`, the resulting
function's apply must still be annotated `[nothrow]`.

rdar://160742150
2025-09-18 12:20:28 -07:00
Kavon Farvardin
61fe8a9b8e introduce @_manualOwnership performance attribute
This attribute forces programmers to acknowledge every
copy that is required to happen in the body of the
function. Only those copies that make sense according
to Swift's ownership rules should be "required".

The way this is implemented as of now is to flag each
non-explicit copy in a function, coming from SILGen, as
an error through PerformanceDiagnostics.
2025-09-17 13:51:57 -07:00
Jakub Florek
d2cd281d4c Revert "Merge pull request #84045 from MAJKFL/new-sil-licm-pass-copy-ownership"
This reverts commit a5c6156525, reversing
changes made to 2b6ea81b9e.
2025-09-17 15:52:48 +01:00
Jakub Florek
a5c6156525 Merge pull request #84045 from MAJKFL/new-sil-licm-pass-copy-ownership
Ownership support for LICM
2025-09-16 11:02:28 +01:00
Meghana Gupta
c764244df0 Merge pull request #84180 from meg-gupta/borrowandmutatepr
Add preliminary support for borrow accessors
2025-09-15 10:01:15 -07:00
Jakub Florek
e84bc084f4 Check for aliasing destroy_addr before hoisting load_borrow - end_borrow pair. 2025-09-15 12:42:30 +01:00
Meghana Gupta
d3e41e5f2b Update SwiftCompilerSources' OwnershipLiveness utility for borrow accessors
It uses a check on conformance to ForwardInstruction for walking down guaranteed forwarding uses.
Since apply of borrow accessors cannot be represented as ForwardingInstruction, handle them separately.

Representing apply of borrow accessors for consistent handling in the optimizer is TBD.
2025-09-14 23:38:10 -07:00
Meghana Gupta
51c64d5fda Update SideEffects for borrow accessors returning addresses
Add a read effect on the self parameter. Without this, the self parameter can get dead code eliminated by the GenericSpecializer.
2025-09-14 23:38:03 -07:00
Nate Chandler
586f8a4694 Revert "InitializeStaticGlobals: support non-loadable enums"
This reverts commit eaf38da903.

rdar://160143339
2025-09-12 11:29:19 -07:00
Andrew Trick
8ea97f31e5 Merge pull request #84245 from atrick/lifedep-log
[NFC] LifetimeDependenceDiagnostics debug output
2025-09-12 04:14:39 -07:00
Andrew Trick
979a2500dd [NFC] LifetimeDependenceDiagnostics debug output
Make the output grep-able for errors since we often have debug output
for many functions.
2025-09-11 09:26:54 -07:00
Andrew Trick
712d39a624 Fix computeAddressableRange, test, and comment.
Address review feedback from the previous commit.
2025-09-10 20:59:20 -07:00
Andrew Trick
52b0b058a7 LifetimeDependenceScopeFixup: extend temporary stack allocations
When the source of a lifetime dependency is a stack-allocated address, extend
the stack allocation to cover all dependent uses.

This avoids miscompilations for "addressable" dependencies which arise in code
built with -enable-experimental-feature AddressableTypes or
AddressableParameters. It is always an error for SILGen to emit the alloc_stack
in such cases. Nonetheless, we want to handle these unexpected cases gracefully
in SIL as a diagnostic error rather than allowing a miscompile.

Fixes rdar://159680262 ([nonescapable] diagnose dependence on a
temporary copy of a global array)
2025-09-10 20:59:19 -07:00
Andrew Trick
72b02eab16 LifetimeDependenceDiagnostics: check for on-stack trivial copies
Add a diagnostic to catch addressable dependencies on a trivial values that have
been copied to a temporary stack location. SILGen should never copy the source
of an addressable dependency to a temporary stack location, but this diagnostic
catches such compiler bugs rather than allowing miscompilation.

Fixes rdar://159680262 ([nonescapable] diagnose dependence on a temporary copy
of a global array)
2025-09-10 20:59:19 -07:00