Commit Graph

22 Commits

Author SHA1 Message Date
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
Andrew Trick
a5d8aafb23 SwiftCompilerSources: Replace BlockArgument with Phi and TermResult.
All SILArgument types are "block arguments". There are three kinds:
1. Function arguments
2. Phis
3. Terminator results

In every situation where the source of the block argument matters, we
need to distinguish between these three. Accidentally failing to
handle one of the cases is an perpetual source of compiler
bugs. Attempting to handle both phis and terminator results uniformly
is *always* a bug, especially once OSSA has phi flags. Even when all
cases are handled correctly, the code that deals with data flow across
blocks is incomprehensible without giving each case a type. This
continues to be a massive waste of time literally every time I review
code that involves cross-block control flow.

Unfortunately, we don't have these C++ types yet (nothing big is
blocking that, it just wasn't done). That's manageable because we can
use wrapper types on the Swift side for now. Wrapper types don't
create any more complexity than protocols, but they do sacrifice some
usability in switch cases.

There is no reason for a BlockArgument type. First, a function
argument is a block argument just as much as any other. BlockArgument
provides no useful information beyond Argument. And it is nearly
always a mistake to care about whether a value is a function argument
and not care whether it is a phi or terminator result.
2023-09-27 18:47:46 -07:00
Kavon Farvardin
e6a8ec9d01 [SwiftCompilerSources] Handle .anyValueFields use-def walks through enums
The walker was not treating an EnumInst with zero payload, such as `Optional.none` as a root.
It seems the best way to fix that is to implement the handling of .anyValueFields for enums, as
they're documented in a comment to mean "follow anything", unlike .enumCase which expects
to find a specific case (though perhaps if it matches and there's no payload, it should still be a root?)
2023-09-21 12:20:24 -07:00
Erik Eckstein
0312804a4e WalkUtils: fix indentation 2023-09-19 15:10:30 +02:00
Erik Eckstein
88a7ee0cd9 WalkUtils: avoid dynamic protocol lookup when handling enum instructions
It's simpler and faster
2023-09-19 15:10:30 +02:00
Erik Eckstein
f0b811c45f SIL: add the end_init_let_ref instruction
This instructions marks the point where all let-fields of a class are initialized.
This is important to ensure the correctness of ``ref_element_addr [immutable]`` for let-fields,
because in the initializer of a class, its let-fields are not immutable, yet.
2023-09-19 15:10:30 +02:00
Erik Eckstein
e5eb15dcbe Swift SIL: replace the set_deallocating instruction with begin_dealloc_ref
Codegen is the same, but `begin_dealloc_ref` consumes the operand and produces a new SSA value.
This cleanly splits the liferange to the region before and within the destructor of a class.
2023-09-19 15:10:30 +02:00
Michael Gottesman
37d60a08bb [move-only] Rename mark_must_check -> mark_unresolved_non_copyable_value.
I was originally hoping to reuse mark_must_check for multiple types of checkers.
In practice, this is not what happened... so giving it a name specifically to do
with non copyable types makes more sense and makes the code clearer.

Just a pure rename.
2023-08-30 22:29:30 -07:00
Erik Eckstein
8bb3e45b41 WalkUtils: more precise handling of existential projections and index_addr 2023-07-05 21:33:24 +02:00
Erik Eckstein
78ce13dbd6 WalkUtils: Don't treat end_access as leaf-use in the AddressDefUseWalker
Instead just ignore it.
2023-05-08 21:23:36 +02: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
Nate Chandler
6caa5048d0 [WalkUtils] Walk through move_value instructions.
Addresses the following regressions

StackPromo                                10100   14400   +42.6%   **0.70x**

seen when enabling lexical lifetimes in the standard library.
2023-01-25 11:39:42 -08:00
Erik Eckstein
b5e731dde2 WalkUtils: fix a crash when visiting mismatching types
The path components may not be related to the current value in case mismatching types are visited, e.g. different concrete types of an existential.
This can lead to mismatching operand numbers for struct and tuple instructions.

rdar://104435056
2023-01-20 15:06:48 +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
99079ec673 ValueDefUseWalker: fix a problem with cond_br
Don't crash when visiting the cond_br condition operand.
2022-10-05 07:37:41 +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
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
e06d1c68a6 WalkUtils: add two inline elements into the WalkerCache to avoid memory allocations in the common case.
If there are no more than 2 elements in the cache, we can avoid using the `cache` Dictionary, which avoids memory allocations.
Fortunately this is the common case by far (about 97% of all walker invocations).
2022-09-19 11:30:35 +02:00
Michael Gottesman
03986db44f [mem-access] Teach mem-access about mark_must_check. 2022-09-07 18:20:33 -07:00
Anxhelo Xhebraj
b8b8f1ac88 Swift Optimizer: add SmallProjectionWalkingPaths in WalkUtils
- This protocol with its default implementations simplifies
  writing walkers, requiring only `merge` for conformance
2022-08-11 10:16:12 -07: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
50a7e25e31 Swift Optimizer: add projection path DefUse/UseDef walkers
Introduces a set of protocols useful to perform def-use and use-def
traversals to find uses and definitions of values.

This logic was originally baked into `EscapeInfo` directly.
Here we extract it into general utilities, namely:
- `ValueDefUseWalker`: visit uses of a value walking down value-value projections/constructions.
- `AddressDefUseWalker`: visit uses of an address walking down addr-addr projections/constructions.
- `ValueUseDefWalker`: visit definitions of a value walking up value-value projections/constructions.
- `AddressUseDefWalker`: visit definitions of an address walking up addr-addr projections/constructions.

These utilities can then be used in other passes or to create
new utilities by composing them. For example to find a definition
passing through both address projections and value extractions,
it's enough to implement a visitor conforming to both
`AddressUseDefWalker` and `ValueUseDefWalker`.
2022-07-05 11:26:13 -07:00