Commit Graph

248 Commits

Author SHA1 Message Date
Andrew Trick
6849b66bb3 LifetimeDependenceDiagnostics; remove a bootstrapping hack.
This temporary hack was preventing diagnostics from kicking in. This could even
result in invalid SIL after the diagnostic failed to trigger.
2025-01-13 08:30:41 -08:00
Andrew Trick
b0f2ca03a7 AccessUtils: allow mark_deps to be tracked by the EnclosingScope.
This encourages AccessPathWalker clients to handle enclosing mark_deps. In
some cases, it is necessary. The accessBaseWithScopes API now provides both
nested begin_access and mark_dependence.
2025-01-11 15:40:22 -08:00
Erik Eckstein
e215ae990b CopyToBorrowOptimization: correctly handle unchecked_enum_data
A `unchecked_enum_data` which extracts a trivial payload out of a non-trivial enum ends the lifetime of its owned operand.

Fixes an ownership verification error
rdar://142644731
2025-01-10 09:08:31 +01:00
Erik Eckstein
a4c675ec88 CopyToBorrowOptimization: fix insertion order of end_borrows
In liferange exit blocks the end_borrows were inserted in the wrong order.

Fixes an ownership verification error
rdar://142632741
2025-01-10 08:56:42 +01:00
Andrew Trick
49136f237f Fix LifetimeDependenceScopeFixup to avoid rewriting mark_dependence.
This pass rewrites mark_depenendence to ignore "useless" borrow scopes. It was
also accidentally rewriting a dependence on a loaded value, which may redirect the
dependence to the access scope used to load that value. That access scope may be
narrower than the lifetime of the loaded value which could result in invalid
SIL. Do not rewrite this mark_dependence:

  %access = begin_access [read] [unknown] %base
  %load = load [trivial] %access
  end_access %access
  %adr = pointer_to_address
  %md = mark_dependence [unresolved] %adr on %load

Fixes rdar://142424000 (Swift compiler crashes with Assertion failed
(isa<UnreachableInst>(block->getTerminator())))
2025-01-07 15:36:52 -08:00
Erik Eckstein
cd7c533d42 Optimizer: add SingleValueInstruction.replace(with:) and use it throughout the optimizer
It replaces all uses and then erases the instruction.
2024-12-19 20:53:45 +01:00
Erik Eckstein
ca7facde35 SIL: add some use-list APIs
* `users`: maps from a sequence of operands to a sequence of instructions
* `users(ofType:)` : as `users`, but filters users of a certain instruction type
* `Value.users`: = `Value.uses.users`
2024-12-19 20:53:45 +01:00
Erik Eckstein
1545e01ab5 SIL: Let SubstitutionMap.replacementTypes return AST types rather than optional SIL types.
This is what the C++ SubstitutionMap does. One has to use `Type.loweredType` to get from the AST type to the SIL type.
2024-12-19 20:53:45 +01:00
Andrew Trick
1f6a74449d [lifetime] disable trivial dependence enforcement in .swiftinterface
Briefly, some versions of Span in the standard library violated trivial
lifetimes; versions of the compiler built at that time simply ignored
dependencies on trivial values. For now, disable trivial dependencies to allow
newer compilers to build against those older standard libraries. This check is
only relevant for ~6 mo (until July 2025).
2024-12-18 16:57:16 -08:00
Andrew Trick
30d81c9e97 Update a comment; an artifact of merging. 2024-12-17 09:53:25 -08:00
Andrew Trick
3897929e4a LifetimeDependence: handle dependence on trivial values. 2024-12-16 16:09:37 -08:00
Andrew Trick
9f74282680 Redesign LifetimeDependenceScopeFixup to handle accessors.
Handle all combinations of nested dependence scopes: access scopes, coroutines,
and borrow scopes.

This is required to enforce ~Escapable _read accessors and unsafeAddress addressors.

Fixes rdar://140424699 (Invalid SIL is generated by some passes for certain
@lifetime annotations)
2024-12-16 15:28:26 -08:00
Andrew Trick
01279c4a07 Redesign LifetimeDependenceInsertion for coroutines
Generalize the design. Extend it to handle different kinds of coroutine
dependencies: address/value, scoped/inherited.
2024-12-16 15:28:25 -08:00
Erik Eckstein
bdd80aac26 CopyToBorrowOptimization: correctly handle uses in dead-end blocks when removing a copy_value
Fixes an ownership verifier crash
rdar://141278208
2024-12-16 09:44:31 +01:00
Andrew Trick
1d1b260c8f Merge pull request #78199 from atrick/lifedep-cleanup
LifetimeDependence: minor diagnostic quality fixes and related utilities
2024-12-15 04:45:08 -08:00
Andrew Trick
7cfe4a5660 LifetimeDependenceDiagnostics: fix global sourceLoc. 2024-12-14 22:46:55 -08:00
Andrew Trick
e871ce960d LifetimeDependenceDiagnostics pass order comments 2024-12-14 22:46:55 -08:00
Andrew Trick
f5fc17804e [NFC] SwiftCompilerSources: Add VariableScopeInstruction utility
To diagnose dependence on trivial variables.
2024-12-14 22:46:54 -08:00
Erik Eckstein
9cdd9fabae ReleaseDevirtualizer: improve finding the last release of an allocation
With OSSA it can happen more easily that the final release is not immediately located before the related dealloc_stack_ref.
Therefore do a more precise check (using escape analysis) if any instruction between a release and a dealloc_stack_ref might (implicitly) release the allocated object.

