Commit Graph

1235 Commits

Author SHA1 Message Date
Andrew Trick
5864004c4e SwiftCompilerSources: remove adjacent phis from InteriorUseWalker.
The extra complexity for traversing phis is not needed now that it handles
borrowed-from instructions. Remove the redundant logic because it complicates
the liveness algorithm and generates confusing results.
2025-02-25 23:08:54 -08:00
Andrew Trick
5a1a487d14 Fix InteriorUseWalker to handle dependent lifetimes as inner scopes
Inner scopes must all be reported because the walker assumes they are
complete. It is up to the client to either complete them or recursively follow
them.
2025-02-25 23:08:54 -08:00
Andrew Trick
7f6962adff Fix OwnershipUseVisitor.dependentUse()
Check if the forwarded value is trivial, not the base value. Presumably, we
won't call this visitor at all if the base is trivial.

Record a dependent non-Escapable values as a pointer-escape. InteriorUseWalker
does not handle lifetime dependencies. That requires
LifetimeDependenceDefUseWalker.
2025-02-25 23:08:54 -08:00
Andrew Trick
f1792d80b3 Fix BorrowingOperand.visitScopeEndingUses
Only return false if the visitor returns false. Clients were ignoring the
result.

If the BorrowingOperand does not create a borrow scope, call visitUnknownUse
instead.

Until we have complete lifetimes, to avoid breaking code that cannot handle dead
defs, consider a dead borrow scope to be an unknown use.
2025-02-25 23:08:54 -08:00
Andrew Trick
a4a675ee00 Remove adjacent phi handling from InteriorUseWalker.
At least the Swift utilities should rely on borrowed-from.
2025-02-25 23:08:54 -08:00
Andrew Trick
6188d29026 Handle borrowed-from in OwnershipUseVisitor.
If it is not a reborrow, then it produces a dependent value, just like
mark_dependence.
2025-02-25 23:08:54 -08:00
Andrew Trick
e22541544c Remove unused computeInterorLiveness API.
This encourages the client to check whether InteriorLivenessResult is valid or
escaping before using the instruction range.
2025-02-25 23:08:54 -08:00
Andrew Trick
fda53929c2 Add support for borrowed-from to BorrowingInstruction.
All instructions with a "Borrow" operand ownership must be valid
BorrowingInstructions.
2025-02-25 23:08:54 -08:00
Andrew Trick
6c99017588 Minor comment cleanup and code formatting.
Extracted from the functional changes for clarity.
2025-02-25 23:08:53 -08:00
Andrew Trick
75e84f1e97 Rename InteriorLiveness methods for clarity.
It was too easy to confuse the "inner" vs. "outer" value.

Use less ambigous names: visitAllUses vs visitInnerScopeUses
2025-02-25 23:08:53 -08:00
Erik Eckstein
57a236e671 InitializeStaticGlobals: support statically initializing globals which are or contain inline arrays
For example:

```
struct S {
  static let slab: Slab = [1, 2, 3, 4]
}
```

rdar://143005996
2025-02-12 22:37:49 +01:00
eeckstein
dff88f968b Merge pull request #79317 from eeckstein/remove-alloc-vector
Remove the experimental FixedArray
2025-02-12 17:03:06 +01:00
eeckstein
b6639e1782 Merge pull request #79314 from eeckstein/fix-simplify-keypath
SimplifyKeyPath: insert the correct destroy operation for an operand of a removed keypath
2025-02-12 15:18:39 +01:00
Erik Eckstein
e0b4f71af6 SIL: remove the alloc_vector instruction
It's not needed anymore, because the "FixedArray" experimental feature is replaced by inline-arrays.
2025-02-12 10:51:14 +01:00
Erik Eckstein
6407f9a0bd remove the allocVector builtin
It's not needed anymore, because the "FixedArray" experimental feature is replaced by inline-arrays.
2025-02-12 10:51:14 +01:00
Erik Eckstein
5b93eb31bf Optimizer: remove the AllocVectorLowering pass
It's not needed anymore, because the "FixedArray" experimental feature is replaced by inline-arrays.
2025-02-12 10:51:14 +01:00
Erik Eckstein
3f95ce9645 Optimizer: fix spelling of the Simplifiable protocol
Rename `Simplifyable` -> `Simplifiable`

NFC
2025-02-12 09:01:11 +01:00
Erik Eckstein
2962474b58 SimplifyKeyPath: insert the correct destroy operation for an operand of a removed keypath
If the operand is an address, we need to use `destroy_addr` and not `destroy_value`.

