Commit Graph

1069 Commits

Author SHA1 Message Date
Meghana Gupta
3cad5c5924 Merge pull request #81043 from meg-gupta/fixcow
Insert end_cow_mutation_addr for lifetime dependent values dependent on mutable addresses
2025-05-01 07:26:28 -07:00
Andrew Trick
2a6a621dd8 Merge pull request #81222 from atrick/missing-markdep
Fix LifetimeDependenceInsertion: handle boxed indirect out arguments
2025-05-01 00:43:03 -07:00
Andrew Trick
9d8e8d3f05 Fix LifetimeDependenceInsertion: handle boxed indirect out arguments
Correctly generate dependency tracking for functions that return a non-Escapable
existential, such as:

func getMutableSpanWithOpaqueReturn(_ array: inout [Int]) -> any PAny & ~Copyable & ~Escapable

Previously, dependency insertion assumed that @out storage always initialized an
alloc_stack. But existentials are always boxed.

First, add a diagnostic to catch any missing dependency insertions now that
we're past the bootstrapping phase.

Then, generalize handling of dependency insertion to handle any access base as
long as it has a recognizable address source.

Fixes rdar://150388126 (Missing mark_dependence for opaque lifetime dependent
value)
2025-04-30 15:50:13 -07:00
Meghana Gupta
5395721a20 Bridge getSwiftMutableSpanDecl() and isBuiltinType() 2025-04-30 13:40:12 -07:00
Meghana Gupta
35d62a4a36 Introduce end_cow_mutation_addr instruction 2025-04-30 13:39:45 -07:00
Meghana Gupta
4951f628ad Insert end_cow_mutation_addr for lifetime dependent values dependent on mutable addresses
Array/ArraySlice/ContiguousArray have support for mutableSpan property.
These types are "optimized COW" types, we use compiler builtins begin_cow_mutation/end_cow_mutation to
optimize uniqueness checks. Since mutableSpan is a property and not a coroutine there is
no way to schedule the end_cow_mutaton operation at the end of the access.
This can lead to miscompiles in rare cases where we can end up using a stale storage buffer after a cow.

This PR inserts end_cow_mutation_addr to avoid this issue.

Note: We can end up with unnecessary end_cow_mutation_addr. But it is just a barrier to prevent invalid optimizations
and has no impact.
2025-04-30 13:37:45 -07:00
Andrew Trick
4a65be8074 Fix LifetimeDependenceScopeFixup: extend scopes enclosing coroutines
When a coroutine is extended because of a dependent lifetime, extend all scopes
that enclose that coroutine even if the coroutine itself has no lifetime
dependencies.

Fixes rdar://150275147 (Invalid SIL after lifetime dependence fixup involving
coroutines)
2025-04-30 11:27:57 -07:00
Andrew Trick
ed7c2b9316 LifetimeDependenceDiagnostics: note for unsupported closure capture
Add a note explaining that dependence on closure captures is not
supported. Otherwise, the diagnostics are very confusing:
"it depends on a closure capture; this is not yet supported"
2025-04-30 09:13:23 -07:00
Andrew Trick
885798932d LifetimeDependence: clarify diagnostics for many unusual cases.
Ensure that we always issue a diagnostic on error, but avoid emitting any notes that don't have source locations.

With implicit accessors and thunks, report the correct line number and indicate which accessor generates the error.

Always check for debug_value users.

Consistently handle access scopes across diagnostic analysis and diagnostic messages.
2025-04-30 09:13:23 -07:00
Andrew Trick
1c49b26153 LifetimeDependenceDiagnostics: avoid infinite recursion on error
Fix a simple typo that results in infinite recursion on invalid code.