This is part of fixing regressions when enabling OSSA modules:
rdar://140229560
2024-12-13 10:06:35 +01:00
eeckstein
81c65758e3 Merge pull request #78059 from eeckstein/destroy-hoisting
Optimizer: add a new destroy-hoisting optimization
2024-12-11 06:18:05 +01:00
Erik Eckstein
5be781a9a0 Optimizer: add a new destroy-hoisting optimization
It hoists `destroy_value` instructions  without shrinking an object's lifetime.
This is done if it can be proved that another copy of a value (either in an SSA value or in memory) keeps the referenced object(s) alive until the original position of the `destroy_value`.
```
  %1 = copy_value %0
  ...
  last_use_of %0
  // other instructions
  destroy_value %0       // %1 is still alive here
```
->
```
  %1 = copy_value %0
  ...
  last_use_of %0
  destroy_value %0
  // other instructions
```

The benefit of this optimization is that it can enable copy-propagation by moving destroys above deinit barries and access scopes.
2024-12-10 16:28:11 +01:00
Erik Eckstein
dd78dc722b Optimizer: add an optimization to remove copy_value of a borrowed value.
It removes a `copy_value` where the source is a guaranteed value, if possible:

```
  %1 = copy_value %0   // %0 = a guaranteed value
  // uses of %1
  destroy_value %1     // borrow scope of %0 is still valid here
```
->
```
  // uses of %0
```

This optimization is very similar to the LoadCopyToBorrow optimization.
Therefore I merged both optimizations into a single file and renamed it to "CopyToBorrowOptimization".
2024-12-09 20:01:07 +01:00
Erik Eckstein
b4ba750481 Optimizer: move Context.erase(instructions:) from Outliner to Context 2024-12-09 19:59:05 +01:00
Erik Eckstein
6a0b7d1f8c ObjectOutliner: create outlined arrays as let variables
This will allow load-simplification to replace a load of such an array.
2024-11-28 09:40:12 +01:00
Andrew Trick
0a70bdd428 LifetimeDependenceDiagnostics: handle undiagnosed mark_depends
Mark unresolved mark_depends as nonescaping so they don't leak into the
optimizer pipeline.
2024-11-18 22:31:07 -08:00
Erik Eckstein
cea7da8d26 RedundantLoadElimination: correctly handle end_borrow instructions
Scope-ending instructions, like `end_borrow` are only irrelevant for RLE if the preceding load is not changed.
If it is changed from `load [copy]` -> `load [take]` the memory effects of those scope-ending instructions prevent that the `load [take]` will illegally mutate memory which is protected from mutation by the scope.

Fixes a memory verifier crash
rdar://139824805
2024-11-14 18:25:11 +01:00
Arnold Schwaighofer
9093e1b0d2 Add comments to SwiftCompilerSources for shouldExpand() 2024-11-05 09:05:24 -08:00
Erik Eckstein
7786596a48 RedundantLoadElimination: support redundant loads of array elements with non-constant index
For example:
```
func test3(_ arr: Array<Int>, index: Int) -> Int {
  return arr[index] + arr[index]
}
```

rdar://138519664
2024-11-04 19:26:45 +01:00
Erik Eckstein
f0633d5638 AccessUtils: support computing "constant" access paths
Add `Value.constantAccessPath`. It is like `accessPath`, but ensures that the projectionPath only contains "constant" elements.
This means: if the access contains an `index_addr` projection with a non-constant index, the `projectionPath` does _not_ contain the `index_addr`.
Instead, the `base` is an `AccessBase.index` which refers to the `index_addr`.
2024-11-04 19:26:44 +01:00
Konrad `ktoso` Malawski
43839ac5fd Merge pull request #76995 from nickolas-pohilets/mpokhylets/disable-stack-promotion
Disable stack promotion for classes with isolated deinit
2024-11-04 18:07:11 +09:00
Arnold Schwaighofer
787c996394 LargeTypesReg2Mem: Add a new heuristic that trys harder to keep large
values on the stack

This heuristic can be enabled by passing -Xfrontend
-enable-aggressive-reg2mem.

