Commit Graph

2663 Commits

Author SHA1 Message Date
Erik Eckstein
c0017a2701 DeadCodeElimination: don't insert destroys for removed values in dead-end blocks
When an owned value has no lifetime ending uses it means that it is in a dead-end region.
We must not remove and inserting compensating destroys for it because that would potentially destroy the value too early.
Initialization of an object might be cut off and removed after a dead-end loop or an `unreachable`.
In this case a class destructor would see uninitialized fields.

Fixes a mis-compile
https://github.com/swiftlang/swift/issues/85851
rdar://165876726
2025-12-05 17:08:51 +01:00
Aidan Hall
b1eb70bf45 Revert "[DebugInfo] Salvage more in -O builds"
This reverts commit a95d2979f9.

rdar://165667449
2025-12-04 15:39:39 +00:00
Erik Eckstein
e603f52757 DeadCodeElimination: don't hoist destroy_value instructions
DeadCodeElimination can remove instructions including their destroys and then insert compensating destroys at a new place.
This is effectively destroy-hoisting which doesn't respect deinit-barriers.
Disable removing and re-creating `destroy_value` instructions. This is done by other optimizations.
2025-12-03 15:53:56 +01:00
Aidan Hall
96dca43eb9 Merge pull request #85244 from aidan-hall/fixing-debug-info-rebase
Retain more debug info in optimized builds
2025-12-01 20:49:40 +00:00
Aidan Hall
a95d2979f9 [DebugInfo] Salvage more in -O builds
Specifically, improved debug info retention in:
* tryReplaceRedundantInstructionPair,
* splitAggregateLoad,
* TempLValueElimination,
* Mem2Reg,
* ConstantFolding.

The changes to Mem2Reg allow debug info to be retained in the case tested by
self-nostorage.swift in -O builds, so we have just enabled -O in that file
instead of writing a new test for it.

We attempted to add a case to salvageDebugInfo for unchecked_enum_data, but it
caused crashes in Linux CI that we were not able to reproduce.
2025-11-28 17:42:18 +00:00
Erik Eckstein
dbc50633b9 DeadCodeElimination: don't remove empty access scopes
Empty access scopes can be a result of e.g. redundant-load-elimination.
It's still important to keep those access scopes to detect access violations.
Even if the load is physically not done anymore, in case of a conflicting access a propagated load is still wrong and must be detected.

rdar://164571252
2025-11-24 14:49:45 +01:00
Slava Pestov
819738c83e AST: Rename mapTypeIntoContext() => mapTypeIntoEnvironment(), mapTypeOutOfContext() => mapTypeOutOfEnvironment() 2025-11-12 14:48:19 -05:00
eeckstein
552b665a9e Merge pull request #85334 from eeckstein/mandatory-destroy-hoisting
Optimizer: make destroy hoisting a mandatory pass
2025-11-07 06:45:03 +01:00
Erik Eckstein
04688a69ec Optimizer: Always respect deinit barriers when hoisting destroys.
Also for non-lexical lifetimes
2025-11-06 21:00:45 +01:00
Michael Gottesman
97b0e2ebae [concurrency] Create builtins for invoking specific concurrency runtime functions.
Specifically:

1. swift_task_addCancellationHandler
2. swift_task_removeCancellationHandler
3. swift_task_addPriorityEscalationHandler
4. swift_task_removePriorityEscalationHandler
5. swift_task_localValuePush
6. swift_task_localValuePop

rdar://109850951
2025-11-05 11:03:44 -08:00
John McCall
13937fdb4e Merge pull request #84528 from rjmccall/async-let-runtime-realism
Model async let begin/finish as builtins in SIL
2025-11-05 10:24:46 -08:00
John McCall
a7d7970e29 Turn finishAsyncLet into a builtin.
This is necessary because we need to model its stack-allocation
behavior, although I'm not yet doing that in this patch because
StackNesting first needs to be taught to not try to move the
deallocation.

