Commit Graph

723 Commits

Author SHA1 Message Date
eeckstein
afdaf838a5 Merge pull request #86817 from eeckstein/fix-rle
RedundantLoadElimination: fix a complexity problem when replacing a huge amount of `load`s with a common value
2026-01-28 22:38:44 +01:00
Erik Eckstein
f2b55335c4 SIL: add Instruction.set(location:) 2026-01-28 17:54:37 +01:00
Alejandro Alonso
a4fdb7d9ec Simplify the identity for dereference borrows 2026-01-27 11:04:25 -08:00
Alejandro Alonso
9f95dc7695 Simplify init_borrow_addr when the borrow type is statically known
make sure we register as well as add test
2026-01-27 11:03:53 -08:00
Joe Groff
0f3ddfbcc8 Merge pull request #86545 from jckarter/builtin-borrow
`Builtin.Borrow` implementation
2026-01-26 07:32:31 -08:00
Joe Groff
b11e8c985a SIL: Handle dereference_borrow returns in SILGenCleanup.
Make sure an `end_borrow` is emitted on the `dereference_borrow` so that
SILGenCleanup recognizes this pattern and lowers it to a `return_borrow`
as it does for returned `load_borrow`s. Add support to the Swift implementation
of `BorrowingInstruction` for `DereferenceBorrow`.
2026-01-23 08:02:09 -08:00
Joe Groff
2f02c7cda3 SIL: Introduce instructions for forming and dereferencing Builtin.Borrow.
Since after address lowering, `Borrow` can remain loadable with a known-
layout address-only referent, we need instructions that handle three
forms:

- borrow and referent are both loadable values
- borrow is a value, but referent is address-only
- borrow and referent are both address-only
2026-01-23 08:02:01 -08:00
Erik Eckstein
535a58e3fb SIL: assume a read-effect for unused indirect arguments
Even if an indirect argument is unused, pretend that the function reads from it.
If the unused argument is passed to another generic function and that function is specialized,
the argument may be re-abstracted and the specializer inserts a load from the indirect argument.
Therefore we must be prepared that unused indirect argument might get loaded from at some time.

Fixes a compiler crash
rdar://168623362
2026-01-23 15:58:23 +01:00
Erik Eckstein
54347dbfd7 SIL Verifier: enable a check for end-borrows
This check requires complete OSSA lifetimes
2026-01-22 17:41:48 +01:00
Erik Eckstein
0f0aa0c17b Optimizer: require that there are no unreachable blocks and infinite loops in OSSA
These two new invariants eliminate corner cases which caused bugs if optimization didn't handle them.
Also, it will significantly simplify lifetime completion.

The implementation basically consists of these changes:
* add a flag in SILFunction which tells optimization if they need to take care of infinite loops
* add a utility to break infinite loops
* let all optimizations remove unreachable blocks and break infinite loops if necessary
* add verification to check the new SIL invariants

The new `breakIfniniteLoops` utility breaks infinite loops in the control flow by inserting an "artificial" loop exit to a new dead-end block with an `unreachable`.
It inserts a `cond_br` with a `builtin "infinite_loop_true_condition"`:
```
bb0:
  br bb1
bb1:
  br bb1              // back-end branch
```
->
```
bb0:
  br bb1
bb1:
  %1 = builtin "infinite_loop_true_condition"() // always true, but the compiler doesn't know
  cond_br %1, bb2, bb3
bb2:                  // new back-end block
  br bb1
bb3:                  // new dead-end block
  unreachable
```
2026-01-22 17:41:23 +01:00
Erik Eckstein
e2ddbf79f0 SIL: fix the corner case of an empty BasicBlockRange
If no block was ever inserted in a BasicBlockRange, the "inclusive" range should be empty and not contain the "begin" block.
2026-01-22 17:41:21 +01:00
Erik Eckstein
1e476700af SIL: add Builder.createExtendLifetime and add isDeadEnd to createDestroyValue 2026-01-22 17:41:21 +01:00
Aidan Hall
37e89902a3 Merge pull request #85957 from aidan-hall/fix-debug-info-again
Retain more debug info in SIL optimization passes
2026-01-13 17:13:36 +00:00
Erik Eckstein
87dc1c5d8b SIL verifier: accept "owned" ownership for borrowed-from's enclosing values
"none" is like "owned" and can happen e.g. if a non-trivial enum is constructed with a trivial case:
```
  %1 = enum $Optional<AnyObject>, #Optional.none!enumelt   // ownership: none
  ...
  %3 = borrowed %phi from (%1)
```

