Commit Graph

75 Commits

Author SHA1 Message Date
Erik Eckstein
92a17f8a01 Optimizer: extract the NamedReturnValueOptimization from CopyForwarding to a separate function pass
This allows to run the NamedReturnValueOptimization only late in the pipeline.
The optimization shouldn't be done before serialization, because it might prevent predictable memory optimizations in the caller after inlining.
2023-05-11 08:11:44 +02:00
Erik Eckstein
3d555a412a refactor two swift passes
NFC
2023-05-10 16:04:57 +02:00
Erik Eckstein
6d6b94e430 Swift Optimizer: add the InitializeStaticGlobals function pass
It converts a lazily initialized global to a statically initialized global variable.

When this pass runs on a global initializer `[global_init_once_fn]` it tries to create a static initializer for the initialized global.
```
  sil [global_init_once_fn] @globalinit {
    alloc_global @the_global
    %a = global_addr @the_global
    %i = some_const_initializer_insts
    store %i to %a
  }
```

The pass creates a static initializer for the global:
```
  sil_global @the_global = {
    %initval = some_const_initializer_insts
  }
```

and removes the allocation and store instructions from the initializer function:
```
  sil [global_init_once_fn] @globalinit {
    %a = global_addr @the_global
    %i = some_const_initializer_insts
  }
```

The initializer then becomes a side-effect free function which let's the builtin-simplification remove the `builtin "once"` which calls the initializer.
2023-05-08 21:23:36 +02:00
Nate Chandler
fc13686403 [ObjCBridgingOpt] Look through copy_value insts. 2023-03-29 11:39:43 -07:00
Erik Eckstein
f1095556c9 Swift SIL: let var UnaryInstruction.operand return an Operand and not a Value
To avoid confusion. Instead add specific getters for unary instructions with dedicated names.

NFC
2023-02-21 17:57:29 +01:00
Erik Eckstein
490c8fa1c2 ComputeEscapeEffects: some refactoring
Mostly source-code restructuring to make the source easier to read.
NFC
2023-02-15 18:42:38 +01:00
Erik Eckstein
8984046972 Effects: remove the isExclusive flag from the escapingToArgument effect
An argument-to-argument escape always involves a store, which makes an exclusive escape impossible.
2023-02-15 18:17:32 +01:00
Erik Eckstein
7a3ae09cfc Effects: add some comments and add enum argument labels
For clarity
2023-02-15 18:17:32 +01:00
Erik Eckstein
113e23df03 ComputeEscapeEffects: correctly handle "exclusive" argument -> return effects
* Disallow stores in the return -> argument path. When walking up in the EscapeUtils, it's allowed to follow stores. Therefore stores wouldn't be handled correctly.
* Also make sure that there is a return -> argument path at all

Fixes a wrong address-escaping effect in case the called function copies an indirect argument to a newly created object.
rdar://105133434
2023-02-13 16:10:17 +01:00
Erik Eckstein
caea41a4e0 ComputeEscapeEffects: don't support exclusive argument -> argument effects.
Exclusive argument -> argument effects cannot appear because such an effect would involve a store which is not permitted for exclusive escapes.
2023-02-13 16:10:17 +01:00
Erik Eckstein
dfde580872 Effects: bail if effects are requested for not supported projection paths
Effects are only defined for operations which don't involve a load.
 In case the argument's path involves a load we need to return the global effects.
2023-02-11 08:55:20 +01:00
Erik Eckstein
cc60815bfe ComputeSideEffects: fix wrong side effect computation of releases/destroys
Only global side effects of the destructor were considered, but side effects weren't attributed to the released value.