I'm not convinced that `async let` *should* be doing a stack allocation,
but it undoubtedly *is* doing a stack allocation, and until we have an
alternative to that, we will need to model it properly.
2025-11-03 16:33:40 -08:00
John McCall
cd67912a50 Remove the deprecated and unused endAsyncLet builtin. 2025-11-03 13:45:18 -08:00
John McCall
1d95fe14de Remove the deprecated and unused startAsyncLet builtin 2025-11-03 13:44:58 -08:00
Aidan Hall
b353bb302f DebugUtils: Remove eraseFromParentWithDebugInsts
There is another near-identical function in DebugOptUtils.h that can be used
everywhere this function is used, and offers more flexibility in its callback
interface.
2025-10-31 13:47:22 +00:00
Meghana Gupta
6734d4a4e6 Disable GenericSpecializer for @guaranteed results 2025-10-23 05:19:15 -07:00
Meghana Gupta
e116df3628 Introduce return_borrow instruction 2025-10-23 05:18:59 -07:00
eeckstein
28535a6865 Merge pull request #85006 from eeckstein/fix-simplify-cfg2
SimplifyCFG: insert compensating `end_lifetime` when replacing a `switch_enum`
2025-10-21 07:25:05 +02:00
eeckstein
9074a1eec3 Merge pull request #85005 from eeckstein/remove-copy-forwarding
Optimizer: remove the CopyForwarding pass
2025-10-21 07:24:42 +02:00
Erik Eckstein
7a7004927c Optimizer: remove the CopyForwarding pass
This pass removes `copy_addr` instructions.
However, it has some problems which causes compiler crashes.
It's not worth fixing these bugs because
1. Most copy_addrs can be eliminated by TempRValueElimination and TempLValueElimination.
2. Once we have opaque value we don't need copy_addr elimination, anyway.

rdar://162212460
2025-10-20 20:19:54 +02:00
Meghana Gupta
0bd6825aa2 Update SIL utilities for borrow and mutate accessors under opaque values mode 2025-10-20 09:05:38 -07:00
Erik Eckstein
a2a57dff0c SimplifyCFG: insert compensating end_lifetime when replacing a switch_enum
This is a follow-up of https://github.com/swiftlang/swift/pull/84905, which handles non-copyable enums with a deinit correctly.
Also, for copyable enums it's more efficient to use `end_lifetime` than `destroy_value`, because we already know that the enum contains a trivial case.
Therefore no destroy operation is needed.
2025-10-20 17:09:59 +02:00
Erik Eckstein
eb7120048b SimplifyCFG: insert compensating destroy when replacing a switch_enum
When replacing a `switch_enum` of an owned enum value with a branch to a non-payload case destination,
we need to insert a destroy of the enum value.

