Commit Graph

1328 Commits

Author SHA1 Message Date
Andrew Trick
f9861ec9c0 Add APIs for terminator results that forward ownership.
Add TermInst::forwardedOperand.

Add SILArgument::forwardedTerminatorResultOperand. This API will be
moved into a proper TerminatorResult abstraction.

Remove getSingleTerminatorOperand, which could be misused because it's
not necessarilly forwarding ownership.

Remove the isTransformationTerminator API, which is not useful or well
defined.

Rewrite several instances of complex logic to handle block arguments
with the simple terminator result API. This defines away potential
bugs where we don't detect casts that perform implicit conversion.

Replace uses of the SILPhiArgument type and code that explicitly
handle block arguments. Control flow is irrelevant in these
situations. SILPhiArgument needs to be deleted ASAP. Instead, use
simple APIs like SILArgument::isTerminatorResult(). Eventually this
will be replaced by a TerminatorResult type.
2022-12-12 12:37:35 -08:00
Erik Eckstein
c180d1363e SIL: simplify deleting instruction while iterating over instructions.
Add `deletableInstructions()` and `reverseDeletableInstructions()` in SILBasicBlock.
It allows deleting instructions while iterating over all instructions of the block.
This is a replacement for `InstructionDeleter::updatingRange()`.
It's a simpler implementation than the existing `UpdatingListIterator` and `UpdatingInstructionIteratorRegistry`, because it just needs to keep the prev/next pointers for "deleted" instructions instead of the iterator-registration machinery.
It's also safer, because it doesn't require to delete instructions via a specific instance of an InstructionDeleter (which can be missed easily).
2022-12-12 19:08:54 +01:00
Erik Eckstein
05a63c70c5 SIL: change way how a SILInstruction is marked as deleted
Instead of setting the parent pointer to null, set the `lastInitializedBitfieldID` to -1.
This allows to keep the parent block information, even when an instruction is removed from it's list.
2022-12-12 19:06:00 +01:00
Erik Eckstein
2ca9a3b9ce SIL: fix APIs for (re)moving instructions
Instructions can only be moved and erased, but never _removed_ from a block.
2022-12-12 19:05:59 +01:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01:00
Xi Ge
c5a7eff0c9 Merge pull request #62147 from tshortli/has-symbol-sil-instruction 2022-11-18 04:34:24 -08:00
Anton Korobeynikov
a5e83817b2 Reapply "Implement several peephole optimizations to unblock further optimizations of autodiff code" with correctness fix (#62012)
* Implement several peephole optimizations to unblock further optimizations of autodiff code

1. Simplify differentiable_function_extract of differentiable_function.
Before:
%x = differentiable_function(%orig, %jvp, %vjp)
%y = differentiable_function_extract [original] %x
After:
%y = %orig

2. Push conversion instructions inside of differentiable_function.
This unblocks inlining and specialization.
Before:
%x = differentiable_function(%orig, %jvp, %vjp)
%y = convert_escape_to_noescape %x
After:
%orig' = convert_escape_to_noescape %orig
%jvp' = convert_escape_to_noescape %jvp
%vjp' = convert_escape_to_noescape %vjp
%y = differentiable_function(%orig', %jvp', %vjp')

3. Another peephole is needed for reordering function conversion instructions to enable full inlining:
(convert_escape_to_noescape (convert_function (thin_to_thick_function x)))
=>
(convert_escape_to_noescape (thin_to_thick_function (convert_function x)))

Co-authored-by: Dan Zheng <danielzheng@google.com>
2022-11-16 23:21:27 -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
Meghana Gupta
5e20112e0c Revert "Implement several peephole optimizations to unblock further optimizations of autodiff code (#60520)"
This reverts commit 2f5492f572.
2022-10-25 13:35:14 -07:00
Erik Eckstein
f6fb3c75db SILInstructions.h: fix ApplyInstBase::getSingleResult() 2022-10-20 09:20:28 +02: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
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
Pavel Yaskevich
df87a494c2 [SIL] Add originator to assign_by_wrapper instruction
Originator of this temporary instruction could be either
type or property wrapper.
2022-09-29 20:50:36 -07:00
Andrew Trick
ea3947ac44 Merge pull request #61291 from atrick/debug-trace
Add debug_value [trace] attribute.
2022-09-26 14:52:14 -07:00
Anton Korobeynikov
2f5492f572 Implement several peephole optimizations to unblock further optimizations of autodiff code (#60520)
* Implement several peephole optimizations to unblock further optimizations of autodiff code

1. Simplify differentiable_function_extract of differentiable_function.
Before:
%x = differentiable_function(%orig, %jvp, %vjp)
%y = differentiable_function_extract [original] %x
After:
%y = %orig

2. Push conversion instructions inside of differentiable_function.
This unblocks inlining and specialization.
Before:
%x = differentiable_function(%orig, %jvp, %vjp)
%y = convert_escape_to_noescape %x
After:
%orig' = convert_escape_to_noescape %orig
%jvp' = convert_escape_to_noescape %jvp
%vjp' = convert_escape_to_noescape %vjp
%y = differentiable_function(%orig', %jvp', %vjp')

3. Another peephole is needed for reordering function conversion instructions to enable full inlining:
(convert_escape_to_noescape (convert_function (thin_to_thick_function x)))
=>
(convert_escape_to_noescape (thin_to_thick_function (convert_function x)))

* Remove broken disabled folding transform:
  - It is disabled
  - It is broken
  - It is certainly not something mandatory

Co-authored-by: Dan Zheng <danielzheng@google.com>
2022-09-26 09:44:04 -07:00
Andrew Trick
87d7237181 Add debug_value [trace] attribute.
This lets us write optimizer unit tests and selectively debug the
optimizer in general. We'll be able trace analyses and control
optimization selectively for certain values.

Adding a trace flag to debug_value is the easiest way to start using
it experimentally and develop the rest of the infrastructure. If this
takes off, then we can consider a new `trace_value`
instruction. For now, reusing debug_value is the least intrusive way to
start writing liveness unit tests.
2022-09-25 22:44:15 -07: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
Andrew Trick
c14059e92c [comment] Add a semantics note to SIL BindMemory 2022-08-29 13:20: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
65c21b61bf [move-only] Begin implementing support for concrete move only types.
This is just the very beginning... I still need to implement more parts of
SILGen for this. But all great things start small. I am going to iterate on top
of this and just wanted to get some initial parts of the work in as I go.
2022-07-21 15:33:17 -07:00
Michael Gottesman
7a43d246b0 Merge pull request #60047 from gottesmm/plus_zero_fix_noimplicitcopy
[no-implicit-copy] Use default param convention instead of forcing +1
2022-07-20 02:36:52 -07:00
Michael Gottesman
f1182a73da [no-implicit-copy] Remove auto +1 param signature change called by noimplicit copy in favor of following normal convention.
I also added a bunch of tests for both the trivial/non-trivial case as well as
some docs to SIL.rst.
2022-07-19 16:39:03 -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
eeckstein
511bd67929 Merge pull request #59999 from eeckstein/simplify-silnode-bits
SIL: simplify the SILNode inline bitfields.
2022-07-12 07:04:56 +02:00
Michael Gottesman
98dbfaeb59 [no-implicit-copy] Assert in SILBuilder that mark_must_check only can take a MoveOnlyWrapped value.
In the future, we may not have this requirement, but for now it is a really
convenient way to track down places in SILGen where I have missed converting
from copyable to moveonlywrapped types.
2022-07-11 12:28:46 -07:00
Erik Eckstein
64ba6fdf5d SIL: simplify the SILNode inline bitfields.
The use of the SWIFT_INLINE_BITFIELD macros in SILNode were a constant source of confusion and bugs.
With this refactoring I tried to simplify the definition of "shared fields" in SILNode, SILValue and SILInstruction classes:

* Move `kind`, `locationKindAndFlags` and the 32-bit fields out of the 64-bitfield into their own member variables. This avoids _a lot_ of manual bit position computations.
* Now we have two separate "shared fields": an 8-bit field (e.g. for boolean flags) and a 32-bit field (e.g. for indices, which can potentially get large). Both fields can be used independently. Also, they are not "bit fields" per se. Instructions can use the field e.g. as a `bool`, `uint32_t`, or  - if multiple flags are to be stored - as a packed bit field.
* With these two separate fields, we don't have the need for defining bitfields both in a base class _and_ in a derived value/instruction class. We can get rid of the complex logic which handles such cases. Just keep a check to catch accidental overlaps of fields in base and derived classes.
* Still use preprocessor macros for the implementation, but much simpler ones than before.
* Add documentation.
2022-07-11 17:27:29 +02:00
Michael Gottesman
72523cf9d0 [move-only] Fix a few bugs around MoveOnlyWrapperToCopyableValue.
The main fixes are:

1. MoveOnlyWrapperToCopyableValue needed to be marked as a
   FirstArgOwnershipForwardingSingleValueInst instead of just as being an
   Ownership mixin. I discovered that in certain cases I was treating it that
   way (in the isa check for FirstArgOwnershipForwardingSingleValueInst), but we
   were inconsistent. Now we are consistent.

2. MoveOnlyWrapperToCopyableValue is always specified as being initialized as
   owned or guaranteed. What is key to understand though is that the
   owned/guaranteed property here is more a semantic property around whether the
   lifetime of the move only value is ending or if we are allowing it to escape
   as an moveonlywrapped unwrapped guaranteed parameter to a function. The main
   implication of this is that we can not just use the actual ownership kind to
   determine the type of moveonlywrapper_to_copyable we are using. This is b/c
   after ownership lowering, the resulting ownership kind will be none, meaning
   the instruction will be in an invalid state. Thus the need to represent this
   as a separate bit in the instruction. It may make sense to rename the forms
   of this instruction to be `[lifetime end]` and `[guaranteed function arg]`
   that way it is semantically clear. But I am going to do that change at
   another time.
2022-06-15 14:15:21 -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
f3adbd5c0e SIL: cache case indices in enum instructions.
As we do with field indices for struct instructions.
This avoids quadratic behavior in case of enums with lots of cases.
Also: cache field and enum case indices in the SILModule.
2022-05-16 09:33:14 -07:00
Joe Groff
d2fad71328 Merge pull request #42589 from jckarter/begin-partial-apply-simplification-pass
[SIL] Initial work on PartialApplySimplification pass
2022-05-02 10:20:39 -07:00
Josh Soref
d767912be2 Spelling sil (#42471)
* spelling: accessible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: accessories

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: allocated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: amortizes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: are

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: arguments

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: cacheable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: check

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clazz

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: compatible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: compilation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: completely

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: construct

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conversion

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declarations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: derivation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: deserialization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: destroyed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: determined

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: different

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: doesn't

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equality

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equivalent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: formation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: forwards

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: global

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: guaranteed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: have

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: identify

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inaccessible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indeterminate

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indices

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inefficient

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inheritance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instantaneous

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instruction

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intentionally

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interior

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intrinsic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: introducing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: irrelevant

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: message

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: multi

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: necessarily

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: object

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: one

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: optimization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: otherwise

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overridden

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameter

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: pattern

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: pipeline

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: possibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: postdominance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: providing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: reached

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recognized

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: refrigerator

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: remaining

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: resilient

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: retrieve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scavenge

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scheduled

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: separately

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: serializable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: signature

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simplicity

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specifically

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substituted

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substitution

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: subtypes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: supplement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: syntax

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: there

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: these

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: this

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: though

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: through

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transitively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transpose

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: trivial

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: value

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: verification

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: visibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: weird

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: whole

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-22 15:11:09 -07:00
Joe Groff
5d7861ff1e Support non-generic nonescaping partial_applys using an on-stack tuple 2022-04-21 12:51:48 -07:00
Joe Groff
f2e785e66d (wip) reflection flag for alloc_box 2022-04-21 12:47:45 -07:00
Andrew Trick
a7c6a94ceb CheckedBranchInst now uses doesCastPreserveOwnership.
Use the new API that determines whether a cast preserves
ownership. Remove an old hack.
2022-04-12 22:23:17 -07:00
Andrew Trick
64ec981f3b Rename isDirectlyForwarding to preservesOwnership. 2022-04-12 22:23:17 -07: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
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
Michael Gottesman
056132cca0 [move-function] Add a new pass that propagates debug_value [moved] into coroutine func-lets.
NOTE: debug_value [moved] appearing in the source code implies a _move was
used. So this will not effect current stable swift code.

This is just a first version of this that I am using to commit/bring up tests
for IRGen supporting a full dataflow version of this patch.

Big picture is that there is a bunch of work that is done in the LLVM level in
the coroutine splitter to work around communicating live variables in the
various coroutine func-lets. This logic is all done with debug.declare and we
would need to update that logic in the coroutine splitter to handle
debug.addr. Rather than do this, after some conversation, AdrianP and I realized
that we could get the same effect of a debug.declare by just redeclaring the
current live set of debug_value after each possible coroutine funclet start. To
do this in full generality, we need a full dataflow but just to bring this up we
initially perform a dominance propagation algorithm of the following sort:

1. We walk the CFG along successors. By doing this we guarantee that we visit
   blocks after their dominators.

2. When we visit a block, we walk the block from start->end. During this walk:

   a. We grab a new block state from the centralized block->blockState map. This
      state is a [SILDebugVariable : DebugValueInst].

   b. If we see a debug_value, we map blockState[debug_value.getDbgVar()] =
      debug_value. This ensures that when we get to the bottom of the block, we
      have pairs of SILDebugVariable + last debug_value on it.

   c. If we see any coroutine funclet boundaries, we clone the current tracked
      set of our block state and then walk up the dom tree dumping in each block
      any debug_value with a SILDebugVariable that we have not already
      dumped. This is maintained by using a visited set of SILDebugVariable for
      each funclet boundary.

The end result is that at the beginning of each funclet we will basically
declare the debug info for an addr.

This is insufficient of course for moves that are in conditional control flow,
e.x.:

```
let x = Klass()
if boolValue {
  await asyncCall()
  let _ = _move(x)
}
```

but this at least lets me begin to write tests for this in lldb using straight
line code and work out the rest of the issues in CodeGen using those tests.
2022-03-21 14:20:06 -07:00
Ben Langmuir
5ce7bf9c18 Use std::reverse_iterator_range
We're using c++14, so no need to use the llvm:: copy of this. The llvm
version is going away, so this fixes build errors on the "next" branch.
2022-02-24 13:49:28 -08:00
Michael Gottesman
ac7e28a57e [alloc-stack-hoisting] Handle alloc_stack [move] correctly.
This is just a quick fix to stop us from dropping live values such as m in the
following example:

```
public func addressOnlyVarTest<T : P>(_ x: T) {
    var k = x
    k.doSomething()
    let m = _move(k)
    m.doSomething()
    k = x
    k.doSomething()
}
```

Before this change, we would just drop m and one wouldn't even see it in the
debugger.

I am only doing this currently for cases where when we merge at least one
alloc_stack was moved. The reason why is that to implement this correctly, I
need to use llvm.dbg.addr and changing the debug info from using
llvm.dbg.declare -> llvm.dbg.addr requires statistics and needs to be done a
little later in the swift development process. If one of these alloc_stack had
the [moved] marker attached to it, we know the user /did/ use move so they have
in a sense opted into having a move function effect its program so we are only
changing how new code appears in the debugger.
2022-02-22 20:36:19 -08:00
Arnold Schwaighofer
62ec31a462 Merge pull request #41338 from aschwaighofer/reuse_contiguous_array_storage_metadata
Reuse `_ContiguousArrayStorage<AnyObject>` metadata for any class or objc generic type
2022-02-17 12:47:23 -05:00
Andrew Trick
59eea142c4 Add OwnershipForwardingMixin::hasSameRepresentation and verify
Also add OwnershipForwardingMixin::isAddressOnly.
2022-02-16 12:23:01 -08:00
Arnold Schwaighofer
9f2b6a4ebb Reuse _ContiguousArrayStorage<AnyObject> metadata for any class or objc generic type
Reduces the number of _ContiguousArrayStorage metadata.

In order to support constant time bridging we do need to set the correct
metadata when we bridge to Objective-C. This is so that the type check
succeeds when bridging back from Objective-C to reuse the storage
instance rather than bridging the elements.

To support dynamically setting the `_ContiguousArrayStorage` element
type i needed to add support for optimizing `alloc_ref_dynamic`
throughout the optimizer.

Possible future improvements:
* Use different metadata such that we can disambiguate native Swift
  classes during destruction -- allowing native release rather then unknown
  release usage.
* Optimize the newly added semantic function
  getContiguousArrayStorageType

rdar://86171143
2022-02-16 07:55:34 -08:00
Andrew Trick
f6ba6332a6 Allow SIL convention overriding in operand ownership verification
This lets the SILBuilder's verification continue to run during
address lowering before the SIL stage has been updated.
2022-02-15 13:28:47 -08:00
Andrew Trick
05224aaa1f Improve the SILInstruction::getOperandValues() API.
Add NonTypeDependentOperandToValue predicate for composability.

Add a getNonTypeDependentOperandValues(), which can be used as a functor.

The skipTypeDependentOperands parameter complicated the API.
2022-02-15 13:24:29 -08: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
Andrew Trick
07e6cfc8ae Fix a miscompile in existential specialization during SILCombine.
The transformation propagations stack-initialized values. It checks
for any writes to the stack before doing so. OpenExistial instructions
now have a mutable property, so that also needs to be checked.

Add OpenExistentialAddrInst::isRead(SILInstruction).

Replace an `isa<OpenExistentialAddrInst>(user)` check with
`OpenExistentialAddrInst::isRead(user).

Fixes rdar://88664423 (SR-15791: Miscompile under -O with mutating protocol method)
2022-02-11 13:10:14 -08:00