Fixes a compiler crash.
rdar://144662171
2025-02-12 08:35:23 +01:00
eeckstein
aa0833b0b3 Merge pull request #79110 from eeckstein/verify_mark_dependence
SIL: Fix memory behavior of mark_dependence
2025-02-11 06:39:43 +01:00
Andrew Trick
c2842e8e19 LifetimeDependenceInsertion: remove a bailout on ~Copyable
Needed to diagnose MutableSpan and OutputSpan.

For now, simply remove the bailout and TODO. The next change will introduce more
logic to force a diagnostic error in rare cases that can't be handled completely.

Fixes rdar://143584461 (Extended exclusive borrow issues with
MutableSpan and OutputSpan)
2025-02-10 09:13:27 -08:00
Andrew Trick
fa3ebb5c1e LifetimeDependence.Scope add global variable support.
This fixes functions that return @lifetime(immortal).
2025-02-10 09:11:22 -08:00
Andrew Trick
39bae0bb58 LifetimeDependenceDiagnostics: immortal dependence on global 'let' 2025-02-10 09:11:22 -08:00
Andrew Trick
c3de120ca5 LifetimeDependence: simplify and fix multiple bugs.
Functional changes:

Improved modeling of dependence on local variable scopes.

For nested modify->read accesses, only extend the read accesses.

Avoid making a read access dependent on an inout argument.
The following needs to be an error to prevent span storage from being modified:

  @lifetime(owner)
  foo(owner: inout Owner) -> Span {
    owner.span
  }

Improve usability of borrowing trivial values (UnsafePointer). Allow:

  let span = Span(buffer.baseAddress)

Ignore access scopes for trivial values.

Structural changes:

Delete the LifetimeDependenceUseDefWalker.

Encapsulate all logic for variable introducers within the LifetimeDependenceInsertion pass. Once mark_dependence instructions are inserted, no subsequent pass needs to think about the "root" of a dependence.

Fixes: rdar://142451725 (Escape analysis fails with mutations)
2025-02-10 09:11:22 -08:00
Andrew Trick
eae2f06dc7 Extend and improve AccessBase.findSingleInitializer
Return an Initializer rather than a tuple. This makes it easier and more robust
for clients to track dependencies on initialized memory.
2025-02-10 09:11:22 -08:00
Andrew Trick
8b39b6d16a LocalVariableUtils: record mark_dependence bad address operands
Avoid bailing out when something depends on the local variable.
2025-02-10 09:11:22 -08:00
Andrew Trick
18de6051de Add BeginAccess.AccessKind.isCompatible(with:ArgumentConvention)
General utility to determine whether an argument already has an access scope
that is compatibly with this BeginAccess.
2025-02-10 09:11:22 -08:00
Andrew Trick
128b0e711a Add Value.isForwarded(from:)
A simple utility on ForwardingInstructions that should be defined alongside
similar utilities rather than inside a pass.
2025-02-10 09:11:22 -08:00
Andrew Trick
f56d98408c Fix VariableScopeInstruction.endOperands for extend_lifetime.
Consider end_lifetime to be part of the endOperands set, which is used for
linear liveness, even though it does not end the lifetime.
2025-02-10 09:11:22 -08:00
Andrew Trick
c0ad676ac6 Add AccessBaseAndScopes API: outerAddress, enclosingAddress. 2025-02-10 09:11:22 -08:00
Andrew Trick
0f537b220e Add BeginAccessInst.unsafeAddressorSelf. 2025-02-10 09:11:21 -08:00
Andrew Trick
84e9e0157a SwiftCompilerSources: Add SingleInlineArray.popLast() 2025-02-10 09:11:21 -08:00
Erik Eckstein
a88cb49ee8 SIL: define a memory-read effect on the mark_dependence base value
If the base value of a mark_dependence is an address, that memory location must be initialized at the mark_dependence.
This requires that the mark_dependence is considered to read from the base address.
2025-02-10 17:57:47 +01:00
Erik Eckstein
33761454b7 MandatoryPerformanceOptimizations: use eliminateRedundantLoads instead of optimizeMemoryAccesses to optimize redundant loads 2025-02-07 11:30:35 +01:00
Erik Eckstein
ce73deebc4 RedundantLoadElimination: add a "mandatory" redundant load elimination pass
And make `eliminateRedundantLoads` callable from other optimizations
2025-02-07 11:30:35 +01:00
Erik Eckstein
2af24703ab RedundantLoadElimination: insert mark_dependence instructions for a removed load
If the memory location depends on something, insert a dependency for the loaded value:
```
  %2 = mark_dependence %1 on %0
  %3 = load %2
```
->
```
  %2 = mark_dependence %1 on %0 // not needed anymore, can be removed eventually
  %3 = load %2
  %4 = mark_dependence %3 on %0
  // replace %3 with %4
```
2025-02-07 11:30:35 +01:00
Erik Eckstein
5acccf1802 RedundantLoadElimination: ignore memory effects of begin_access
Memory effects of begin_access are only defined to prevent the optimizer moving loads and stores across a begin_access.
But those memory effects are not relevant for RedundantLoadElimination
2025-02-07 11:30:35 +01:00
Erik Eckstein
ad2462f7f2 RedundantLoadElimination: optimize a load from a memory location which was written by copy_addr
For example:
```
  %1 = alloc_stack $B
  copy_addr %0 to [init] %1
  %3 = load [take] %1
  dealloc_stack %1
```
->
```
  %3 = load [copy] %0
```
2025-02-07 11:30:34 +01:00
Andrew Trick
a54a23a1e6 Merge pull request #79177 from atrick/fix-markdep-ownership
Fix mark_dependence [nonescaping] ownership
2025-02-06 01:18:14 -08:00
Andrew Trick
e705a6d7c3 Temporarily introduce AnyInteriorPointer operand ownership.
This is necessary to fix a recent OSSA bug that breaks common occurrences on
mark_dependence [nonescaping]. Rather than reverting that change above, we make
forward progress toward implicit borrows scopes, as was the original intention.