Fixes rdar://147470493 ([nonescapable] LifetimeDependenceInsertion: infinite
recursion in VariableUseDefWalker.walkup with immortal setter)
2025-04-30 09:13:23 -07:00
Erik Eckstein
65178170b1 ComputeSideEffects: handle program termination functions which are defined in the same module
This case was neglected. The fix can result in better side effect analysis, e.g. in the stdlib core module.
2025-04-29 20:30:21 +02:00
Erik Eckstein
d80f7a3560 SIL: make BeginBorrowInstruction.endOperands and BeginBorrowValue.scopeEndingOperands consistent.
* rename `ScopedInstruction.endOperands` -> `scopeEndingOperands`
* let them behave the same way. For `load_borrow` there was a difference because `endOperands` didn't consider branches to re-borrow phis.
2025-04-28 10:24:56 +02:00
Erik Eckstein
cbf5c196b2 SIL: rename protocol BorrowIntroducingInstruction -> BeginBorrowInstruction
to match with `BeginBorrowValue`
2025-04-28 10:07:45 +02:00
Erik Eckstein
0dee86590d SIL: make protocol ScopeInstruction an Instruction protocol
This allows to remove the `var instruction` property.

NFC
2025-04-28 09:40:06 +02:00
Andrew Trick
8a48cd979b Bypass lifetime diagnostics in interfaces for copied arguments.
Briefly (April 2025), RawSpan._extracting, Span._extracting, and UTF8Span.span
returned a borrowed value that depended on a copied argument. Continue to
support those interfaces. The implementations were correct but needed an
explicit _overrideLifetime.
2025-04-25 18:52:20 -07:00
Andrew Trick
4f470a1d34 Fix LifetimeDependenceDiagnostics: scoped dependence on a copy
Diagnose a scoped dependence on an argument that inherits its lifetime as an
error:

@lifetime(borrow arg)
func reborrowSpan<T>(_ arg: Span<T>) -> Span<T> { arg }

@lifetime(copy span)
public func testBorrowInheritedArg<T>(_ span: Span<T>) -> Span<T> {
  reborrowSpan(span) // expected-error {{lifetime-dependent value escapes its scope}}
}

Fixes: rdar://146319009 ([nonescapable] enforce borrow constraint narrowing of inherited lifetime)
2025-04-25 17:58:23 -07:00
Andrew Trick
92b2a8587f Fix LifetimeDependenceDiagnostics: handle mark_dependence_addr
A small typo meant that scoped dependencies modeled with mark_dependence_addr
were not diagnosed.
2025-04-25 17:58:23 -07:00
Andrew Trick
060364546a [NFC] LifetimeDependenceUtils comment 2025-04-25 17:58:23 -07:00
Andrew Trick
bb9e52c3f2 LifetimeDependenceScopeFixup: cleanup for clarity 2025-04-25 17:58:23 -07:00
Andrew Trick
b4b93ef34c Merge pull request #81061 from atrick/rdar147500193-vector-expectEquals
Fix LifetimeDependenceDiagnostics: handle address-only 'let's
2025-04-24 11:59:48 -07:00
Andrew Trick
5831777407 Fix LifetimeDependenceDiagnostics: handle address-only 'let's
Add a case to LifetimeDependence.Scope to support dependencies on address-only
'let' variables. This comes up with C++ interop.

Fixes rdar://147500193 (Spurious lifetime error with closures)
2025-04-23 22:48:27 -07:00
eeckstein
8226f20ddb Merge pull request #80912 from eeckstein/copyaddr-in-rle
RedundantLoadElimination: support replacing a redundant `copy_addr` with a `store`
2025-04-23 20:59:03 +02:00
Erik Eckstein
8cf4e34cc1 RedundantLoadElimination: support replacing a redundant copy_addr with a store
For example:
```
  %0 = load %1
  copy_addr %1 to %2
```
->
```
  %0 = load %1
  store %0 to %2
```

This is important for MandatoryRedundantLoadElimination to be able to create statically initialized globals in the mandatory pipeline.
For example:
```
public struct MyStruct {
  public static let r: Range<Int> = 1 ..< 3
}

```
gets a statically initialized global, even at Onone, with this improvement.