Fix a false verification error
https://github.com/swiftlang/swift/issues/86407
rdar://167833469
2026-01-12 08:56:31 +01:00
Aidan Hall
0ef2094279 [DebugInfo] Salvage more during SIL optimization passes
This reverts commit b1eb70bf45.

The original PR (#85244) was reverted (#85836) due to rdar://165667449

This version fixes the aforementioned issue, and (potentially) improves overall
debug info retention by salvaging info in erase(instructionIncludingDebugUses:),
rather than inserting many explicit salvageDebugInfo calls throughout the code
to make the test cases pass.

Bridging: Make salvageDebugInfo a method of MutatingContext

This feels more consistent than making it a method of Instruction.

DebugInfo: Salvage from trivially dead instructions

This handles the case we were checking in constantFoldBuiltin, so we do not need to salvage debug info there any more.
2026-01-06 12:01:20 +00:00
Daniil Kovalev
7f0963e23f Fix conformance-related warnings appearing after PR85757 (#86183)
The conformances `Type: Comparable` and `EnumCase: Equatable` were
previously introduced in #85757 for implementing AutoDiff closure
specialization logic. This patch moves the latter directly to the SIL
module. The conformance `Type: Comparable` is deleted, and `sort(by:)`
is used instead of `sort` to mimic the same behavior in tests. These
changes address warnings mentioned in the comment:
https://github.com/swiftlang/swift/pull/85757#issuecomment-3681636278
2026-01-02 11:58:29 +00:00
Erik Eckstein
6ce2df2ed1 SIL Verifier: workaround a MoveOnlyChecker pass bug
The MoveOnlyChecker is inserting a `destroy_addr` in a read-only access scope, which is illegal.
Relax the verification of read-only access scope by only looking at dynamic scopes.

Fixes a verifier crash.
rdar://166896665
2025-12-22 10:57:41 +01:00
Daniil Kovalev
1f77138afe [AutoDiff] Closure specialization: specialize branch tracing enums (#85757)
This patch contains part of the changes intended to resolve #68944.

1. Closure info gathering logic.
2. Branch tracing enum specialization logic.
3. Specialization of branch tracing enum basic block arguments in VJP.
4. Specialization of branch tracing enum payload basic block arguments
in pullback.

Note that mangling-related logic is implemented in C++ since at this
moment we have no Swift bridged for that.

Here is a simplified example of how branch tracing enum (BTE)
specialization looks like.

Before specialization:

```
enum $_AD__xxx {
  case bb0(((Float) -> Float))
}

func vjp(...) {
  // ...
  %foo      = function_ref $foo         : (Float, Float) -> Float
  %pa1      = partial_apply %foo(%arg1) : (Float) -> Float
  %payload1 = tuple (%pa1)              : ((Float) -> Float)
  %bte      = enum $_AD__xxx.bb0!enumelt, %payload1
  // ...
}

func pullback(%bte, ...) {
  // ...
  %payload2 = unchecked_enum_data %bte, $_AD__xxx.bb0!enumelt : ((Float) -> Float)
  %pa2      = tuple_extract %payload2, 0                      : (Float) -> Float
  %res      = apply %pa2(%arg2)                               : Float
  // ...
}
```

After specialization:

```
enum $_AD__xxx_spec_bb0_0 {
  case bb0(((Float)))
}

func vjp(...) {
  // ...
  %captured1 = tuple (%arg1)      : (Float)
  %payload1  = tuple (%captured1) : ((Float))
  %bte_spec  = enum $_AD__xxx_spec_bb0_0.bb0!enumelt, %payload1
  // ...
}

func pullback_spec(%bte_spec, ...) {
  // ...
  %payload2  = unchecked_enum_data %bte, $_AD__xxx_spec_bb0_0.bb0!enumelt : ((Float))
  %captured2 = tuple_extract %payload2, 0                                 : (Float)
  %arg1      = tuple_extract %captured2, 0                                : Float
  %foo       = function_ref $foo                                          : (Float, Float) -> Float
  %res       = apply %foo(%arg2, %arg1)                                   : Float
  // ...
}
```
2025-12-21 00:33:50 +00:00
Erik Eckstein
439bda67c8 SIL: add Type.isHeapObjectReferenceType 2025-12-19 17:43:59 +01:00
eeckstein
fd8c3ea046 Merge pull request #86042 from eeckstein/sil-unit-tests
SwiftCompilerSources: convert all unit-test passes to real tests
2025-12-15 14:38:50 +00:00
Erik Eckstein
c822615dc2 Optimizer: convert the UpdateBorrowedFromPass pass to a test
And remove the now empty TestPasses directory.
2025-12-15 10:01:51 +01:00
Erik Eckstein
bff873dea0 Optimizer: convert the SILPrinter and TestInstructionIteration passes to tests 2025-12-15 10:01:41 +01:00
Erik Eckstein
c639c716b9 Optimizer: convert the RangeDumper pass to a test 2025-12-15 10:01:41 +01:00
Mahdi Bahrami
d1bea5b184 Minor fix in HasShortDescription doc-comments 2025-12-15 11:54:41 +03:30
Erik Eckstein
edacd4c4e3 Optimizer: convert the AccessDumper from a pass to a test 2025-12-15 09:09:41 +01:00
Joe Groff
da4e72cf2d SIL verifier: The atInstruction/atArgument parameter to require should not be optional.
The underlying C++ code expects a non-null `Instruction*` or `SILArgument*` pointer, and
most of the contextual information in a verifier error is derived from these arguments,
so it doesn't really make sense for the Swift level interface to present these arguments
as optional.
2025-12-10 10:27:56 -08:00
Aidan Hall
21aa6b2ea2 Merge pull request #85836 from aidan-hall/revert-debuginfo
Revert "[DebugInfo] Salvage more in -O builds"
2025-12-05 14:14:17 +00:00
Erik Eckstein
9ceb8b83c1 SIL-Verifier: Don't verify that there are no stores in read-only access scopes if there is a conflicting scope
This is a programming error, but the compiler should not crash. The violation is caught at runtime.
2025-12-04 21:12:32 +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
Daniil Kovalev
b73676ee68 Bridging: Implement several optional- and enum-related bridges (#85756)
In #85757, part of the changes resolving #68944 is submitted. Most
bridges required for #85757 were previously implemented in #84648. After
#82653 got merged, we have demand for several new bridges in order to
properly support optimizing derivatives of throwing functions via
AutoDiff Closure Specialization pass.

This patch implements:

- **AST:**

   * `var optionalObjectType: Type` property of `Type` struct
   
   * `var optionalType: Type` property of `Type` struct

- **SIL:**

  * `let name: StringRef` property of `EnumCase` struct

* `func createOptionalSome(operand: Value, type: Type) -> EnumInst`
method of `Builder`

* `func createOptionalNone(type: Type) -> EnumInst` method of `Builder`
2025-12-04 08:26:44 +00:00
Arnold Schwaighofer
36a3c6e611 Merge pull request #85644 from aschwaighofer/wip_embedded_exits_with_eriks_changes_v1
[embedded] Fix associated type conformances for specialized witness tables
2025-12-01 16:40:31 -08: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
Michael Gottesman
24c69c674d Merge pull request #85604 from gottesmm/alloc_stack_non_nested
[irgen] Implement support for alloc_stack non_nested.
2025-12-01 09:38:06 -08: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
d2dc3de7f4 SIL: add the WorklistWithPayload utility
It is like `Worklist` but can store an additional arbitrary payload per element.
2025-11-24 14:49:45 +01:00
Erik Eckstein
7d79179818 SIL: add the IterableSet utility
It is a set which supports iterating over its elements.
2025-11-24 14:49:45 +01:00
Erik Eckstein
2c5d8237bc SIL: add var Instruction.mayCallFunction
It checks if arbitrary functions may be called by an instruction.
This can be either directly, e.g. by an `apply` instruction, or indirectly by destroying a value which might have a deinitializer which can call functions.
2025-11-24 14:49:45 +01:00
Michael Gottesman
c876c1ee88 [sil-verifier] Split SILVerifier verificationFailure into separate functions for Instructions, Arguments, and add a variant for Values.
This also required me to change how we handled which instruction/argument we
emit an error about in the verifier. Previously we were using two global
variables that we made nullptr to control which thing we emitted an error about.
This was unnecessary. Instead I added a little helper struct that internally
controls what we will emit an error about and an external "guard" RAII struct
that makes sure we push/pop the instruction/argument we are erroring upon
correctly.
2025-11-21 11:21:15 -08:00
Arnold Schwaighofer
1b6da50ed9 Merge pull request #85602 from aschwaighofer/wip_embedded_exit_cast
[embedded] Implement swift_dynamicCast suport for casts from existential to concrete type
2025-11-20 21:01:41 -05:00
Erik Eckstein
b218d9ab5c SIL: add some APIs for InitExistentialAddrInst
* `var conformances: ConformanceArray`
* `var formalConcreteType: CanonicalType`
2025-11-20 10:55:47 -08:00
Arnold Schwaighofer
3cff05d540 [embedded] Implement swift_dynamicCast suport for casts from existential to concrete type 2025-11-19 14:41:37 -08:00
Daniil Kovalev
c12819f881 Address review comments 2025-11-17 14:13:09 +03:00
Daniil Kovalev
c1f4bcfd98 Merge branch 'main' into users/kovdan01/ast-bridges-for-autodiff-closure-spec 2025-11-17 10:22:24 +03:00
Slava Pestov
819738c83e AST: Rename mapTypeIntoContext() => mapTypeIntoEnvironment(), mapTypeOutOfContext() => mapTypeOutOfEnvironment() 2025-11-12 14:48:19 -05:00
Andrew Trick
b28cd59dfc [NFC] TypeLowering: add CustomDeinit.
Teach SIL type lowering to recursively track custom vs. default deinit status.

Determine whether each type recursively only has default deinitialization. This
includes any recursive deinitializers that may be invoked by releasing a
reference held by this type.

If a type only has default deinitialization, then the deinitializer cannot
have any semantically-visible side effects. It cannot write to any memory
2025-11-11 17:29:45 -08:00
Daniil Kovalev
f0bf57a269 Resolve merge conflicts & address review comments 2025-11-10 19:18:25 +03:00
Daniil Kovalev
72431dbd2d Merge branch 'main' into users/kovdan01/ast-bridges-for-autodiff-closure-spec 2025-11-10 18:46:04 +03:00
Meghana Gupta
32cd86f719 Update access base for borrow/mutate accessors in SwiftCompilerSources 2025-11-06 10:55:39 -08:00
Meghana Gupta
a0eb58fa07 Handle return_borrow in a few more places in SwiftCompilerSources 2025-11-06 10:55:31 -08:00
Andrew Trick
382529c73b Merge pull request #85232 from atrick/rdar159793739-lifedep-cast
LifetimeDependenceDiagnostics: handle dynamic casting of Span<T>
2025-10-31 08:35:36 -07:00