rdar://105237110
2023-02-11 08:55:20 +01:00
Erik Eckstein
7eb2cb82e4 Swift Optimizer: add a pass to cleanup debug_step instructions
If a `debug_step` has the same debug location as a previous or succeeding instruction it is removed.
It's just important that there is at least one instruction for a certain debug location so that single stepping on that location will work.
2023-02-09 06:50:05 +01:00
Erik Eckstein
67ed6cfff8 Swift Optimizer: add Simplification passes
Those passes are a framework for instruction simplifications (which are not yet included in this commit).
Comparable to SILCombine
2023-02-09 06:49:58 +01:00
Erik Eckstein
393d1a1488 SIL Builder: rename insert(at:) -> insert(before:)
It matches with `insert(after:)` and the intent should be clearer now
2023-01-16 15:11:34 +01:00
Erik Eckstein
cc68bd98c9 Swift Optimizer: rework pass context types and instruction passes
* split the `PassContext` into multiple protocols and structs: `Context`, `MutatingContext`, `FunctionPassContext` and `SimplifyContext`
* change how instruction passes work: implement the `simplify` function in conformance to `SILCombineSimplifyable`
* add a mechanism to add a callback for inserted instructions
2023-01-16 15:11:34 +01:00
Erik Eckstein
c32d6cd0fb EscapeUitls: some refactoring 2023-01-16 15:11:34 +01:00
Erik Eckstein
eb0d6ed87e StackPromotion: some refactoring
NFC
2023-01-16 15:11:34 +01:00
Erik Eckstein
6c35258f83 Swift SIL: rename parent accessors to parentX, e.g. Instruction.parentBlock
It makes it easier to read
2023-01-16 15:11:34 +01:00
Erik Eckstein
1f0f9d65b9 ComputeSideEffects: ignore side effects of debug_value with address operands
We already ignored side effects of debug_value with non-address operands. Now also do this for address operands.
2023-01-05 09:56:11 +01:00
Erik Eckstein
e26affacbd ComputeSideEffects: correct side effects for destroy_addr
A destroy_addr also involves a read from the address. It's equivalent to a `%x = load [take]` and `destroy_value %x`.
It's also a write, because the stored value is not available anymore after the destroy.

Fixes a compiler crash in SILMem2Reg.

