Commit Graph

62 Commits

Author SHA1 Message Date
Erik Eckstein
7eb123ff29 Swift SIL: Fix argument conventions for functions which have both, a direct and indirect result.
The function convention for the first argument is not identified as indirect-out.
This lets alias analysis assume that the memory pointed to by argument 0 cannot be written by the called function.

The problem is that subscripting a LazyFilterCollection (with the base index, e.g. `Int`) does not work as expected, because it returns the nth element of the base collection!
The fix is to implement the subscript "manually".

Fixes a mis-compile.
rdar://152160748
2025-05-30 12:40:44 +02:00
Erik Eckstein
30e138c48b SIL: define mark_dependence_addr to read and write to its address operand
This prevents simplification and SILCombine passes to remove (alive) `mark_dependence_addr`.
The instruction is conceptually equivalent to
```
  %v = load %addr
  %d = mark_dependence %v on %base
  store %d to %addr
```

Therefore the address operand has to be defined as writing to the address.
2025-05-23 07:53:14 +02:00
Andrew Trick
97b249bd11 Merge pull request #80263 from atrick/markdep-addr
SIL: add mark_dependence_addr
2025-03-26 10:33:42 -07:00
Andrew Trick
d9dd93560d Support mark_dependence_addr in SIL passes. 2025-03-25 23:02:45 -07:00
John McCall
3fe70968cc Remove the substitution map from zeroInitializer builtin in SIL.
This is a value operation that can work just fine on lowered types,
so there's no need to carry along a formal type. Make the value/address
duality clearer, and enforce it in the verifier.
2025-03-26 00:34:15 -04:00
Erik Eckstein
be73bd552e AliasAnalysis: fix effect of end/abort_apply for read-only coroutines
The lifetime of yielded values always end at the end_apply.
This is required because a yielded address is non-aliasing inside the begin/end_apply scope, but might be aliasing after the end_apply.
For example, if the callee yields an `ref_element_addr` (which is encapsulated in a begin/end_access).
Therefore, even if the callee does not write anything, the effects must be "read" and "write".

