Commit Graph

46 Commits

Author SHA1 Message Date
Erik Eckstein
97db5d8a80 AliasAnalysis: handle global let-variables in ImmutableScope
Global let-variables are immutable, except in functions which initialize them.
This brings back handling of global let-variables in alias analysis, which was removed in the previous commit.
2025-01-20 08:50:56 +01:00
Erik Eckstein
a312732f84 AliasAnalysis: consider memory effects of a consume/destroy of a class on it's let-fields
Although a let-field can never be mutated, a release or consume of the class must be considered as writing to such a field.

This change removes the special handling of let-fields in two places, where they don't belong.
Class fields are handled by ImmutableScope anyway.
Handling of global let-variable is temporarily removed by this commit.

Fixes a miscompile.
rdar://142996449
2025-01-20 08:50:56 +01: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
c5b14c2b93 BorrowUtils: make unchecked_ownership_conversion to guaranteed ownership a BeginBorrowValue
BeginBorrowValue needs to handle all cases where a guaranteed value is produced.
Fixes a compiler crash.
2024-12-21 08:28:21 +01:00
eeckstein
ca50c55eb5 Merge pull request #77806 from eeckstein/rle-of-array-elements
Optimizer: remove the ArrayElementPropagation optimization
2024-12-02 07:13:08 +01:00
Erik Eckstein
e3df3da8a9 AliasAnalysis: fix the complexity limit for ARCSequenceOpts
The comment already says that we need a lower complexity limit for ARCSequenceOpts, but the actual budget was not set correctly to a lower limit.
2024-11-28 10:35:39 +01:00
Erik Eckstein
b98608dfbe AliasAnalysis: fix memory-behavior of closures with inout arguments
Calls of such closures were not considered to read or modify the inout argument.

Fixes a miscompile.
rdar://140338313
2024-11-27 12:16:43 +01:00
Erik Eckstein
75e75831f2 AliasAnalysis: fix the memory behavior of end_borrow
Checking if an access base is derived from a begin-borrow was too optimistic.
We have to bail for instructions which are not handled by the walker utilities.

Fixes a verifier crash.
rdar://139788357
2024-11-13 17:44:01 +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
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
8f839f0eab AliasAnalysis: use AccessBase.isLet instead of duplicating the code
A small refactoring. NFC
2024-08-05 17:02:07 +02:00
Erik Eckstein
345f9c1dfc AliasAnalysis: handle destroy_value [dead_end] in computeMemoryEffect
We don't have to take deinit effects into acount for a `destroy_value [dead_end]`.
Such destroys are lowered to no-ops and will not call any deinit.
2024-08-05 17:02:06 +02:00
Erik Eckstein
f9b524b1cb AliasAnalysis: a complete overhaul of alias- and memory-behavior analysis
The main changes are:

*) Rewrite everything in swift. So far, parts of memory-behavior analysis were already implemented in swift. Now everything is done in swift and lives in `AliasAnalysis.swift`. This is a big code simplification.

*) Support many more instructions in the memory-behavior analysis - especially OSSA instructions, like `begin_borrow`, `end_borrow`, `store_borrow`, `load_borrow`. The computation of end_borrow effects is now much more precise. Also, partial_apply is now handled more precisely.

*) Simplify and reduce type-based alias analysis (TBAA). The complexity of the old TBAA comes from old days where the language and SIL didn't have strict aliasing and exclusivity rules (e.g. for inout arguments). Now TBAA is only needed for code using unsafe pointers. The new TBAA handles this - and not more. Note that TBAA for classes is already done in `AccessBase.isDistinct`.

*) Handle aliasing in `begin_access [modify]` scopes. We already supported truly immutable scopes like `begin_access [read]` or `ref_element_addr [immutable]`. For `begin_access [modify]` we know that there are no other reads or writes to the access-address within the scope.

*) Don't cache memory-behavior results. It turned out that the hit-miss rate was pretty bad (~ 1:7). The overhead of the cache lookup took as long as recomputing the memory behavior.
2024-07-29 17:33:46 +02:00
cui fliter
127077b3aa chore: fix some comments
Signed-off-by: cui fliter <imcusg@gmail.com>
2024-03-05 17:23:22 +08:00
Nate Chandler
75ccbaed04 [AliasAnalysis] Builtin effects depend on escaping
Mostly restore the behavior of getMemoryEffectsFn on builtins other than
`once` and `onceWithContext` to before
8a8a895239 but keeping the improvement to
return `Instruction.memoryEffects` in the face of escaping.
2024-01-19 07:16:52 -08:00
nate-chandler
7365f9f36b Merge pull request #70774 from nate-chandler/nfc/20240108/1/deinit-barrier-component-predicates
[NFC] SIL: Clarified deinit barrier APIs.
2024-01-08 23:11:38 -08:00
Nate Chandler
82b7495bb1 [NFC] SIL: Clarified deinit barrier APIs.
An instruction is a deinit barrier whenever one of three component
predicates is true for it.  In the case of applies, it is true whenever
one of those three predicates is true for any of the instructions in any
of its callees; that fact is cached in the side-effect analysis of every
function.