rdar://149356742
2025-04-23 11:57:28 +02:00
Andrew Trick
3b08592ed2 Fix LifetimeDependenceDiagnostics: handle drop_deinit unsafeAddress
This adds support to handle unsafe addressors, which generate mark_dependence
instructions with an address base. This case does not arise with lifetime
dependencies. Nonetheless, the lifetime dependence diagnostics kick in to
attempt to promote the unsafe addressor's mark_dependence to noescape, so we
need to handle it.

rdar://149784450 (Compiler crash with non-escapable deinit dereferencing)
2025-04-22 22:35:09 -07:00
Andrew Trick
33fbe11bf8 Fix LifetimeDependenceScopeFixup: read access can depend on 'inout'
Allow a dependency on a local [read] access scope to be transfered to the
caller's [modify] access.

Fixes rdar://149560133 (Invalid lifetime dependence error when
trying to return Span from an inout argument)
2025-04-22 11:54:53 -07:00
Andrew Trick
a1aaed9159 LifetimeDependenceScopeFixup: handle returning dependent Optional
Add support for returnValue phis (e.g. to return an Optional .some or .none).

Fixes rdar://149397018 (Wrapping non escapable in an Optional
(or any copy lifetime wrapper) is an escape)
2025-04-21 22:33:38 -07:00
Erik Eckstein
6c31eb0c43 embedded: rewrite the diagnostic pass for embedded swift
1. move embedded diagnostics out of the PerformanceDiagnostics pass. It was completely separated from the other logic in this pass, anyway.
2. rewrite it in swift
3. fix several bugs, that means: missed diagnostics, which led to IRGen crashes
  * look at all methods in witness tables, including base protocols and associated conformances
  * visit all functions in the call tree, including generic functions with class bound generic arguments
  * handle all instructions, e.g. concurrency builtins
4. improve error messages by adding meaningful call-site information. For example:
  * if the error is in a specialized function, report where the generic function is originally specialized with concrete types
  * if the error is in a protocol witness method, report where the existential is created
2025-04-18 06:58:40 +02:00
Erik Eckstein
d222cf20f1 MandatoryPerformanceOptimizations: support default methods for class existentials
For example:
```
protocol P: AnyObject {
  func foo()
}
extension P {
  func foo() {}
}
class C: P {}

let e: any P = C()
```

Such default methods are SILGen'd with a generic self argument. Therefore we need to specialize such witness methods, even if the conforming type is not generic.

