Commit Graph

11692 Commits

Author SHA1 Message Date
Meghana Gupta
96cd2e1e10 Merge pull request #85987 from meg-gupta/undefcapture
Tolerate undef closure captures in ClosureLifetimeFixup
2025-12-12 16:31:09 -08:00
Michael Gottesman
22d182552c Merge pull request #85999 from gottesmm/pr-c29e9002447c10b77a408ede1f7b7e42c5034dbf
[rbi] When looking for closure uses, handle unresolved_non_copyable_value and store_borrow temporaries.
2025-12-12 00:09:08 -08:00
Michael Gottesman
79eee82b87 Merge pull request #85997 from gottesmm/pr-10810fd33c3e8d8fd1e4072f78d63d3200d35aa7
[rbi] Remove highlights from errors.
2025-12-11 23:57:55 -08:00
Michael Gottesman
d64fda488e [rbi] When looking for closure uses, handle unresolved_non_copyable_value and store_borrow temporaries.
This ensures that in cases like the following:

+func testNoncopyableNonsendableStructWithNonescapingMainActorAsync() {
+  let x = NoncopyableStructNonsendable()    <=========
+  let _ = {
+    nonescapingAsyncClosure { @MainActor in
+      useValueNoncopyable(x) // expected-warning {{sending 'x' risks causing data races}}
+      // expected-note @-1 {{task-isolated 'x' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
+    }
+  }
+}

We emit the diagnostic on the use instead of the <=====.

rdar://166347485
2025-12-11 18:45:06 -08:00
Michael Gottesman
8bea3518f5 [rbi] Remove highlights from errors.
I have noticed over time when working on the command line, we often times
highlight too large of an expression due to the locations provided to us by
earlier parts of the compiler. This isn't technically necessary and the
following doesn't look nice... so remove it.

```
test5.swift:171:16: error: sending 'x' risks causing data races [#SendingRisksDataRace]
169 |   let _ = {
170 |     nonescapingAsyncUse { @MainActor in
171 | _ _ _ _ _u_s_e_V_a_l_u_e_(_x_)
    |                |- error: sending 'x' risks causing data races [#SendingRisksDataRace]
    |                `- note: task-isolated 'x' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses
172 |     }
173 |   }
```
2025-12-11 17:29:20 -08:00
Meghana Gupta
f30b5841c4 Tolerate undef closure captures in ClosureLifetimeFixup
We may see undef closure captures in ClosureLifetimeFixup since
it is a mandatory pass that runs on invalid code as well.

This could sometimes hang the compiler while running `insertDeallocOfCapturedArguments`
in release builds.

This change adds a bailout when we see an undef closure capture to avoid running into this issue.
2025-12-11 12:16:12 -08:00
Andrew Trick
10e1be4387 Merge pull request #85870 from atrick/comment-copyprop
Add a FIXME to CopyPropagation to highlight an incomplete fix.
2025-12-10 13:51:30 -08:00
Andrew Trick
8cdef92334 Add a FIXME to CopyPropagation to highlight an incomplete fix. 2025-12-05 11:16:08 -08:00
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
Erik Eckstein
953d692e53 SILCombine: don't remove dead Array adoptStorage call
If followed by a dead infinite loop, the array initialization might have beed removed.
Therefore when inserting a compensating destroy of the array buffer can lead to a crash.

https://github.com/swiftlang/swift/issues/85851
rdar://165876726
2025-12-05 17:08:51 +01: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
Anthony Latsis
153dd02cd8 Merge pull request #85833 from swiftlang/jepa-main
[NFC] "SwiftVersion" → "LanguageMode" in `DiagnosticEngine::warnUntilSwiftVersion`, etc.
2025-12-05 09:34:30 +00: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
Anthony Latsis
88220a33c3 [NFC] "SwiftVersion" → "LanguageMode" in DiagnosticEngine::warnUntilSwiftVersion, etc. 2025-12-04 15:11:07 +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
Erik Eckstein
98805c9141 Optimizer: let the InstructionDeleter respect deinit-barriers by default
The InstructionDeleter 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. Therefore it's not done for lexical lifetimes.
However, since https://github.com/swiftlang/swift/pull/85334, the optimizer should treat _all_ lifetimes as fixed and not only lexical lifetimes.

This change adds a `assumeFixedLifetimes` flag to InstructionDeleter which is on by default.
Only mandatory passes (like OSLogOptimization) should turn this off.
2025-12-03 15:53:56 +01:00
Aidan Hall
90e12147e0 Merge pull request #85456 from aidan-hall/pack-opt-fix-weather-swb
PackSpecialization: Fix result & type parameter handling
2025-12-02 15:38:32 +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
Rauhul Varma
27ebe4dd95 Merge pull request #85492 from swiftlang/rauhul/cxx-exception-personality 2025-12-01 08:25:25 -08:00
eeckstein
9304ce951c Merge pull request #85707 from eeckstein/embedded-witness-method-specialization
embedded: change the function representation of directly called witness methods
2025-12-01 09:36:45 +01:00
eeckstein
62a13962a9 Merge pull request #85724 from eeckstein/fix-ossa-canonicalization
Optimizer: correctly handle bit-wise escaping values in OSSA canonicalization
2025-12-01 09:36:17 +01:00
eeckstein
46c69e40c1 Merge pull request #85533 from eeckstein/fix-access-simplification
SILOptimizer: don't remove empty conflicting access scopes
2025-12-01 09:35:48 +01:00
eeckstein
e18ba6d1bb Merge pull request #85691 from eeckstein/fix-sil-combine
SILCombine: fix propagation of concrete existentials in enums
2025-12-01 09:34:55 +01: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
Aidan Hall
97b7c35647 PackSpecialization: Fix result & type parameter handling
Refactor certain functions to make them simpler. and avoid calling
AST.Type.loweredType, which can fail. Instead, access the types of the
function's (SIL) arguments directly.

Correctly handle exploding packs that contain generic or opaque types by using
AST.Type.mapOutOfEnvironment().

@substituted types cause the shouldExplode predicate to be unreliable for AST
types, so restrict it to just SIL.Type. Add test cases for functions that have
@substituted types.

Re-enable PackSpecialization in FunctionPass pipeline.

Add a check to avoid emitting a destructure_tuple of the original function's
return tuple when it is void/().
2025-11-28 17:39:41 +00:00
Erik Eckstein
633d42b1b4 Optimizer: correctly handle bit-wise escaping values in OSSA canonicalization
We cannot compute the liverange of a value if it bit-wise escapes.
This fixes a mis-compile in copy-propagation which hoists a destroy_value over a use of the escaped value when lexical liveranges are disabled.
The test case is a simplified SIL sequence from the stdlib core where this problem shows up, because we build the stdlib core with disabled lexical liveranges.
2025-11-27 22:07:11 +01:00
Erik Eckstein
64dd574bea embedded: change the function representation of directly called witness methods
This is needed in Embedded Swift because the `witness_method` convention requires passing the witness table to the callee.
However, the witness table is not necessarily available.
A witness table is only generated if an existential value of a protocol is created.

This is a rare situation because only witness thunks have `witness_method` convention and those thunks are created as "transparent" functions, which means they are always inlined (after de-virtualization of a witness method call).
However, inlining - even of transparent functions - can fail for some reasons.

This change adds a new EmbeddedWitnessCallSpecialization pass:
If a function with `witness_method` convention is directly called, the function is specialized by changing the convention to `method` and the call is replaced by a call to the specialized function:

```
  %1 = function_ref @callee : $@convention(witness_method: P) (@guaranteed C) -> ()
  %2 = apply %1(%0) : $@convention(witness_method: P) (@guaranteed C) -> ()
...
sil [ossa] @callee : $@convention(witness_method: P) (@guaranteed C) -> () {
  ...
}
```
->
```
  %1 = function_ref @$e6calleeTfr9 : $@convention(method) (@guaranteed C) -> ()
  %2 = apply %1(%0) : $@convention(method) (@guaranteed C) -> ()
...
// specialized callee
sil shared [ossa] @$e6calleeTfr9 : $@convention(method) (@guaranteed C) -> () {
  ...
}
```

Fixes a compiler crash
rdar://165184147
2025-11-26 16:23:47 +01:00
Erik Eckstein
17ca4d9787 Optimizer: add FunctionPassContext.mangle(withChangedRepresentation original: Function) 2025-11-26 16:23:47 +01:00
Erik Eckstein
ab2345a2ed FunctionPassContext: support setting arbitrary function type representations when creating specialized functions 2025-11-26 16:23:47 +01:00
Erik Eckstein
2ac69f3c55 SILCombine: fix propagation of concrete existentials in enums
This peephole optimization didn't consider that an alloc_stack of an enum can be overridden by another value.
The fix is to remove this peephole optimization at all because it is already covered by `optimizeEnum` in alloc_stack simplification.

Fixes a miscompile
https://github.com/swiftlang/swift/issues/85687
rdar://165374568
2025-11-25 09:42:19 +01:00
Erik Eckstein
9a124742b0 Optimizer: add the DeadAccessScopeElimination optimization pass
It eliminates dead access scopes if they are not conflicting with other scopes.

Removes:
```
  %2 = begin_access [modify] [dynamic] %1
  ...                                       // no uses of %2
  end_access %2
