Commit Graph

47 Commits

Author SHA1 Message Date
Andrew Trick
e7000e4668 SIL: Add mark_dependence_addr 2025-03-25 23:02:42 -07:00
Erik Eckstein
e0b4f71af6 SIL: remove the alloc_vector instruction
It's not needed anymore, because the "FixedArray" experimental feature is replaced by inline-arrays.
2025-02-12 10:51:14 +01:00
Erik Eckstein
3ec5d7de24 SIL: replace the is_escaping_closure instruction with destroy_not_escaped_closure
The problem with `is_escaping_closure` was that it didn't consume its operand and therefore reference count checks were unreliable.
For example, copy-propagation could break it.
As this instruction was always used together with an immediately following `destroy_value` of the closure, it makes sense to combine both into a `destroy_not_escaped_closure`.
It
1. checks the reference count and returns true if it is 1
2. consumes and destroys the operand
2025-01-24 19:23:27 +01:00
Michael Gottesman
7ae56aab2e [sil] Add a new instruction ignored_use.
This is used for synthetic uses like _ = x that do not act as a true use but
instead only suppress unused variable warnings. This patch just adds the
instruction.

Eventually, we can use it to move the unused variable warning from Sema to SIL
slimmming the type checker down a little bit... but for now I am using it so
that other diagnostic passes can have a SIL instruction (with SIL location) so
that we can emit diagnostics on code like _ = x. Today we just do not emit
anything at all for that case so a diagnostic SIL pass would not see any
instruction that it could emit a diagnostic upon. In the next patch of this
series, I am going to add SILGen support to do that.
2025-01-22 21:12:36 -08:00
Hamish Knight
f728466273 [SwiftCompilerSources] Use interpolation instead of String(describing:)
`String(describing:)` does a bunch of dynamic casts
that can be pretty slow. Use interpolation instead,
which bypasses them.

For `swift-frontend`, this brings the time taken
for type-checking an empty file down from ~100ms
to ~70ms.