rdar://103879105
2023-01-05 09:56:11 +01:00
Anton Korobeynikov
dd6f468d09 Ensure that partial_apply of partial_apply does not produce conservative global side effects. (#62351)
Fixes #62249
2022-12-02 06:14:46 -08:00
Erik Eckstein
82107c5bf2 ComputeSideEffects: consider effects in dead-end blocks
It was a wrong assumption that we can ignore effects in dead-end blocks.
2022-11-09 08:06:19 +01:00
Erik Eckstein
ab2fe452f9 ComputeSideEffects: checking for unknown argument uses need to consider type which contain raw pointers 2022-11-09 08:06:19 +01:00
Erik Eckstein
dbb4d4db32 ComputeSideEffects: fix a typo in a comment 2022-11-09 08:06:19 +01:00
Erik Eckstein
b275d987b5 ComputeSideEffects: handle reference count reading instructions.
Conservatively model those effects as "destroy" effects.
2022-10-20 09:20:28 +02:00
Erik Eckstein
8961e2982e swift side effects: some additions and refactoring
add `Function.getSideEffects(forArgument:,atIndex:,withConvention:)`
2022-10-20 09:20:28 +02:00
Erik Eckstein
60609eb809 Swift SIL: invert Type.isNonTrivialOrContainsRawPointer to Type.isTrivialNonPointer
This is consistent with `Type.isTrivial`.
Also, introduce corresponding properties in `Value`: `hasTrivialType` and `hasTrivialNonPointerType`, because
1. It's less to type than `Type.isTrivial(in: function)` because `Value` knows in which function it is.
2. It fixes the corner case where value is an `Undef`, which has not parent function.
2022-10-20 09:20:28 +02:00
Erik Eckstein
0a2d233d1e compute effects: Don't modify the effects if they didn't change
This avoids sending a change notification which can trigger unnecessary other invalidations.
2022-10-20 09:20:28 +02:00
Nate Chandler
4476088ab5 [ComputeSideEffects] Track deinit-barrier-ness.
Functions "are deinit barriers" (more pedantically, applies of functions
are deinit barriers) if any of their instructions are deinit barriers.
During side-effect analysis, when walking a function's instructions for
other global effects, also check for the deinit-barrier effect.  If an
instruction is found to be a deinit barrier, mark the function's global
effects accordingly.

Add SILFunction::isDeinitBarrier to conveniently access the effects
computed during ComputeSideEffects.

Update the isBarrierApply predicate to iterate over the list of callees,
if complete, to check whether any is a deinit barrier.  If none is, then
the apply is not a deinit barrier.
2022-10-18 21:23:22 -07:00
Erik Eckstein
741c6c38df Swift Optimizer: add the ComputeSideEffects pass.
Computes the side effects for a function, which consists of argument- and global effects.
This is similar to the ComputeEscapeEffects pass, just for side-effects.
2022-10-05 07:38:11 +02:00
Erik Eckstein
e1c65bd1d6 Swift Optimizer: rename the ComputeEffects pass to ComputeEscapeEffects 2022-10-05 07:38:11 +02:00
Erik Eckstein
66f07fe3da Swift SIL: rework function effects and add function side-effects
So far, function effects only included escape effects.
This change adds side-effects (but they are not computed, yet).
It also involves refactoring of the existing escape effects.
Also the SIL effect syntax changed a bit. Details are in docs/SIL.rst
2022-10-05 07:38:11 +02:00
Erik Eckstein
53363c7c3b WalkUtils: add UnusedWalkingPath
Which is a walking path which matches everything.

Useful for walkers which don't care about the path and unconditionally walk to all defs/uses.
2022-10-05 07:37:41 +02:00
Erik Eckstein
9889f165ea EscapeUtils: another small refactoring of the isEscape functions
Instead of the `startWalkingDown` arguments, add separate `isEscapingWhenWalkingDown`/`visitByWalkingDown` functions
2022-09-19 16:48:10 +02:00
Erik Eckstein
a8b58735fc Swift Optimizer: improve ergonomics of EscapeUtils
Replace the `struct EscapeInfo` with a simpler API, just consisting of methods of `ProjectedValue` and `Value`:
* `isEscaping()`
* `isAddressEscaping()`
* `visit()`
* `visitAddress()`
2022-09-19 14:39:10 +02:00
Erik Eckstein
4554939dc4 SwiftCompilerSources: consistently use assert instead of precondition
It's better to use the new assert implementation (defined in the "Basic" module) than Swift's `precondition`
2022-09-14 14:16:26 +02:00
Erik Eckstein
984ae9e4f1 Define our own assert implementation for the swift compiler sources
For two reasons:
* We also like to check for assert failures in release builds. Although this could be achieved with `precondition`, it's easy to forget about it and use `assert` instead.
* We need to see the error message in crashlogs of release builds. This is even not the case for `precondition`.

Also, re-export the "Basic" module in "SIL" so that the new assert implementation is also available in the Optimizer module (where all files import SIL).
2022-09-14 14:16:26 +02:00
Erik Eckstein
024ec094d1 Swift SIL: simplify the representation of argument effects
Just refactoring, it's a NFC.
2022-09-09 21:50:10 +02:00
Erik Eckstein
2fe1ee5533 Swift SIL: add a few Builder functions
* add `createAllocStack`
* add `createDeallocStack`
* add `createCopyAddr`
* add `@discardableResult` to the existing `createDeallocStackRef`
2022-08-24 17:55:02 +02:00
Erik Eckstein
c2ef10661a Swift Optimizer: move function passes which are only used for unit testing to their own TestPasses directory. 2022-08-24 17:54:46 +02:00
Erik Eckstein
3bba7caacc Swift SIL: add var Function.instructions
To be used to iterate over all instructions in a function without the need of two loops - one for blocks and one for instructions.
2022-08-24 17:54:46 +02:00
Erik Eckstein
20a8f450dd Swift AccessUtils: improvements and bug fixes
While I was using the new AccessUtils for a new optimization pass I discovered some areas for improvements. Also I found some bugs.

Changes:

* AccessBase: remove the unhealthy redundancy between `kind` and `baseAddress` types. Now AccessBase is single enum with the relevant base objects/addresses as payloads.

* AccessBase: for `global`, store the `GlobalValue` and not a `global_address` instruction, which is more accurate (because there can be multiple `global_addr`s for a single global variable)

* AccessBase: drop the support for function argument "pointers". The `pointer` is now always a `pointer_to_address` instruction. This also simplifies `PointerIdentification`: either it finds a matching `address_to_pointer` or it bails.

* AccessBase: improve `func isDistinct(from:)`. There are more possibilities to prove that two access bases do not alias.

* AccessBase: replace `var isUniquelyIdentified` with `var hasKnownStorageKind` which is more useful for aliasing checking.

* AccessPath: fix `func isDistinct(from:)`. `SmallProjectionPath.matches` is the wrong way to check if two expression paths may overlap. Instead use the new `SmallProjectionPath.mayOverlap`.

* AccessStoragePathWalker: rename `getAccessStorage` -> `visitAccessStorageRoots` and let it return false if it's not a class/reference AccessBase.

* add tests for `AccessPath.isDistinct(from:)`
2022-08-22 13:22:14 +02:00
Anxhelo Xhebraj
7a20bc3ea6 Swift Optimizer: add AccessUtils
This set of utilities introduce concepts such as `AccessBase`,
`AccessPath` and `AccessStoragePath` useful to analyze memory accesses.
2022-08-12 09:42:13 -07:00
Erik Eckstein
872ded9341 ReleaseDevirtualizer: use the ValueUseDefWalker instead of the manual use-def walking implementation 2022-07-20 13:50:18 +02:00
Erik Eckstein
b52297bb79 Swift SIL: some improvements for WalkUtils and EscapeInfo
* "merge" the `Path` and `State` in WalkUtils into a single `WalkingPath`. This makes it simpler for clients to configure a path and additional state variables. EscapeInfo now defines `EscapePath` which includes the projection path and EscapeInfo's specific state variables.
* Make the `WalkerCache` part of the WalkUtils, so that not all clients have to re-implement it.
* Rename `walkDownResults` -> `walkDownAllResults` and `walkUpOperands` -> `walkUpAllOperands` and make these functions client configurable.
2022-07-20 13:50:18 +02:00
Anxhelo Xhebraj
c3ccbde52b Swift Optimizer: update EscapeInfo to use the generic walker utilities
`EscapeInfo` now conforms to the generic protocols defined in `WalkUtils`.
This simplifies the implementation a bit, since trivial instructions are handled
by `WalkUtils` and `EscapeInfo` only has to handle a subset of instructions
inherent to escape information.
Passes using `EscapeInfo` are updated accordingly to become visitors that
customize the `EscapeInfo` walk.
2022-07-05 11:28:49 -07:00
Erik Eckstein
ec3d9dd9c7 Optimizer: add the ObjCBridgingOptimization to optimize ObjectiveC bridging operations.
Removes redundant ObjectiveC <-> Swift bridging calls.
Basically, if a value is bridged from ObjectiveC to Swift an then back to ObjectiveC again, then just re-use the original ObjectiveC value.

Also in this commit: add an additional DCE pass before ownership elimination. It can cleanup dead code which is left behind by the ObjCBridgingOptimization.

rdar://89987440
2022-06-08 22:51:57 +02:00
Erik Eckstein
ad9dafc9bf Swift SIL: add Value.definingBlock
and re-factor `Value.definingInstruction`
2022-05-12 21:48:37 +02:00
Erik Eckstein
3b43da9637 Swift Optimizer: improve ergonomics of Builder and PassContext
* split the PassUtils.swift file into PassContext.swift and Passes.swift
* rework `Builder` bridging allowing more insertion point variations, e.g. inserting at the end of a block.
* add Builder.create functions for more instructions
* add `PassContext.splitBlock`
* move SIL modification functions from PassContext to extensions of the relevant types (e.g. instructions).
* rename `Location.bridgedLocation` -> `Location.bridged`
2022-05-12 21:48:37 +02:00