Fixes a SIL verifier error
rdar://147601749
2025-03-24 10:51:53 +01: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
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
Erik Eckstein
53bb72c3e4 EscapeUtils: don't follow the result of a partial_apply for not captured address operands.
A partial_apply copies the values from indirect-in arguments, but does not capture the address.
2024-11-27 12:16:43 +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
def3b6fab0 AccessUtils: recognize addressor calls of globals as a "global" access base
Makes e.g. alias analysis more precise in the early stage of the pass pipeline where addressor calls are not inlined, yet.
2024-08-05 17:12:46 +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
Erik Eckstein
8cb2caa5ab tests: remove unneeded SIL comments and fix check-lines in alias-analysis tests
*) remove `// users: ...` comments
*) replace some `CHECK:` with `CHECK-NEXT:` lines. Otherwise the test could pass although the result is wrong
2024-07-29 17:33:45 +02:00
Erik Eckstein
da5857d5ec EscapeInfo: improve handling of begin_applys which yield an address value
Instead of just aborting if a `begin_apply` gets an address argument, follow the yielded values and see if they actually escape
2024-07-29 17:33:44 +02:00
Erik Eckstein
0f359ff6f8 SideEffects: fix effects of indirect-in apply arguments
Indirect-in arguments are consumed by the caller and that not only counts as read but also as a write.
2024-07-29 17:33:43 +02:00
Anton Korobeynikov
d84847ac9d Reland Allow normal function results of @yield_once coroutines (#71645)
* Allow normal function results of @yield_once coroutines

* Address review comments

* Workaround LLVM coroutine codegen problem: it assumes that unwind path never returns.
This is not true to Swift coroutines as unwind path should end with error result.
2024-03-27 13:09:02 -07:00
Alejandro Alonso
254e4f041f Handle atomic instructions in escape analysis
Split atomic loads/stores

no more guard

invert condition
2024-03-05 08:32:51 -08:00
Erik Eckstein
abd6ce0c9d EscapeUtils: fix escape result in case an address is stored
This unusual situation can happen if an address is converted to a raw pointer and that pointer is stored to a memory location.
In this case the walkers need to follow load instructions even if the visitor and current projection path don't say so.

Fixes a miscompile
rdar://122805546
2024-02-12 17:56:09 +01:00
Nate Cook
e317febc9d Revert "Allow normal function results of @yield_once coroutines (#69843)"
This reverts commit aa5b505014.
2024-02-07 14:57:31 -06:00
Anton Korobeynikov
aa5b505014 Allow normal function results of @yield_once coroutines (#69843)
This adds SIL-level support and LLVM codegen for normal results of a coroutine.

The main user of this will be autodiff as VJP of a coroutine must be a coroutine itself (in order to produce the yielded result) and return a pullback closure as a normal result.

For now only direct results are supported, but this seems to be enough for autodiff purposes.
2024-02-06 22:13:15 -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
Erik Eckstein
8571ea0554 tests: add a test in mem-behavior.sil for global let variables 2023-09-19 15:10:30 +02:00
Erik Eckstein
40d41d4d82 MemoryBehavior: be more accurate with destructor side effects of a store [assign]
So far we unconditionally treated `store [assign]` to have side effects because it destructs the old value.
But we can do better by checking if the address in question actually can escape to a destructor.
2023-07-21 07:19:12 +02:00
Erik Eckstein
f96c13e925 MemBehavior: correctly handle debug_value
debug_value just "reads" the operand if it is an address.
2023-07-05 21:33:25 +02:00
Erik Eckstein
fa1ecff143 Swift Optimizer: rewrite the MemBehaviorDumper test pass in swift. 2023-05-09 08:25:09 +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
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
beb46eb624 Use the new escape and side effects in alias analysis 2022-12-21 17:41:46 +01:00
Nate Chandler
ed623d7b64 [NFC] Shortened SIL [init] flag.
Instead of writing out [initalization] for some instructions, use [init]
everywhere.
2022-10-27 10:38:54 -07:00
Josh Soref
730b16c569 Spelling siloptimizer
* access
* accessed
* accesses
* accessor
* acquiring
* across
* activated
* additive
* address
* addresses'
* aggregated
* analysis
* and
* appropriately
* archetype
* argument
* associated
* availability
* barriers
* because
* been
* beginning
* belongs
* beneficial
* blocks
* borrow
* builtin
* cannot
* canonical
* canonicalize
* clazz
* cleanup
* coalesceable
* coalesced
* comparisons
* completely
* component
* computed
* concrete
* conjunction
* conservatively
* constituent
* construct
* consuming
* containing
* covered
* creates
* critical
* dataflow
* declaration
* defined
* defining
* definition
* deinitialization
* deliberately
* dependencies
* dependent
* deserialized
* destroy
* deterministic
* deterministically
* devirtualizes
* diagnostic
* diagnostics
* differentiation
* disable
* discipline
* dominate
* dominates
* don't
* element
* eliminate
* eliminating
* elimination
* embedded
* encounter
* epilogue
* epsilon
* escape
* escaping
* essential
* evaluating
* evaluation
* evaluator
* executing
* existential
* existentials
* explicit
* expression
* extended
* extension
* extract
* for
* from
* function
* generic
* guarantee
* guaranteed
* happened
* heuristic
* however
* identifiable
* immediately
* implementation
* improper
* include
* infinite
* initialize
* initialized
* initializer
* inside
* instruction
* interference
* interferes
* interleaved
* internal
* intersection
* intractable
* intrinsic
* invalidates
* irreducible
* irrelevant
* language
* lifetime
* literal
* looks
* materialize
* meaning
* mergeable
* might
* mimics
* modification
* modifies
* multiple
* mutating
* necessarily
* necessary
* needsmultiplecopies
* nonetheless
* nothing
* occurred
* occurs
* optimization
* optimizing
* original
* outside
* overflow
* overlapping
* overridden
* owned
* ownership
* parallel
* parameter
* paths
* patterns
* pipeline
* plottable
* possible
* potentially
* practically
* preamble
* precede
* preceding
* predecessor
* preferable
* preparation
* probably
* projection
* properties
* property
* protocol
* reabstraction
* reachable
* recognized
* recursive
* recursively
* redundant
* reentrancy
* referenced
* registry
* reinitialization
* reload
* represent
* requires
* response
* responsible
* retrieving
* returned
* returning
* returns
* rewriting
* rewritten
* sample
* scenarios
* scope
* should
* sideeffects
* similar
* simplify
* simplifycfg
* somewhat
* spaghetti
* specialization
* specializations
* specialized
* specially
* statistically
* substitute
* substitution
* succeeds
* successful
* successfully
* successor
* superfluous
* surprisingly
* suspension
* swift
* targeted
* that
* that our
* the
* therefore
* this
* those
* threshold
* through
* transform
* transformation
* truncated
* ultimate
* unchecked
* uninitialized
* unlikely
* unmanaged
* unoptimized key
* updataflow
* usefulness
* utilities
* villain
* whenever
* writes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-10-03 18:31:33 -04:00
Holly Borla
8713d78704 [PrintOptions] Print explicit 'any' in SIL. 2022-08-18 01:15:12 -04:00
Erik Eckstein
e2970155e8 MemAccessUtils: handle the case of enum with no operand in findOwnershipReferenceAggregate
This fixes a crash when trying to compute the immutable scope of an address which comes from an `Optional.none`.

rdar://90119694
2022-03-31 09:53:50 +02:00
Erik Eckstein
2d1045f7bc MemBehavior: handle guaranteed arguments in non-OSSA mode.
In non-OSSA, this is the only case for which we know that if an instruction is within a "borrow-scope".
2021-11-29 09:41:05 +01:00
Erik Eckstein
3701de4731 AliasAnalysis: check for immutable scopes.
If the "regular" alias analysis thinks that an instruction may write to an address, check if the instruction is in an immutable scope of V.
That means that even if we don't know anything about the instruction (e.g. a call to an unknown function), we can be sure that it cannot write to the address.

An immutable scope is for example a read-only begin_access/end_access scope.
Another example is a borrow scope of an immutable copy-on-write buffer, for example:
   %b = begin_borrow %array_buffer
   %addr = ref_element_addr [immutable] %b : $BufferType, #BufferType.someField
2021-05-18 10:14:44 +02:00
Erik Eckstein
67ce72cebb MemBehavior: fix minor bugs for `begin_access and end_access`.
* ``begin_access [modify]`` returned MayWrite, but "modify" means, it can be a read as well.
Instead, return MayReadWrite. Only for ``begin_access [init]`` return MayWrite.
This is more or less cosmetic - probably this bug had no real impact on any optimization.

* ``begin_access [deinit]`` needs to return MayReadWrite for the same reason ``destroy_addr`` returns MayReadWrite (see SILInstruction::MemoryBehavior).
2021-03-24 12:16:07 +01:00
Erik Eckstein
8828d8e6bf tests: clean-up MemBehavior tests
Add more relevant instructions to dump in MemBehaviorDumper.
Therefore the -enable-mem-behavior-dump-all option can be removed.
Also mem-behavior-all.sil into mem-behavior.sil, because the sil-opt command lines don't differ anymore.
2021-03-24 11:19:00 +01:00
Erik Eckstein
007351223e MemBehavior: handle begin_access when checking for apply side-effects. 2020-10-16 16:32:48 +02:00
Erik Eckstein
b0c9e69b6f SideEffectAnalysis: don't assume that arguments with trivial type cannot be pointers.
Even values of trivial type can contain a Builtin.RawPointer, which can be used to read/write from/to.

To compensate for the removed check, enable the escape-analysis check in MemBehavior (as it was before).

This fixes a recently introduced miscompile.
rdar://problem/70220876
2020-10-13 11:32:47 +02:00
Erik Eckstein
d4a6bd39b6 SILOptimizer: improve MemBehavior for apply instructions.
1. Do a better alias analysis for "function-local" objects, like alloc_stack and inout parameters
2. Fully support try_apply and begin/end/abort_apply

So far we fully relied on escape analysis. But escape analysis has some shortcomings with SIL address-types.
Therefore, handle two common cases, alloc_stack and inout parameters, with alias analysis.
This gives better results.
The biggest change here is to do a quick check if the address escapes via an address_to_pointer instructions.
2020-10-09 20:54:58 +02:00
Erik Eckstein
aced5c74df SILOptimizer: Remove InspectionMode from MemBehehaviorVisitor
The InspectionMode was never set to anything else than "IgnoreRetains"
2020-10-09 20:54:58 +02:00
Michael Gottesman
fd4828e40a Eliminate -assume-parsing-unqualified-ownership-sil from tests.
I am doing this separately from the actual change to eliminate the option to
make it easier to review.
2018-12-19 12:54:13 -08:00
Harlan Haskins
66a61c5eca Rename @sil_stored to @_hasStorage 2018-11-12 11:32:32 -08:00
Johannes Weiß
c7990f2abd redundant load elimination for @in_guaranteed-only funcs 2017-07-24 18:22:50 +01:00
Arnold Schwaighofer
b8a3c162e9 Change a cl::opt that conflicts once we link llvm passes and sil passes 2016-12-20 07:24:02 -08:00
Michael Gottesman
20dd563efb [semantic-arc] Update tests for qualified/unqualified ownership and SILGen emission of copy_value, destroy_value. 2016-10-29 20:11:09 -07:00
Dmitri Gribenko
d175b3b66d Migrate FileCheck to %FileCheck in tests 2016-08-10 23:52:02 -07:00
Michael Gottesman
4e530dd5f0 [sil-printer] Only sort the PredIds, UserIDs that we put in comments if we are supposed to emit sorted SIL.
This was done some time ago to make it easier to diff large amounts of SIL
output. The problem is that it makes it difficult to know the *true* memory
order that the predecessor list is in which can lead to surprise when working
with SIL and create test cases.

I believe some time after that point we added the notion of "sorted" sil, i.e.
SIL that does not guarantee any relation to the actual memory representation of
the SIL and is meant to ease diffing. This fits nicely with the true intention
of this sort of sorting.

Thus this commit puts sorting PredIDs, UserIDs behind that flag.
2016-07-17 15:39:53 -07:00