rdar://123916109
2024-10-31 13:22:06 -07:00
Mykola Pokhylets
cb7a8d5cfc Disable stack promotion for classes with isolated deinit 2024-10-31 20:43:11 +01:00
Erik Eckstein
b8026d74e6 Revert "Revert "Optimizer: improve the load-copy-to-borrow optimization and implement it in swift""
This reverts commit 0666c446ec.
2024-10-22 08:40:18 +02:00
Erik Eckstein
0666c446ec Revert "Optimizer: improve the load-copy-to-borrow optimization and implement it in swift"
This reverts commit eed8645610.
2024-10-18 10:36:06 +02:00
Erik Eckstein
eed8645610 Optimizer: improve the load-copy-to-borrow optimization and implement it in swift
The optimization replaces a `load [copy]` with a `load_borrow` if possible.

```
  %1 = load [copy] %0
  // no writes to %0
  destroy_value %1
```
->
```
  %1 = load_borrow %0
  // no writes to %0
  end_borrow %1
```

The new implementation uses alias-analysis (instead of a simple def-use walk), which is much more powerful.

rdar://115315849
2024-10-11 09:41:37 +02:00
Erik Eckstein
10782cf42b SwiftCompilerSources: introduce the AST module
As the optimizer uses more and more AST stuff, it's now time to create an "AST" module.
Initially it defines following AST datastructures:
* declarations: `Decl` + derived classes
* `Conformance`
* `SubstitutionMap`
* `Type` and `CanonicalType`

Some of those were already defined in the SIL module and are now moved to the AST module.
This change also cleans up a few things:
* proper definition of `NominalTypeDecl`-related APIs in `SIL.Type`
* rename `ProtocolConformance` to `Conformance`
* use `AST.Type`/`AST.CanonicalType` instead of `BridgedASTType` in SIL and the Optimizer
2024-10-02 07:10:29 +02:00
Erik Eckstein
701a7f7275 SwiftCompilerSources: don't make anything public in the Optimizer module
The Optimizer module is a leave module. No other modules depend on it. Therefore nothing must be public in this module.
2024-10-02 07:10:28 +02:00
Erik Eckstein
e683d7b679 ComputeSideEffects: fix a corner case with consuming indirect arguments in dead-end functions
Usually there _must_ be a read from a consuming in-argument, because the function has to consume the argument.
But in the special case if all control paths end up in an `unreachable`, the consuming read might have been dead-code eliminated.
Therefore make sure to add the read-effect in any case. Otherwise it can result in memory lifetime failures at a call site.

fixes a memory lifetime failure

rdar://134881045
2024-08-29 18:51:46 +02:00
Erik Eckstein
c96b196ffa SwiftCompilerSources: bridge SILLinkage
Make SILLInkage available in SIL as `SIL.Linkage`.
Also, rename the misleading Function and GlobalVariable ABI `isAvailableExternally` to `isDefinedExternally`
2024-08-22 08:56:27 +02:00
Erik Eckstein
a5ef2b30f1 DeinitDevirtualizer: Don't run the pass on non-OSSA functions 2024-08-12 13:34:50 +02:00
Alexander Cyon
c18a24e499 [SwiftCompilerSources] Fix typos 2024-08-08 22:22:39 -07:00
Andrew Trick
11ba799cd4 LifetimeDependence: diagnose yield and store-to-yield. 2024-07-30 16:27:48 -07:00
Andrew Trick
c8fcb722a3 LifetimeDependenceInsertion for inout dependencies. 2024-07-30 15:57:57 -07:00
Andrew Trick
ba9f12a80f LifetimeDependenceDiagnostics support for inout reassignment.
This relies on parameter dependence targets.

i.e. dependsOn in parameter position instead of result position.
2024-07-30 15:57:57 -07:00
Andrew Trick
058d22b2b6 Fix LifetimeDependenceScopeFixup for loops.
Handle situations in which the uses of the new scope are inside a loop so the
new range has no end instructions.
2024-07-30 15:57:56 -07:00
Andrew Trick
f3cf529b5d [SwiftCompilerSources] use debugLog in diagnostic passes 2024-07-30 15:57:56 -07:00
Andrew Trick
d065a3e576 Merge pull request #75562 from atrick/nfc-lifedep
[nfc] LifetimeDiagnostics cleanup
2024-07-30 09:03:24 -07:00
Andrew Trick
1113c757f0 Improve function convention printing. 2024-07-29 23:44:02 -07:00
Andrew Trick
20905b2f8e LifetimeDependenceDiagnostics comment. 2024-07-29 23:44:02 -07:00
Andrew Trick
103c59b273 [SwiftCompilerSources] Add assert to Builder.init(after:)
This API is incorrect for terminators. Assert that it isn't used
incorrectly. Later, we should rename it.
2024-07-29 23:44:02 -07:00