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.
The testing works by way of a new pass "UnitTestRunner" and a new
instruction test_specification. When a function contains
test_specification instructions, it invokes the UnitTest subclass named
in the test_specification instruction with the arguments specified in
that instruction.
For example, when running the unit-test-runner class, having the
instructions
```
test_specification "my-neato-utility 19 @function[callee].block[2] @trace[2]"
test_specification "my-neato-utility 43 @block @trace"
```
would result in the test associated with "my-neato-utility" in
UnitTestRunner.cpp being invoked twice. Once with (19, aBlock, aValue),
and once with (43, anotherBlock, someOtherValue). That UnitTest
subclass class would need to call takeUInt, takeBlock, and takeTrace on
the Arguments struct it is invoked with. It would then pass those
arguments along to myNeatoUtility and dump out interesting results. The
results would then be FileChecked.
To improve the debugging experience of values whose lifetimes are
canonicalized without compromising the semantics expressed in the source
language, when canonicalizing OSSA lifetimes at Onone, lengthen
lifetimes as much as possible without incurring copies that would be
eliminated at O.
rdar://99618502
Rather than having finding the boundary be a single combined step,
separate finding the original boundary from extending that boundary.
This enables inserting an optional step between those steps, namely to
extend unconsumed liveness to its original extent at Onone.
It is possible for phis to be marked live. With guaranteed phis, they
will be the last uses and be non-consuming. In this case, the
merge block will have multiple predecessors whose terminators are on the
boundary. When inserting destroys, track whether a merge point has been
visited previously.
To facilitate this, restructure the boundary extension and destroy
insertion code.
Previously, the extender was building up a list of places at which to
insert destroys. In particular it was using the "boundary edge"
collection for all blocks at the beginning of which a destroy should be
created. In particular, it would add merge blocks. Such blocks are not
boundary blocks.
Here, the extender produces a PrunedLivenessBoundary which doesn't
violate that invariant.
This required some changes to the destroy insertion code to find where
to insert destroys. It is now similar to
PrunedLivenessBoundary::visitInsertionPoints and could be used as a
template for a PrunedLivenessBoundary::visitBoundaryPoints through which
::visitInsertionPoints might be factored.
Previously, the destroys set (now set vector) wasn't ever being cleared.
The result was that users could get overly pessimistic behavior if they
had previously used the utility with a destroy that came after the
destroys relevant for its current run. Here, it is cleared when the
utility is initialized with a new def. Addresses a TODO in the
copy_propagation test.
Previously, CanonicalizeOSSALifetime had its own copy of a variation of
the code for computing the liveness boundary that PrunedLiveness has.
Here, it is switched over to using PrunedLiveness' version.
In order to do that without complicating the interface for PrunedLivness
by adding a visitor, the extra bookkeeping that was being done for
destroy_values and debug_values is dropped. Instead, after getting an
original boundary from PrunedLiveness::computeBoundary, the boundary is
extended out to preexisting destroys which are not separated from the
original boundary by "interesting" instructions.
First restore the basic PrunedLiveness abstraction to its original
intention. Move code outside of the basic abstraction that polutes the
abstraction and is fundamentally wrong from the perspective of the
liveness abstraction.
Most clients need to reason about live ranges, including the def
points, not just liveness based on use points. Add a PrunedLiveRange
layer of types that understand where the live range is
defined. Knowing where the live range is defined (the kill set) helps
reliably check that arbitrary points are within the boundary. This
way, the client doesn't need to be manage this on its own. We can also
support holes in the live range for non-SSA liveness. This makes it
safe and correct for the way liveness is now being used. This layer
safety handles:
- multiple defs
- instructions that are both uses and defs
- dead values
- unreachable code
- self-loops
So it's no longer the client's responsibility to check these things!
Add SSAPrunedLiveness and MultiDefPrunedLiveness to safely handle each
situation.
Split code that I can't figure out into
DiagnosticPrunedLiveness. Hopefully it will be deleted soon.
Andy some time ago already created the new API but didn't go through and update
the old occurences. I did that in this PR and then deprecated the old API. The
tree is clean, so I could just remove it, but I decided to be nicer to
downstream people by deprecating it first.
And replace them with explicit `metatype` instruction in the entry block.
This allows such metatype instructions to be deleted if they are dead.
rdar://94388453
The resignID call within the initializer moved into DI, because an assignment to
the actorSystem, and thus initialization of the id, is no longer guaranteed to happen.
Thus, while we previously could model the resignation as a clean-up emitted on all
unwind paths in an initializer, now it's conditional, based on whether the id was
initialized. This is exactly what DI is designed to do, so we inject the resignation
call just before we call the identity's deinit.
The reason why I am doing this is that right now SelectionDAG seems to sink
certain llvm.dbg.addr to the end of block. By breaking the block, we ensure that
we initialize the debug value of values early enough. NOTE: We are relying on
code at -Onone not eliminating control flow which it does not today.
A few additional notes:
1. I also fixed a small issue where I was not setting the proper debug scope for
reinit debug_values. This came up when I was writing test cases for this commit.
So I just fixed it at the same time.
2. Since I am splitting blocks and I don't want to invalidate dominators/etc at
this point in the pipeline, I took advantage of the APIs ability to update
dominators/loopinfo at the same time.
3. I also expanded the tests in tree further by adding debug info tests for the
reinit copyable/addressonly cases in the multi-block case.
The new utility, to be run as part of copy propagation, hoists
destroy_values of owned lexical values up to deinit barriers. It is
heavily based on the rewritten ShrinkBorrowScope.
Replaced ShrinkBorrowScope's own data flow with the general
BackwardReachability.
Took this opportunity to refactor and document the utility.
Taken together these changes make ShrinkBorrowScope serve as a template
for a future LexicalDestroyHoisting which will operate on owned lexical
values (rather than guaranteed as here) and hoist destroy_values (rather
than end_borrows as here) but should otherwise be quite similar.
RAUWing a lexical value with a non-lexical value is illegal because it
would result in the value's lifetime being shortened without regard to
deinit barriers. RAUWing _with_ a lexical value is LEGAL so long as
doing so doesn't extend its lifetime.
C++ closures can implicitly malloc.
Avoid this by just capturing `this` and nothing else.
Reduces the time spent in the SIL pass pipeline by 25% when compiling the stdlib core.
rdar://88567996
The new utility folds patterns like
TOP:
// %borrowee is some owned value
%lifetime = begin_borrow %borrowee
BOTTOM:
// %copy is some transitive copy of %borrowee
apply %f(%copy)
end_borrow %lifetime
destroy_value %borrowee
into
TOP:
%move = move_value [lexical] %borrowee
%lifetime begin_borrow [lexical] %move
BOTTOM:
end_borrow %lifetime
apply %f(%move)
It is intended to be run after ShrinkBorrowScope moves the end_borrow up
to just before a relevant apply and after CanonicalizeOSSALifetime moves
destroy_value instructions up to just after their last guaranteed use,
at which point these patterns will exist.
Pulled out a simple check--that CanonicalizeOSSALifetime now uses to
determine whether to continue hoisting a destroy_value instruction--into
a predicate that can be used by LexicalDestroyFolding.
This optimizes keypath-closures, like
```
a.map { \.x }
```
It results in a significant performance improvement for such code patterns.
rdar://87968067
Squashed commit of the following:
commit e5a05ffe44
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Thu Jan 27 17:45:31 2022 +0900
cleanup
commit 1f751cea5a
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Thu Jan 27 14:50:33 2022 +0900
cleanups
commit c632f3215d
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Thu Jan 27 14:01:09 2022 +0900
add test for generic from actor decl
commit 09b8bd50a7
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Thu Jan 27 14:00:58 2022 +0900
cleanups
commit 31f4d0cffd
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Thu Jan 27 11:40:51 2022 +0900
fix test
commit ad4db2fb6c
Merge: 97227edcca07e2dfda56
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 26 23:31:41 2022 +0900
Merge branch 'main' into wip-zzz
commit 97227edcca
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 26 21:01:25 2022 +0900
remove @_dynamic methods!
fix tests
commit 1c79344dbb
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 19 12:51:09 2022 +0900
cleanup
wip
stuck
fixed the stack cleanups
cleanups pretty good now
weird load
rki
works
remove hack
add take + throw + return
fix test
more tests fixed
more tests fixed
more tests fixed
commit 3ed494c175
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Tue Jan 18 21:09:28 2022 +0900
stack issues in SIL verification
commit 5cf43a7f86
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Tue Jan 18 09:19:51 2022 +0900
about to call the remoteCall
goot to return, but missing subs
commit df8e47122a
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Thu Jan 13 14:09:49 2022 +0900
[Distributed] Refactor Invocation to Decoder/Encoder
getting there
done-recording
working on the string init
stuck trying to get String initializer SILFunction
created the remote call target
commit fc7bd62f32
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 12 23:01:14 2022 +0900
[Distributed] Pass arguments from Invocation to HBuffer
commit cafc2cc058
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 12 22:08:47 2022 +0900
works
commit a7d01837ff
Author: Pavel Yaskevich <pyaskevich@apple.com>
Date: Tue Jan 11 15:48:58 2022 -0800
[Distributed] Adjust interface of `swift_distributed_execute_target`
Since this is a special function, `calleeContext` doesn't point to
a direct parent but instead both parent context (uninitialized)
and resume function are passed as last arguments which means that
`callContext` has to act as an intermediate context in call to accessor.
commit c1f830be27
Author: Pavel Yaskevich <pyaskevich@apple.com>
Date: Tue Jan 11 17:00:08 2022 -0800
[Distributed] Drop optionality from result buffer in `_executeDistributedTarget`
`RawPointer?` is lowered into a two arguments since it's a struct,
to make it easy let's just allocate an empty pointer for `Void` result.
commit c83c2c37b6
Author: Pavel Yaskevich <pyaskevich@apple.com>
Date: Tue Jan 11 17:02:45 2022 -0800
[Distributed] NFC: Update _remoteCall test-case to check multiple different result types
commit 29e7cf50e4
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 12 21:32:37 2022 +0900
wip
commit 9128ecc6f8
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 12 20:46:20 2022 +0900
wip
commit a6b2a62a67
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 12 20:38:22 2022 +0900
wip
commit 8b188f0d43
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 12 16:55:10 2022 +0900
wip
commit 3796bec2b9
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Jan 12 16:55:02 2022 +0900
wip
commit 0ffc68b5ef
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Tue Jan 11 21:44:58 2022 +0900
[Distributed] Implementing ad-hoc protocol requirements
commit 78862575e4
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Thu Jan 6 18:03:54 2022 +0900
cleanup
commit 5f4ab89e25
Merge: 24a628e7c0fdda6f2ee4
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Thu Jan 6 15:51:39 2022 +0900
Merge branch 'main' into wip-impl-execute-swift
commit 24a628e7c0
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Thu Jan 6 15:33:21 2022 +0900
wip
commit 69e7fed09d
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Dec 22 06:36:45 2021 +0900
[Distributed] comment out distributed_actor_remoteCall for now
commit 376733a9f6
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Tue Dec 21 16:00:06 2021 +0900
reimplement distributed get type info impls
commit 74ab47886a
Author: Konrad `ktoso` Malawski <konrad_malawski@apple.com>
Date: Wed Dec 15 21:37:08 2021 +0900
[Distributed] Implement func metadata and executeDistributedTarget
dont expose new entrypoints
able to get all the way to calling _execute
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.
So that CopyPropagation and other clients can react accordingly, pass
back a list of copy_value instructions that were rewritten by
ShrinkBorrowScope. In CopyPropagation, add each modified copy to the
copy worklist.