For `swift build`, this brings the time taken for
a null build down from ~600ms to ~450ms (the
larger delta is presumably due to the fact that
there's much more Swift code in `swift-package`).
2024-12-19 15:33:39 +00:00
Michael Gottesman
3c38c79f7a [region-isolation] Implement MergeIsolationRegionInst.
I am adding this instruction to express artificially that two non-Sendable
values should be part of the same region. It is meant to be used in cases where
due to unsafe code using Sendable, we stop propagating a non-Sendable dependency
that needs to be made in the same region of a use of said Sendable value. I
included an example in ./docs/SIL.rst of where this comes up with @out results
of continuations.
2024-11-01 11:25:53 -07:00
Michael Gottesman
561662d6cc [sil] Add a new instruction called ThunkInst.
For now this will only be used for HopToMainActorIfNeeded thunks. I am creating
this now since in the past there has only been one option for creating
thunks... to create the thunk in SILGen using SILGenThunk. This code is hard to
test and there is a lot of it. By using an instruction here we get a few benefits:

1. We decouple SILGen from needing to generate new kinds of thunks. This means
that SILGenThunk does not need to expand to handle more thunks.

2. All thunks implemented via ThunkInst will be easy to test in a decoupled way
with SIL tests.

3. Even though this stabilizes the patient, we still have many thunks in SILGen
and various parts of the compiler. Over time, we can swap to this model,
allowing us to hopefully eventually delete SILGenThunk.
2024-10-02 14:15:49 -07:00
Alejandro Alonso
75c2cbf593 Implement value generics
Some requirement machine work

Rename requirement to Value

Rename more things to Value

Fix integer checking for requirement

some docs and parser changes

Minor fixes
2024-09-04 15:13:25 -07:00
Nate Chandler
2a5d07522d [SIL] Add extend_lifetime instruction.
It indicates that the value's lifetime continues to at least this point.
The boundary formed by all consuming uses together with these
instructions will encompass all uses of the value.
2024-06-05 16:28:26 -07:00
Erik Eckstein
ac4bc89c9a SIL: add the borrowed-from instruction.
It declares from which enclosing values a guaranteed phi argument is borrowed from.
2024-04-10 13:38:10 +02:00
Erik Eckstein
68cc6c8780 SwiftCompilerSources: add all missing instruction classes
And require that all new instructions must be added and registered in SwiftCompilerSources as well.
2024-02-22 07:12:10 +01:00
Andrew Trick
1c8a150d95 SwiftCompilerSources: register the new instructions. 2024-01-30 08:38:57 -08:00
Erik Eckstein
e652f2c92e SIL: add the alloc_vector and vector instructions
* `alloc_vector`: allocates an uninitialized vector of elements on the stack or in a statically initialized global
* `vector`: creates an initialized vector in a statically initialized global
2023-12-09 18:49:55 +01:00
Erik Eckstein
e4d227a5fb SwiftCompilerSources: add StoreBorrowInst and BorrowIntroducingInstruction
`BorrowIntroducingInstruction` is a protocol to which all instructions conform which start a borrow-scope which must be ended by `EndBorrowInst` instructions: `begin_borrow`, `load_borrow` and `store_borrow`
2023-11-27 16:20:47 +01:00
Erik Eckstein
37c715c58c SwiftCompilerSources: add EndLifetimeInst 2023-11-27 09:21:33 +01:00
Slava Pestov
05ccd9734c SIL: Introduce ThrowAddrInst 2023-10-31 16:58:54 -04:00
Erik Eckstein
b6938475b9 Optimizer: add simplification for the convert_escape_to_noescape instruction
Including the required bridging stuff.

  %2 = thin_to_thick_function %1 to $() -> ()
  %3 = convert_escape_to_noescape %2 : $() -> () to $@noescape () -> ()
->
  %3 = thin_to_thick_function %1 to $@noescape () -> ()
2023-10-27 10:47:07 +02: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
Andrew Trick
bce9817162 SwiftCompilerSources: add ForwardingInstruction 2023-10-03 23:54:57 -07: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
b688a1f4a1 [SILOpt] experimental async demotion pass
For chains of async functions where suspensions can be statically
proven to never be required, this pass removes all suspensions and
turns the functions into synchronous functions.

For example, this function does not actually require any suspensions,
once the correct executor is acquired upon initial entry:

```
func fib(_ n: Int) async -> Int {
  if n <= 1 { return n }
  return await fib(n-1) + fib(n-2)
}
```

So we can turn the above into this for better performance:

```
func fib() async -> Int {
  return fib_sync()
}

func fib_sync(_ n: Int) -> Int {
  if n <= 1 { return n }
  return fib(n-1) + fib(n-2)
}
```

while rewriting callers of `fib` to use the `sync` entry-point
when we can prove that it will be invoked on a compatible executor.

This pass is currently experimental and under development. Thus, it
is disabled by default and you must use
`-enable-experimental-async-demotion` to try it.
2023-09-21 12:21:02 -07:00
Erik Eckstein
ad594f2713 Swift SIL: add some APIs
* `AssignInst`
* `Function.isDestructor`
* `MarkUninitializedInst.kind`
* `Type.isMoveOnly`
* `RefElementAddrInst.isImmutable` and `RefElementAddrInst.set(isImmutable:)`
* `BeginBorrowInst.endBorrows`
* `Context.hadError` and `Context.silStage`
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
5325a4fe21 Swift SIL: add some instruction classes and APIs
* add `UnownedRetainInst` and `UnownedReleaseInst`
* add `var value` to `RetainValueInst` and `ReleaseValueInst`
* make the protocol `UnaryInstruction` be an `Instruction`
* add `var Type.isValueTypeWithDeinit`
* add `var Type.isUnownedStorageType`
* add `var OperandArray.values`
2023-06-07 12:55:56 +02:00
Erik Eckstein
5c0ae940eb Optimizer: add simplification for the value_to_bridge_object instruction
This comes up in the code for constructing an empty string literal.
With this optimization it's possible to statically initialize empty string global variables.
2023-05-25 16:28:41 +02:00
Erik Eckstein
a4225a9088 Swift SIL: add a few SIL instructions and instruction APIs 2023-05-22 15:34:26 +02:00
Erik Eckstein
4dcd91af7b Swift SIL: add all deallocation instructions and let them conform to the Deallocation protocol 2023-05-11 08:03:19 +02:00
Erik Eckstein
e95c6425f2 Swift SIL: add some APIs for global variables 2023-05-08 21:23:36 +02:00
Erik Eckstein
7d70a70acf SIL: add the drop_deinit instruction
his instruction is a marker for a following destroy instruction to suppress the call of the move-only type's deinitializer.
2023-04-11 10:25:48 +02:00
Erik Eckstein
cef6ef9a84 SIL: add a debug_step instruction
This instruction can be inserted by Onone optimizations as a replacement for deleted instructions to
ensure that it's possible to single step on its location.
2023-02-09 06:50:05 +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
d2bdec9f59 Swift SIL: add MarkUninitializedInst and MetatypeInst instructions 2023-01-16 19:00:09 +01: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
Erik Eckstein
4a60ea809b Add some Swift SIL infrastructure
* In `ApplySite`: `argumentOperands` and `isCalleeOperand`
* In `ArgumentConvention`: `isIndirect`, `isIndirectIn` and `isGuaranteed`
* In `Function`: `isDefinition`, `numParameterArguments`, `numArguments`, `getArgumentConvention`, `effectAttribute`
* In `Type`: `isFunction` and `isCalleeConsumedFunction`
* In `Instruction`: `hasUnspecifiedSideEffects`
* New bridged instructions: `EndApplyInst` and `AbortApplyInst`
* `LoadInst.ownership`
* `BeginAccessInst.isStatic`
* make the `Allocation` protocol a `SingleValueInstruction` (instead of `AnyObject`)
2022-10-05 07:37:41 +02:00
Michael Gottesman
03986db44f [mem-access] Teach mem-access about mark_must_check. 2022-09-07 18:20:33 -07:00
Erik Eckstein
bfb284f827 Swift SIL: add a few instructions and Instruction.visitReferencedFunctions
* add `DynamicFunctionRefInst` and `PreviousDynamicFunctionRefInst`
* add a common base class to all function-referencing instructions: `FunctionRefBaseInst`
* add `KeyPathInst`
* add `IndexAddrInst.base` and `IndexAddrInst.index` getters
* add `Instruction.visitReferencedFunctions` to visit all functions which are referenced by an instruction
2022-08-24 17:55:02 +02:00
Egor Zhdan
0e2d438c5b [cxx-interop][SwiftCompilerSources] Use llvm::StringRef instead of BridgedStringRef
rdar://83361000
2022-07-21 16:32:16 +01:00
Erik Eckstein
325a0b1f48 swift SIL: add some Instruction, Value and Type APIs
* instructions `RefToBridgeObjectInst`, `BridgeObjectToWordInst`, `StringLiteralInst`, `ProjectBoxInst`, `InitEnumDataAddrInst`, `UncheckedTakeEnumDataAddrInst`, `InjectEnumAddrInst`
* protocols `StoringInstruction` and `EnumInstruction`
* load/store-weak/unowned instructions
* `CopyAddrInst.isTakeOfSrc/isInitializationOfDest`
* `ApplySite.calleeArgIndex/callerArgIndex`
* `SILValue.definingInstruction/definingBlock/function`
*  `Type.isReferenceCounted`
* `FunctionArgument.isExclusiveIndirectParameter`
* support `CondBranchInst` in `incomingPhiValues`
2022-03-30 14:45:58 +02:00
Andrew Trick
05fb8c7930 Remove CheckedCastValue from Swift compiler sources. 2022-03-22 18:09:48 -07:00
Rintaro Ishizaki
7486cd1c21 [SwiftCompiler] Move common bridging facilities to 'Basic'
A preparation for AST/DiagnosticEngine bridging
2022-02-20 22:06:39 -08:00
Erik Eckstein
f09dfc93a9 Swift SIL: escape effects for function arguments.
Store a list of argument effects in a function, which specify if and how arguments escape.
Such effects can be specified in the Swift source code (for details see docs/ReferenceGuides/UnderscoredAttributes.md) or derived in an optimization pass.

For details see the documentation in SwiftCompilerSources/Sources/SIL/Effects.swift.
2022-01-25 11:29:44 +01:00
Max Desiatov
848fa70529 libswift: reimplement Instruction helpers in Swift 2022-01-19 18:51:19 +00:00
Erik Eckstein
24b62d4d7c Swift SIL: add a few utilities and instructions
* instructions: function_ref, mark_dependence
* add `BuiltinInst.id`
* add isObjC and canAllocOnStack for alloc_ref and alloc_ref_dynamic
* add `ApplySite::referencedFunction`
* add `Builder.createDeallocStackRef`
* add == and != operators for `Function`
* add `List.first` and `ReverseList.first`
2022-01-12 15:47:15 +01:00
Erik Eckstein
383c52aa35 SIL: rename dealloc_ref [stack] -> dealloc_stack_ref
Introduce a new instruction `dealloc_stack_ref ` and remove the `stack` flag from `dealloc_ref`.

The `dealloc_ref [stack]` was confusing, because all it does is to mark the deallocation of the stack space for a stack promoted object.
2022-01-07 16:20:27 +01:00
Erik Eckstein
4beb94c2f9 Rename the libswift directory to SwiftCompilerSources 2021-12-22 09:46:25 +01:00