Commit Graph

626 Commits

Author SHA1 Message Date
Michael Gottesman
00d54ebaa8 [reference-binding] Add mark_unresolved_reference_binding to signal from SILGen to the pass to check.
Just the SIL part of this.
2023-03-03 17:14:41 -08:00
Nate Chandler
ec1a5e0911 Add attr to enable lexical lifetime per function.
Enables modules to migrate to the new lifetime rules incrementally.
2023-02-18 11:59:54 -08:00
Erik Eckstein
2c1d48b69c SIL: add type-dependent operands to the keypath instruction
It's need to correctly maintain dependencies from an open-existential instruction to a `keypath` instruction which uses the opened type.
Fixes a SILVerifier crash.

rdar://105517521
2023-02-17 17:48:55 +01:00
John McCall
a38478724a Add a pack_length SIL instruction for measuring the length of a pack 2023-02-10 21:50:44 -05: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
John McCall
159c653780 Add the tuple_pack_element_addr SIL instruction.
This allows dynamically indexing into tuples.  IRGen not yet
implemented.

I think I'm going to need a type_refine_addr instruction in
order to handle substitutions into the operand type that
eliminate the outer layer of tuple-ness.  Gonna handle that
in a follow-up commit.
2023-02-07 23:22:35 -05:00
John McCall
27142e42f6 Add SIL instructions to get and set pack elements 2023-02-07 01:10:15 -05:00
John McCall
6bf9ac858b Add instructions to allocate and deallocate packs.
Having added these, I'm not entirely sure we couldn't just use
alloc_stack and dealloc_stack.  Well, if we find ourselves adding
a lot of redundancy with those instructions (e.g. around DI), we
can always go back and rip these out.
2023-01-31 22:39:34 -05:00
John McCall
374c202b99 Add SIL instructions to generate pack indices 2023-01-19 23:57:22 -05:00
John McCall
37baf9b2dc Add a SIL instruction to open a pack as an element archetype
IRGen not yet done.
2023-01-11 03:11:30 -05:00
Pavel Yaskevich
f7ee072810 [Serialization] SILFunction: handling for "runtime accessible" attribute
Appears in serialized SIL as "[runtime_accessible]" optional attribute
on a SILFunction declaration.
2022-12-20 09:44:58 -08:00
Michael Gottesman
9e44011e4d [sil] Add a new attribute called @closureCaptured to SILFunctionArguments that are closure capture arguments.
I am adding this to make it easy to determine if a SILFunction that is not inout
aliasable is captured. This is useful when emitting certain types of
diagnostics like I need to emit with move only.
2022-12-14 15:16:43 -08:00
Allan Shortlidge
3da18b6e68 SIL: Serialize and deserialize has_symbol instructions. 2022-11-16 16:07:59 -08:00
Allan Shortlidge
0a24042cdd SIL: Introduce the has_symbol SIL instruction. 2022-11-16 16:07:26 -08:00
Erik Eckstein
c078b7677c Don't serialize derived function effects for function with @_semantics("optimize.no.crossmodule") 2022-10-20 09:20:28 +02:00
Nate Chandler
ab35362056 [SIL] Added new test_specification instruction.
The new instruction exists only to be used in tests.  The idea is to
specify tests that ought to be run "in the context" of the containing
function.
2022-10-11 17:15:13 -07: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
Dario Rexin
210c68d8aa [SILOptimizer] Add prespecialization for arbitray reference types (#58846)
* [SILOptimizer] Add prespecialization for arbitray reference types

* Fix benchmark Package.swift

* Move SimpleArray to utils

* Fix multiple indirect result case

* Remove leftover code from previous attempt

* Fix test after rebase

* Move code to compute type replacements to SpecializedFunction

* Fix ownership when OSSA is enabled

* Fixes after rebase

* Changes after rebasing

* Add feature flag for layout pre-specialization

* Fix pre_specialize-macos.swift

* Add compiler flag to benchmark build

* Fix benchmark SwiftPM flags
2022-09-22 16:29:01 -07:00
Michael Gottesman
c54acc83e2 [move-only] Add the ability to specify a deinit at the SIL level for a move only type.
Specifically, we get an additional table like thing called sil_moveonlydeinit. It looks as follows:

sil_moveonlydeinit TYPE {
  @FUNC_NAME
}

It always has a single entry.
2022-09-20 15:19:31 -07:00
Erik Eckstein
8e2e7a73c5 SIL: make argument effects more readable in textual SIL
So far, argument effects were printed in square brackets before the function name, e.g.
```
sil [escapes !%0.**, !%1, %1.c*.v** => %0.v**] @foo : $@convention(thin) (@guaranteed T) -> @out S {
bb0(%0 : $*S, %1 : @guaranteed $T):
...
```

As we are adding more argument effects, this becomes unreadable.
To make it more readable, print the effects after the opening curly brace, and print a separate line for each argument. E.g.
```
sil [ossa] @foo : $@convention(thin) (@guaranteed T) -> @out S {
[%0: noescape **]
[%1: noescape, escape c*.v** => %0.v**]
bb0(%0 : $*S, %1 : @guaranteed $T):
...
```
2022-09-12 09:14:54 +02:00
Erik Eckstein
97b2354be6 SIL: add needsStackProtection flags for address_to_pointer and index_addr instructions.
Also add new "unprotected" variants of the `addressof` builtins:
* `Builtin.unprotectedAddressOf`
* `Builtin.unprotectedAddressOfBorrow`
2022-09-08 08:42:22 +02:00
Hamish Knight
b12015c343 [SIL] Introduce the increment_profiler_counter instruction
This is a dedicated instruction for incrementing a
profiler counter, which lowers to the
`llvm.instrprof.increment` intrinsic. This
replaces the builtin instruction that was
previously used, and ensures that its arguments
are statically known. This ensures that SIL
optimization passes do not invalidate the
instruction, fixing some code coverage cases in
`-O`.

rdar://39146527
2022-09-07 17:55:13 +01:00
Erik Eckstein
d93ab2019a CrossModuleOptimization: public global variables must not be serialized if they reference private functions/closures
For example:
```
public static var privateFunctionPointer: (Int) -> (Int) = { $0 }
```

Fixes a verifier crash and/or undefined symbol error

rdar://99493254
2022-09-02 22:17:40 +02:00
Nate Chandler
dc3106f3f2 [Serialization] Explicit function arg lifetimes. 2022-08-21 21:44:51 -07:00
Nate Chandler
8450e37ddb [SIL] Removed SILArgument::isNoImplicitCopy.
The attribute can't be applied to non-function arguments and may cause
confusion by being available on them.
2022-08-21 21:44:30 -07:00
Allan Shortlidge
40eb1422bb IRGen/SIL: Fix IR linkage computation for inlined function references from modules imported @_weakLinked.
Include the parent `ModuleDecl` when serializing a `SILFunction` so that it is available on deserialized functions even though the full `DeclContext` is not present. With the parent module always available we can reliably compute whether the `SILFunction` comes from a module that was imported `@_weakLinked`.

Serialize the `DeclContext` member of `SILFunction` so that it can be used to look up the module that a function belongs to in order to compute weak import status.

Resolves rdar://98521248
2022-08-19 09:56:45 -07:00
Michael Gottesman
5baf2af88a [sil] Add a new instruction called explicit_copy_addr.
This is exactly like copy_addr except that it is not viewed from the verifiers
perspective as an "invalid" copy of a move only value. It is intended to be used
in two contexts:

1. When the move checker emits a diagnostic since it could not eliminate a copy,
we still need to produce valid SIL without copy_addr on move only types since we
will hit canonical SIL eventually even if we don't actually codegen the SIL. The
pass can just convert said copy_addr to explicit_copy_addr and everyone is
happy.

2. To implement the explicit copy function for address only types.
2022-08-11 11:40:53 -07:00
Michael Gottesman
9b625588f0 [sil] Make copyable_to_moveonlywrapper forwarding like moveonlywrapper_to_copyable.
Specifically this means that rather than always being owned, we now have owned
and guaranteed versions of copyable_to_moveonlywrapper. Similar to
moveonlywrapper_to_copyable, one chooses which variant one gets by using
specific SILBuilder APIs:
create{Owned,Guaranteed}CopyableToMoveOnlyWrapperValueInst. It is still
forwarding and the rest of the forwarding APIs work as expected except that the
forwarding ownership is fixed (and an assertion will result if one attempts to
do so).

NOTE: It is assumed that trivial operands are always passed to the owned
variant.
2022-07-19 14:39:59 -07:00
Michael Gottesman
e1006c62f9 [move-only] Add copyable_to_moveonlywrapper and moveonlywrapper_to_copyable instructions.
These instructions have the following attributes:

1. copyably_to_moveonlywrapper takes in a 'T' and maps it to a '@moveOnly
T'. This is semantically used when initializing a new moveOnly binding from a
copyable value. It semantically destroys its input @owned value and returns a
brand new independent @owned @moveOnly value. It also is used to convert a
trivial copyable value with type 'Trivial' into an owned non-trivial value of
type '@moveOnly Trivial'. If one thinks of '@moveOnly' as a monad, this is how
one injects a copyable value into the move only space.

2. moveonlywrapper_to_copyable takes in a '@moveOnly T' and produces a new 'T'
value. This is a 'forwarding' instruction where at parse time, we only allow for
one to choose it to be [owned] or [guaranteed].

* moveonlywrapper_to_copyable [owned] is used to signal the end of lifetime of
the '@moveOnly' wrapper. SILGen inserts these when ever a move only value has
its ownership passed to a situation where a copyable value is needed. Since it
is consuming, we know that the no implicit copy checker will ensure that if we
need a copy for it, the program will emit a diagnostic.

* moveonlywrapper_to_copyable [guaranteed] is used to pass a @moveOnly T value
as a copyable guaranteed parameter with type 'T' to a function. In the case of
using no-implicit-copy checking this is always fine since no-implicit-copy is a
local pattern. This would be an error when performing no escape
checking. Importantly, this instruction also is where in the case of an
@moveOnly trivial type, we convert from the non-trivial representation to the
trivial representation.

Some important notes:

1. In a forthcoming commit, I am going to rebase the no implicit copy checker on
top of these instructions. By using '@moveOnly' in the type system, we can
ensure that later in the SIL pipeline, we can have optimizations easily ignore
the code.

2. Be aware of is that due to SILGen only emitting '@moveOnly T' along immediate
accesses to the variable and always converts to a copyable representation when
calling other code, we can simply eliminate from the IR all moveonly-ness from
the IR using a lowering pass (that I am going to upstream). In the evil scheme
we are accomplishing here, we perform lowering of trivial values right after
ownership lowering and before diagnostics to simplify the pipeline.

On another note, I also fixed a few things in SILParsing around getASTType() vs
getRawASTType().
2022-06-09 19:47:31 -07:00
Erik Eckstein
26b03096c6 SIL: fix serialization of the unchecked_ref_cast instruction
We didn't serialize the ownership kind, which resulted in a miscompile causing an over-release.

The unchecked_ref_cast is the only instruction for which we change the ownership in the optimizer, so that it doesn't match the operand's ownership. Therefore this fix is sufficient for now - we don't need to serialize the ownership of other instructions.
But this is really a design flaw of the `OwnershipForwardingMixin`. It should not allow to set the ownership to arbitrary values.

rdar://92696202
2022-05-06 15:30:51 +02:00
Joe Groff
1e2bda9ea0 Extensions to SILBoxType to represent captures.
- Add a `[reflection]` bit to `alloc_box` instructions, to indicate that a box
  should be allocated with reflection metadata attached.
- Add a `@captures_generics` attribute to SILLayouts, to indicate a type layout
  that captures the generic arguments it's substituted with, meaning it can
  recreate the generic environment without additional ABI-level arguments, like
  a generic partial application can.
2022-04-21 12:51:46 -07:00
Konrad `ktoso` Malawski
dadf3011f9 cleanups 2022-04-18 16:53:44 -07:00
Konrad `ktoso` Malawski
79ad9278b2 [Distributed] Retain adhoc decodeNextArgument in distributed thunk 2022-04-18 16:53:10 -07:00
Erik Eckstein
6b7ae416e6 SIL: remove unused instructions thin_function_to_pointer and pointer_to_thin_function 2022-03-25 15:44:59 +01:00
Andrew Trick
2fd4de411e [SIL-opaque] Removed [Unconditional]CheckedCastValue 2022-03-22 17:04:13 -07:00
Erik Eckstein
6a020f8f15 Stabilize and simplify SIL linkage and serialization
The main point of this change is to make sure that a shared function always has a body: both, in the optimizer pipeline and in the swiftmodule file.
This is important because the compiler always needs to emit code for a shared function. Shared functions cannot be referenced from outside the module.
In several corner cases we missed to maintain this invariant which resulted in unresolved-symbol linker errors.

As side-effect of this change we can drop the shared_external SIL linkage and the IsSerializable flag, which simplifies the serialization and linkage concept.
2022-03-09 15:28:05 +01:00
John McCall
713bb43a94 Rework the serialization schema for conformances and requirements.
We now schedule conformance emissions in basically the same way
we do for types and declarations, which means that we'll emit them
uniquely in the module file instead of redundantly at every use.
This should produce substantially smaller module files overall,
especially for modules that heavily use generics.  It also means
that we can remove all the unfortunate code to support using
different abbrev codes for them in different bitcode blocks.

Requirement lists are now emitted inline in the records that need
them instead of as trailing records.  I think this will improve
space usage, but mostly it assists in eliminating the problem
where abbrev codes are shared between blocks.
2022-02-28 17:32:00 -05:00
Michael Gottesman
375ce353f2 [move-function] Add a flag to alloc_stack and debug_value that states that they describe an address/value that was moved at some point locally in the function.
The main effect of this will be that in IRGen we will use llvm.dbg.addr instead
of llvm.dbg.declare. We must do this since llvm.dbg.declare implies that the
given address is valid throughout the program.

This just adds the instructions/printing/parsing/serialization/deserialization.

rdar://85020571
2022-02-14 17:56:03 -08:00
Michael Gottesman
68d37e142b [no-implicit-copy] Add a new instruction called MarkMustCheckInst and use it in the move checker.
This is an instruction that I am going to use to drive some of the ownership
based dataflow optimizations that I am writing now. The instruction contains a
kind that allows one to know what type of checking is required and allows the
need to add a bunch of independent instructions for independent checkers. Each
checker is responsible for removing all of its own mark instructions. NOTE:
MarkMustCheckInst is only allowed in Raw SIL since once we are in Canonical SIL
we want to ensure that all such checking has already occurred.
2022-01-29 14:49:39 -08:00
nate-chandler
0472c0d83c Merge pull request #40926 from nate-chandler/sil/move_value_defined_flag
[SIL] Added lexical flag to move_value.
2022-01-26 19:58:27 -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
Nate Chandler
572510835b [SIL] Added lexical flag to move_value.
The new flag will be used to track whether a move_value corresponds to a
source-level lexical scope. Here, the flag is just added to the
instruction and represented in textual and serialized SIL.
2022-01-20 08:33:09 -08: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
Pavel Yaskevich
4860f90fd7 [SIL] Add new flag to SILFunction - IsDistributed
Determines whether given SILFunction represents a distributed
method or its thunk.
2021-12-17 10:52:52 -08:00
Michael Gottesman
d74299e68d [move-function] Add a new instruction called mark_unresolved_move_addr.
This instruction is similar to a copy_addr except that it marks a move of an
address that has to be checked. In order to keep the memory lifetime verifier
happy, the semantics before the checker runs are the mark_unresolved_move_addr is
equivalent to copy_addr [init] (not copy_addr [take][init]).

The use of this instruction is that Mandatory Inlining converts builtin "move"
to a mark_unresolved_move_addr when inlining the function "_move" (the only
place said builtin is invoked).

This is then run through a special checker (that is later in this PR) that
either proves that the mark_unresolved_move_addr can actually be a move in which
case it converts it to copy_addr [take][init] or if it can not be a move, emit
an error and convert the instruction to a copy_addr [init]. After this is done
for all instructions, we loop back through again and emit an error on any
mark_unresolved_move_addr that were not processed earlier allowing for us to
know that we have completeness.

NOTE: The move kills checker for addresses is going to run after Mandatory
Inlining, but before predictable memory opts and friends.
2021-12-06 12:47:29 -08:00
Andrew Trick
90c0c8b60f Add rebind_memory SIL instruction.
Required for UnsafeRawPointer.withMemoryReboud(to:).

%out_token = rebind_memory %0 : $Builtin.RawPointer to %in_token

%0 must be of $Builtin.RawPointer type

%in_token represents a cached set of bound types from a prior memory state.

%out_token is an opaque $Builtin.Word representing the previously bound
types for this memory region.

This instruction's semantics are identical to ``bind_memory``, except
that the types to which memory will be bound, and the extent of the
memory region is unknown at compile time. Instead, the bound-types are
represented by a token that was produced by a prior memory binding
operation. ``%in_token`` must be the result of bind_memory or
2021-11-14 22:44:46 -08:00
Michael Gottesman
99d87c35f8 [moveOnly] Allow for move_value to have an optional [allows_diagnostics] modifier.
This is a signal to the move value kill analysis that this is a move that should
have diagnostics emitted for it. It is a temporary addition until we add
MoveOnly to the SIL type system.
2021-11-04 17:13:29 -07:00
Michael Gottesman
4cd1201bab [noImplicitCopy] Add support for marking a SILArgument as being a NoImplicitCopy argument.
I am purposely doing this in SILGen rather than at the type system level to
avoid having to have to add a bunch of boilerplate to the type system. Instead
of doing that, I am in SILGen checking for the isNoImplicitCopy bit on the
ParamDecl when we emit arguments. At that point, I set on the specific
SILArgument being emitted the bit that it is no implicit copy. In terms of
printing at the SIL level, I just printed it in front of the function argument
type like @owned, e.x.:

  func myFunc(_ x: @_noImplicitCopy T) -> T {
  ...
  }

becomes:

  bb0(%0 : @noImplicitCopy @owned $T):

Some notes:

* Just to be explicit, I am making it so that no implicit copy parameters by
  default are always passed at +1. The reason why I think this makes sense is
  that this is the natural way of working with a move only value.

* As always, one can not write no implicit copy the attribute without passing
  the flag -enable-experimental-move-only so this is NFC.

rdar://83957088
2021-11-01 09:34:38 -07:00
Michael Gottesman
f9122a79b7 [moveOnly] Implement a new _copy function that performs an explicit copy value.
The key thing is that the move checker will not consider the explicit copy value
to be a copy_value that can be rewritten, ensuring that any uses of the result
of the explicit copy_value (consuming or other wise) are not checked.

Similar to the _move operator I recently introduced, this is a transparent
function so we can perform one level of specialization and thus at least be
generic over all concrete types.
2021-10-29 15:37:46 -07:00
Erik Eckstein
8229b374b1 Performance annotations: add attributes @_noLocks and @_noAllocation 2021-10-28 18:43:14 +02:00