In the near future, all InteriorPointer instructions will create an implicit
borrow scope. This means we have the option of not emitting extraneous
begin/end_borrow instructions around intructions like ref_element_addr,
open_existential, and project_box. After that, we can also migrate
GuaranteedForwarding instructions like tuple_extract and struct_extract.
2025-02-05 16:23:02 -08:00
Rintaro Ishizaki
9078714460 [BasicBriding] Use assumingMemoryBound(to:)
For accessing elements in BridgedArrayRef in Swift code.
2025-02-05 10:49:13 -08:00
Erik Eckstein
9b2dfbb741 DestroyHoisting: visit begin_borrows which don't have an end_borrow in dead-end blocks.
This makes sure that incomplete lifetimes are handled correctly.

Fixes an ownership violation.
rdar://144065326
2025-02-04 12:59:40 +01:00
Arnold Schwaighofer
c95c45201e Merge pull request #78996 from aschwaighofer/checked_cast_br_nightmares
SIL: Update formal source type in SimplifyRefCasts when possible
2025-02-02 08:27:01 -08:00
Arnold Schwaighofer
0fe3cf0096 SIL: Update formal source type in SimplifyRefCasts when possible
We use the formal source type do decide whether a checked_cast_br is
known to succeed/fail. If we don't update it we loose that optimization

That is:

```
  checked_cast_br AnyObject in %2 : X to X, bb1, bb2
```

Will not be simplified even though the operand and the destintation type
matches.
2025-01-29 09:07:21 -08:00
Kuba (Brecka) Mracek
7c685ba36b Merge pull request #78915 from kubamracek/embedded-string-switch-with-cache
[embedded] Support _findStringSwitchCaseWithCache in Embedded Swift
2025-01-28 15:56:22 -08:00
Kuba Mracek
e1d22b5076 [embedded] Avoid changing lookupStdlibFunction, load findStringSwitchCaseWithCache in MPO instead 2025-01-28 10:03:14 -08:00
Erik Eckstein
1f534e1c6f DeinitDevirtualizer: bail out for C++ move-only types.
We cannot de-virtualize C++ destructor calls of C++ move-only types because we cannot get its destructor in SIL.
Fixes a miscompile.
2025-01-27 09:59:48 +01:00
Erik Eckstein
f53635911c Swift AST: add var Decl.hasClangNode 2025-01-27 09:59:48 +01:00
Kuba Mracek
92b0c5f5d0 [embedded] Support _findStringSwitchCaseWithCache in Embedded Swift 2025-01-25 09:09:47 -08:00
Erik Eckstein
3ec5d7de24 SIL: replace the is_escaping_closure instruction with destroy_not_escaped_closure
The problem with `is_escaping_closure` was that it didn't consume its operand and therefore reference count checks were unreliable.
For example, copy-propagation could break it.
As this instruction was always used together with an immediately following `destroy_value` of the closure, it makes sense to combine both into a `destroy_not_escaped_closure`.
It
1. checks the reference count and returns true if it is 1
2. consumes and destroys the operand
2025-01-24 19:23:27 +01:00
eeckstein
694ee2d9c6 Merge pull request #78849 from eeckstein/autodiff-workarounds
Two workarounds for autodiff specific optimizations with OSSA
2025-01-24 15:53:32 +01:00