Fixes a SIL ownership verification failure.
https://github.com/swiftlang/swift/issues/84552
rdar://161482601
2025-10-15 11:24:12 +02:00
Arnold Schwaighofer
95358e85a1 Merge pull request #84856 from aschwaighofer/fix_assembly_vision_tests
AssemblyVision: Add assemblyvisionremarkgen-diagnose-copy-destroy-addr option and use it
2025-10-13 13:03:06 -07:00
Arnold Schwaighofer
bd2d6284bd AssemblyVision: Add assemblyvisionremarkgen-diagnose-copy-destroy-addr option and use it
rdar://162443309
2025-10-13 07:44:43 -07:00
Erik Eckstein
65e4c10113 Optimizer: remove the obsolete SpeculativeDevirtualization pass
This pass has been disabled since a very long time (because it's terrible for code size).
It does not work for OSSA. Therefore it cannot be enabled anymore (as is) once we have OSSA throughout the pipeline.
So it's time to completely remove it.
2025-10-13 10:49:17 +02:00
Arnold Schwaighofer
895cd0181d Merge pull request #84796 from aschwaighofer/assembly_vision_copy_destroy
AssemblyVision: Emit remarks for generic copies and destroys
2025-10-11 08:10:43 -07:00
Erik Eckstein
1cbed39f32 Optimizer: support the new array literal initialization pattern in the COWOpts pass 2025-10-10 14:20:59 +02:00
Erik Eckstein
de557cab56 Optimizer: support the new array literal initialization pattern in the ArrayCountPropagation pass 2025-10-10 14:20:59 +02:00
Arnold Schwaighofer
0e89791d01 AssemblyVision: Emit remarks for generic copies and destroys
rdar://162305752
2025-10-09 12:04:40 -07:00
Nate Chandler
52822ded70 [DeadObjectElim] Bail on invalid access path.
rdar://162237650
2025-10-09 06:34:08 -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
Kavon Farvardin
4a943d464d sil: provide ability to run CopyPropagation in -Onone
This does not enable it by default. Use either of the flags:

```
-enable-copy-propagation
-enable-copy-propagation=always
```

to enable it in -Onone. The previous frontend flag
`-enable-copy-propagation=true` has been renamed to
`-enable-copy-propagation=optimizing`, which is currently default.

rdar://107610971
2025-09-19 16:23:19 -07:00
Meghana Gupta
6665cd5d46 [NFC] hasGuaranteedAddressResults -> hasGuaranteedAddressResult and hasGuaranteedResults -> hasGuaranteedResult 2025-09-14 23:38:06 -07:00
Meghana Gupta
29f5dad72f Disable GenericSpecializer for borrow accessors in OSSA temporarily 2025-09-14 23:38:05 -07:00
nate-chandler
b3af244c46 Merge pull request #84022 from nate-chandler/rdar158139991
[Mem2Reg] Add end_lifetime for more trivial case non-trivial enums.
2025-09-01 06:56:26 -07:00
Jakub Florek
eae7864370 Merge pull request #83988 from MAJKFL/new-sil-licm-pass-copy
New SIL LICM pass
2025-09-01 10:28:17 +01:00
Nate Chandler
1c52364d28 [Mem2Reg] Complete single-block trivial enum cases
Add `end_lifetime` for values of non-trivial enum type which aren't
destroyed in non-dead-end blocks.
2025-08-29 15:47:10 -07:00
Nate Chandler
4b3588c9b9 [NFC] Mem2Reg: Delete this dead code.
Since the time that lifetimes in `alloc_stack [lexical]` began to be
represented after promotion by `move_value [lexical]`s, the
`endOwnedLexicalLifetimeBeforeInst` is just an assertion.  In the
future, lifetimes of values never destroyed that leak into dead end
blocks should be completed by OSSACompleteLifetime.  For now, just
delete this code.
2025-08-29 15:45:23 -07:00
Nate Chandler
69abf25f3a [NFC] Mem2Reg: Restructured conditional.
In preparation for adding other cases.  Also improved comments.
2025-08-29 15:45:19 -07:00
Nate Chandler
1f7432dedb [Mem2Reg] Don't skip write-only enum locations.
The lifetimes of the values stored into these locations may need to be
completed: if a trivial case of a non-trivial enum is written to the
location, its lifetime must be completed.

rdar://158139991
2025-08-29 15:45:14 -07:00
Nate Chandler
63a3c65147 [Mem2Reg] Fix isStorageValid.
In a few places, it wasn't getting set to false: `end_borrow`s of
`store_borrow`s and `load [take]`s.
2025-08-29 15:45:12 -07:00
Nate Chandler
09b1c3109d [NFC] Mem2Reg: Remove unused parameter. 2025-08-28 15:32:50 -07:00
nate-chandler
9fe43836f6 Merge pull request #83907 from nate-chandler/rdar158149082
[AllocBoxToStack] Don't destroy in dead-ends.
2025-08-28 13:36:28 -07:00
Jakub Florek
bc86fe5a38 Hoist ArrayCallKind to a separate file 2025-08-28 20:50:33 +01:00
Nate Chandler
1eafced6a2 [AllocBoxToStack] Don't destroy in dead-ends.
It is valid to leak a value on paths into dead-end regions.
Specifically, it is valid to leak an `alloc_box`.  Thus, "final
releases" in dead-end regions may not destroy the box and consequently
may not release its contents.  Therefore it's invalid to lower such final
releases to `dealloc_stack`s, let alone `destroy_addr`s.  The in-general
invalidity of that transformation results in miscompiling whenever a box
is leaked and its projected address is used after such final releases.

Fix this by not treating final releases as boundary markers of the
`alloc_box` and not lowering them to `destroy_addr`s and
`dealloc_stack`s.

rdar://158149082
2025-08-27 17:03:48 -07:00
Anthony Latsis
2bfe2bd587 SIL: Treat -1 as signed when using it to construct an "all bits set" llvm::APInt
This should enable us to revert
73c70ee338.
2025-08-27 15:22:30 +01:00
Erik Eckstein
bdea6063d7 Mem2Reg: Fix lifetime completion for enum case values.
Enum types may have incomplete lifetimes in address form for trivial case values. When promoted to value form, they will end up with incomplete ossa lifetimes.
Because we know that the incomplete enum values are trivial enum cases we complete their lifetimes with `end_lifetime` instead of `destroy_value`.
This is especially important for Embedded Swift where we are not allowed to insert destroys which were not there before.

Fixes a compiler crash in Embedded Swift caused by de-virtualizing such an inserted destroy and ending up with a non-specialized generic function.

rdar://158807801
2025-08-25 09:35:46 +02:00
Nate Chandler
5da38cb04b [NFC] OSSACanonicalizeGuaranteed: Renamed. 2025-08-18 09:45:27 -07:00
Nate Chandler
8f1d6616af [NFC] OSSACanonicalizeOwned: Renamed. 2025-08-18 09:45:21 -07:00