If side-effect analysis or callee analysis is unavailable, in order to
define each of those three component predicates on a
`FullApplySite`/`EndApplyInst`/`AbortApplyInst`, it would be necessary
to define them to conservatively return true: it isn't known whether any
of the instructions in any of the callees were deinit barriers.

Refactored the two versions of the deinit barrier predicate (namely
`Instruction.isDeinitBarrier(_:) and
`swift::mayBeDeinitBarrierNotConsideringSideEffects`) to handle
`FullApplySite`/`EndApplyInst`/`AbortApplyInst`s specially first (to
look up the callees' side-effect and to conservatively bail,
respectively).  Asserted that the three component predicates are not
called with `FullApplySite`/`EndApplyInst`/`AbortApplyInst`s.  Callers
should instead use the `isDeinitBarrier` APIs.

An alternative would be to conservatively return true from the three
components.  That seems more likely to result in direct calls to these
member predicates, however, and at the moment at least there is no
reason for such calls to exist.  If some other caller besides the
deinit-barrier predicates needs to call this function, side-effect
analysis should be updated to cache these three properties separately at
that point.
2024-01-08 15:25:24 -08:00
Nate Chandler
77fd37be99 [NFC] SIL: Renamed maySynchronize.
Dropped the NotConsideringSideEffects suffix.
2024-01-08 13:35:20 -08:00
Andrew Trick
2128c21106 Migrate SwiftCompilerSources to FunctionConvention.
Layers:
- FunctionConvention: AST FunctionType: results, parameters
- ArgumentConventions: SIL function arguments
- ApplyOperandConventions: applied operands

The meaning of an integer index is determined by the collection
type. All the mapping between the various indices (results,
parameters, SIL argument, applied arguments) is restricted to the
collection type that owns that mapping. Remove the concept of a
"caller argument index".
2024-01-03 12:24:50 -08:00
Erik Eckstein
2dbd6cc56b SwiftCompilerSources: rework bridging
Introduce two modes of bridging:
* inline mode: this is basically how it worked so far. Using full C++ interop which allows bridging functions to be inlined.
* pure mode: bridging functions are not inlined but compiled in a cpp file. This allows to reduce the C++ interop requirements to a minimum. No std/llvm/swift headers are imported.

This change requires a major refactoring of bridging sources. The implementation of bridging functions go to two separate files: SILBridgingImpl.h and OptimizerBridgingImpl.h.
Depending on the mode, those files are either included in the corresponding header files (inline mode), or included in the c++ file (pure mode).

The mode can be selected with the BRIDGING_MODE cmake variable. By default it is set to the inline mode (= existing behavior). The pure mode is only selected in certain configurations to work around C++ interop issues:
* In debug builds, to workaround a problem with LLDB's `po` command (rdar://115770255).
* On windows to workaround a build problem.
2023-10-09 09:52:52 +02:00
Erik Eckstein
f6f9e75173 AliasAnalysis: use a complexity limit for the isObjReleased function
We already use a complexity limit for other functions in AliasAnalysis.
This is a workaround for quadratic complexity in ARCSequenceOpts.

Fixes a compile time problem
rdar://114352817
2023-09-04 19:52:57 +02:00
Erik Eckstein
29246fd80b AliasAnalysis: add complexity budget for the getMemEffectsFunction 2023-07-21 07:19:56 +02:00
Erik Eckstein
b03ef3cc80 AliasAnalysis: rename the main API functions
Instead of
  aliasAnalysis.mayRead(inst: i, fromAddress: a)
it's more natural to write
  i.mayRead(fromAddress: a, aliasAnalysis)
2023-07-05 21:33:24 +02:00
Erik Eckstein
8a8a895239 alias analysis: compute more precise memory effects of builtin "once"
* Check if the address in question is even visible from outside the function
* Return the memory effects of the called function

Also, add a new API `Instruction.memoryEffects`, which is internally used by `mayReadFromMemory` et al.
2023-05-08 21:23:36 +02:00
Erik Eckstein
da3f126322 CalleeAnalysis: no need to provide the PassManager to the getMemBehaviorFn
A NFC simplification
2023-05-03 14:33:45 +02:00
Erik Eckstein
010efc1ca6 Swift Bridging: use C++ instead of C bridging for the optimizer 2023-03-21 15:33:09 +01:00
Erik Eckstein
7789b4063e Swift Bridging: remove BridgedMemoryBehavior and use swift.MemoryBehavior instead 2023-03-21 15:33:09 +01:00
Erik Eckstein
2d88482c9f EscapeUtils: add a computational limit to avoid quadratic complexity in some corner cases.
The `isEscaping` function is called a lot from ARCSequenceOpt and ReleaseHoisting.
To avoid quadratic complexity for large functions, limit the amount of work what the EscapeUtils are allowed to to.
This keeps the complexity linear.

The arbitrary limit is good enough for almost all functions.
It lets the EscapeUtils do several hundred up/down walks which is much more than needed in most cases.

Fixes a compiler hang
https://github.com/apple/swift/issues/63846
rdar://105795976
2023-02-24 18:58:01 +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
beb46eb624 Use the new escape and side effects in alias analysis 2022-12-21 17:41:46 +01:00
Erik Eckstein
7db7065740 swift side effects: add CalleeAnalysis.getSideEffects(of: apply) 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
Nate Chandler
7ea336367d [NFC] Port isDeinitBarrier to Swift.
Added new C++-to-Swift callback for isDeinitBarrier.

And pass it CalleeAnalysis so it can depend on function effects.  For
now, the argument is ignored.  And, all callers just pass nullptr.

Promoted to API the mayAccessPointer component predicate of
isDeinitBarrier which needs to remain in C++.  That predicate will also
depends on function effects.  For that reason, it too is now passed a
BasicCalleeAnalysis and is moved into SILOptimizer.

Also, added more conservative versions of isDeinitBarrier and
maySynchronize which will never consider side-effects.
2022-10-18 21:23:22 -07: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
87ae9e3a73 add passes to dump the results of EscapeInfo
And add test files which uses the passes for verification of EscapeInfo
2022-04-22 09:50:07 +02:00
Saleem Abdulrasool
218ef587e6 Revert "Merge pull request #42242 from eeckstein/escapeinfo"
This reverts commit c05e064cd8, reversing
changes made to c1534d5af9.

This caused a regression on Windows.
2022-04-21 20:33:37 -07:00
Erik Eckstein
4d5987c469 add passes to dump the results of EscapeInfo
And add test files which uses the passes for verification of EscapeInfo
2022-04-21 08:45:08 +02:00
Erik Eckstein
d8bf949582 BasicCalleeAnalysis: improve finding the actual called deinits of a destroy/release instruction
* C++: add a function `getDestructors(SILType type, bool isExactType)’: if the type is a final class or `isExactType` is true, then return the one and only destructor of that class.
* swift: add `getDestructor(ofExactType type: Type)` and `getIncompleteCallees`
* swift: remove `getDestructor` from the PassContext. The API of the `calleeAnalysis` can be used instead.
2022-04-05 20:33:23 +02:00
Erik Eckstein
82ad1fa5a1 CalleeAnalysis: add getDestructors(destroyInst: Instruction) 2022-01-12 15:47:16 +01:00
Erik Eckstein
a24b17a333 Swift Optimizer: add the dominator and post-dominator tree analysis 2022-01-12 15:47:16 +01:00
Erik Eckstein
4440beb555 Swift Optimizer: add bridging to the DeadEndBlocksAnalysis 2022-01-12 15:47:16 +01:00
Erik Eckstein
345fcbe39a Improve collections in the swift SIL/Optimizer
Improve block/instruction lists and similar collections

* pretty print collections in the form “[a, b, c]”
* also do this for lazy sequences
* define a custom Mirror
* in a collection, only print the name of blocks, functions and globals (instead of the full object)
* replace `BasicBlock.reverseInstructions` with `BasicBlock.instructions.reversed()` - in an efficient way
2022-01-12 15:47:16 +01:00
Max Desiatov
e54524d7a5 Gardening: remove trailing whitespaces in libswift 2022-01-09 21:09:57 +00:00
Erik Eckstein
ba364a17ef libswift: rename cmake targets and functions
libswift -> swiftCompilerModules or swiftCompilerSources
2021-12-22 11:31:52 +01:00
Erik Eckstein
4beb94c2f9 Rename the libswift directory to SwiftCompilerSources 2021-12-22 09:46:25 +01:00