```

However, dead _conflicting_ access scopes are not removed.
If a conflicting scope becomes dead because an optimization e.g. removed a load, it is still important to get an access violation at runtime.
Even a propagated value of a redundant load from a conflicting scope is undefined.

```
  %2 = begin_access [modify] [dynamic] %1
  store %x to %2
  %3 = begin_access [read] [dynamic] %1    // conflicting with %2!
  %y = load %3
  end_access %3
  end_access %2
  use(%y)
```
After redundant-load-elimination:
```
  %2 = begin_access [modify] [dynamic] %1
  store %x to %2
  %3 = begin_access [read] [dynamic] %1    // now dead, but still conflicting with %2
  end_access %3
  end_access %2
  use(%x)                                  // propagated from the store, but undefined here!
```
In this case the scope `%3` is not removed because it's important to get an access violation error at runtime before the undefined value `%x` is used.

This pass considers potential conflicting access scopes in called functions.
But it does not consider potential conflicting access in callers (because it can't!).
However, optimizations, like redundant-load-elimination, can only do such transformations if the outer access scope is within the function, e.g.

```
bb0(%0 : $*T):     // an inout from a conflicting scope in the caller
  store %x to %0
  %3 = begin_access [read] [dynamic] %1
  %y = load %3     // cannot be propagated because it cannot be proved that %1 is the same address as %0
  end_access %3
```

All those checks are only done for dynamic access scopes, because they matter for runtime exclusivity checking.
Dead static scopes are removed unconditionally.
2025-11-24 14:49:45 +01: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
Erik Eckstein
0ff2caea12 SimplifyInstructions: 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:05:15 +01:00
Doug Gregor
47bc712deb [SIL linker] Ensure that we only link the foreign entrypoint when that's all there is 2025-11-22 08:38:48 -08:00
Michael Gottesman
682ef268d2 [optimizer] Teach SIL optimizer that stack nesting should ignore nested stack allocations. 2025-11-21 11:21:15 -08:00
Erik Eckstein
9d02917087 SIL: make a linkage mismatch during de-serialization a human readable diagnostic
Although this error can only happen when tinkering with the stdlib's runtime functions, it's nice to get a readable error message. So far, the compiler just crashed later without a hint to the original problem.
2025-11-21 11:47:46 +01:00
Erik Eckstein
60a28cd570 embedded: don't re-abstract witness method calls for existentials
Don't convert indirect to direct arguments. This is needed to support general existentials in embedded swift.
2025-11-20 10:54:37 -08:00
Kavon Farvardin
7d4f45b303 Merge pull request #85608 from kavon/opaque-values/fixes-5
OpaqueValues: fixes for distributed actors + introduce AccessControls
2025-11-20 06:48:24 -08:00
eeckstein
7ce79f2cdf Merge pull request #85430 from jamieQ/remove-di-non-tuple-carveout
[NFC][DI]: remove getLivenessAtNonTupleInst method from definite init
2025-11-20 10:02:47 +01:00
Kavon Farvardin
7c6d54efa6 OpaqueValues: fix emitDistributedActorSystemWitnessCall
This code was not consulting SILFunctionConventions, so it was
passing things indirect when they are not in sil-opaque-values.

This fixes callers as well to ensure they pass arguments and
results correctly in both modes.
2025-11-19 17:35:14 -08:00
Aidan Hall
ea0f86ed29 Merge pull request #85408 from aidan-hall/164256638
Only print SIL before sub-passes of selected passes with -sil-print-every-subpass
2025-11-19 15:25:50 +00:00
Aidan Hall
305a5efaef SILOptimizer: Disable PackSpecialization pass to unblock SWBs
rdar://164515160
2025-11-17 17:38:13 +00: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
Jamie
c76fad87c6 [NFC][DI]: remove getLivenessAtNonTupleInst method from definite init
The method originally special-cased logic that would provide a
meaningful speedup and simplification, but IIUC the history, this has no
longer been the case for many years, so we might as well remove it to
make the code more straightforward.
2025-11-11 07:17:04 -06:00
Meghana Gupta
e2123e1b3b Merge pull request #85362 from meg-gupta/moreborrow
Add SIL verification for borrow and mutate accessors and some other minor fixes
2025-11-10 09:04:28 -08:00
Aidan Hall
ec14566021 Optimizer: SILPrintEverySubpass: restrict to selected functions 2025-11-10 11:29:31 +00:00
Michael Gottesman
1bb65d8def Merge pull request #85165 from gottesmm/rdar153207557
[sil] Change SILIsolationInfo inference for classmethods to use SILDeclRef instead of using the AST directly.
2025-11-07 02:02:50 -08:00