rdar://145855851
2025-04-18 06:58:40 +02:00
Erik Eckstein
655dae825a Optimizer: add Options.noAllocations 2025-04-18 06:58:39 +02:00
Erik Eckstein
f0f1c3c84b SIL: make SILFunctionConvention constructible without needing a SIL function
Add an initializer which takes the `hasLoweredAddresses` directly and add `Context.moduleHasLoweredAddresses`
2025-04-18 06:58:38 +02:00
Erik Eckstein
75152f27be Swift AST: make Conformance hashable and rename var proto -> var protocol 2025-04-18 06:58:38 +02:00
Erik Eckstein
1c9a7cd562 SwiftCompilerSources: refactor DiagnosticEngine
* move it from the SIL to the AST module (where it belongs)
* change the signature of `diagnose` from `diagnose(location, .some_error)` to `diagnose(.some_error, at: location)`
* add an overload to allow passing a `SIL.Location` directly to `diagnose`
* add a `Diagnostic : Error` utility struct which allows throwing a `Diagnostic`
2025-04-18 06:58:38 +02:00
Andrew Trick
6f8605263d Fix unidentified LifetimeDependence.Scope initialization.
Fixes rdar://149226564 (Compiler crash with non-escapable storing another
non-escapable and having a deinit)
2025-04-16 16:46:38 -07:00
Andrew Trick
62454f42fd LifetimeDependenceScopeFixup: _read accessor: extend temporaries
Add support for extending owned temporary values in addition to access scopes
and borrow scopes. Required for _read accessors in which the coroutine depends
on an owned value.
2025-04-16 16:46:38 -07:00
Andrew Trick
4e35d255ad LocalVariableUtils: add store_borrow access tracking.
We sometimes use LocalVariableUtils to analyze temporary storage in which the
store_borrow is not already enclosed by an access scope.
2025-04-16 16:46:38 -07:00
Andrew Trick
b80bd16eea [NFC] Add LifetimeDependenceUseDefWalker utility.
Refactor VariableIntroducerUseDefWalker into a general
LifetimeDependenceUseDefWalker for use with LifetimeDependenceScopeFixup.
2025-04-16 16:43:23 -07:00
Andrew Trick
43debc529f [NFC] minor cleanup 2025-04-16 16:43:23 -07:00
Andrew Trick
28daec01a7 Add InstructionRange.overlapsWithPath() utility. 2025-04-16 16:43:23 -07:00
Andrew Trick
2bdaa68e98 SwiftCompilerSources: add IgnoredUseInst as incidental
Fixes rdar://148540048 (Assigning span value to `_` results in an incorrect escape diagnostic)
2025-04-16 16:42:36 -07:00
eeckstein
a9c6da6c70 Merge pull request #80819 from eeckstein/copy-block-optimization
Optimizer: remove redundant `copy_block` instructions
2025-04-15 20:17:02 +02:00
Anton Korobeynikov
87ca0f8680 Fix ownership issues with sequences of partial_apply's in AutoDiff closure specialization pass (#80662)
Each partial_apply consumes its arguments, therefore we should never release intermediate ones in the sequence of closures.

Fixes #78847
2025-04-15 07:14:44 -07:00
Erik Eckstein
199eb1d6e7 Optimizer: remove redundant copy_block instructions
Removes a `copy_block` if its only uses, beside ownership instructions, are callees of function calls
```
  %2 = copy_block %0
  %3 = begin_borrow [lexical] %2
  %4 = apply %3() : $@convention(block) @noescape () -> ()
  end_borrow %3
  destroy_value %2
```
->
```
  %4 = apply %0() : $@convention(block) @noescape () -> ()
```

rdar://118521396
2025-04-15 11:02:39 +02:00
Andrew Trick
4b5d5197ae Merge pull request #80782 from atrick/rdar143992296-addressliverange
Fix AddressOwnershipLiveRange to include the full range.
2025-04-12 15:02:35 -07:00
Andrew Trick
c9279d9899 Fix AddressOwnershipLiveRange to include the full range.
This allows further extension of access scopes.

Fixes rdar://143992296 (Use of `RawSpan` in switch context causes compiler crash
in AddressOwnershipLiveRange)
2025-04-11 23:49:07 -07:00
Meghana Gupta
2c462ba368 Merge pull request #80733 from meg-gupta/updatectb
Handle a special case of borrowed from instruction in CopyToBorrowOptimization
2025-04-11 21:12:54 -07:00
Meghana Gupta
fe780b670f Handle a special case of borrowed from instruction in CopyToBorrowOptimization 2025-04-11 13:21:22 -07:00
Andrew Trick
ccb26bcd89 LocalVariableUtils: add unit tests 2025-04-10 23:27:55 -07:00
Andrew Trick
37ecd0e9bd LocalVariableUtils: fix data flow propagation of escapes.
This is only used for lifetime dependence diagnostics.

Fix a couple of obvious problems with data flow propagation that crept in during
"cleanup" because no unit tests existed.
2025-04-10 23:27:55 -07:00
Andrew Trick
6e51dd8534 Merge pull request #80628 from atrick/address-escape-effect
Fix escape analysis: addressable parameters.
2025-04-08 13:40:02 -07:00
Andrew Trick
05a9acbb40 Fix escape analysis: addressable parameters.
An address-type parameter may escape via an indirect argument if the function's
result depends on the argument's address.
2025-04-08 00:07:30 -07:00