Commit Graph

2601 Commits

Author SHA1 Message Date
Nate Chandler
bf3e425e0f [Mem2Reg] Omit lexical moves for lexical values.
When promoting an `alloc_stack [lexical]` that is "owned" (i.e. not a
store_borrow location), omit lexical lifetimes (represented with
`move_value [lexical]` instructions) if the value being stored is
already lexical.  Such moves are redundant.

rdar://99160718
2023-04-07 18:09:49 -07:00
Nate Chandler
3da0e6a6af [Mem2Reg] Doc'd function. 2023-04-07 18:09:16 -07:00
Nate Chandler
38cbc6fde1 [DCE] Destroys of live values are live.
As is done for `end_borrow`s, add a dependency from a `destroy_value`s
to its operand so that it is not eliminated if its operand isn't.
2023-04-06 13:43:57 -07:00
Nate Chandler
5f5692c3ba [Gardening] Separated debug output lines. 2023-04-06 13:35:01 -07:00
Adrian Prantl
158772c2ab Rebase SILScope generation on top of ASTScope.
This patch replaces the stateful generation of SILScope information in
SILGenFunction with data derived from the ASTScope hierarchy, which should be
100% in sync with the scopes needed for local variables. The goal is to
eliminate the surprising effects that the stack of cleanup operations can have
on the current state of SILBuilder leading to a fully deterministic (in the
sense of: predictible by a human) association of SILDebugScopes with
SILInstructions. The patch also eliminates the need to many workarounds. There
are still some accomodations for several Sema transformation passes such as
ResultBuilders, which don't correctly update the source locations when moving
around nodes. If these were implemented as macros, this problem would disappear.

This necessary rewrite of the macro scope handling included in this patch also
adds proper support nested macro expansions.

This fixes

rdar://88274783

and either fixes or at least partially addresses the following:

rdar://89252827
rdar://105186946
rdar://105757810
rdar://105997826
rdar://105102288
2023-04-04 15:20:11 -07:00
Nate Chandler
a25d56af7b [Mem2Reg] NFC: Removed passthrough function.
Just directly invoke the member function instead.
2023-04-02 20:29:13 -07:00
Nate Chandler
4198cc0b2a [Mem2Reg] Fix store_borrow user block omission.
Previously, when blocks were added to the worklist, only blocks which
were users of the `alloc_stack` instruction were considered.  For
"guaranteed alloc_stacks" (`store_borrow` locations), that resulted in
not processing blocks which contained uses of the `store_borrow` but not
the `alloc_stack`.  When such a user was an `end_borrow`, the effect was
that no `end_borrow` was created for the newly introduced
`begin_borrow [lexical]`.

Fix this by adding blocks with users of the `store_borrow` to the
worklist.
2023-03-31 18:43:48 -07:00
swift-ci
be620b8ada Merge pull request #64709 from meg-gupta/dcefix
Don't DCE @owned phis that may have escaped
2023-03-29 14:26:45 -07:00
Meghana Gupta
246e9c819b Don't DCE @owned phis that may have escaped 2023-03-29 11:38:13 -07:00
swift-ci
54862c1439 Merge pull request #64700 from meg-gupta/updatehaspointerescapedce
Support all BorrowedValueKind in hasPointerEscape(BorrowedValue) api
2023-03-29 00:36:03 -07:00
Meghana Gupta
a135f4fc50 Check lexicality at reborrow instead of borrow while disabling DCE 2023-03-28 20:31:32 -07:00
Meghana Gupta
b77a3f8a38 Use the updated hasPointerEscape api in DCE 2023-03-28 20:31:32 -07:00
eeckstein
85986f4e58 Merge pull request #64635 from eeckstein/fix-inline-always
PerformanceInliner:  protect against misuse of @inline(__always)
2023-03-28 16:24:12 +02:00
Konrad `ktoso` Malawski
0586c14b60 [Concurrency] SerialExecutor.isSameExclusiveExecutionContext (#64604) 2023-03-28 15:56:28 +09:00
Nate Chandler
1a7c4a4d12 [NFC] Renamed DestroyAddrHoisting.
It was previously named SSADestroyHoisting which is rather misleading
considering that it deals with addresses and hoists destroy_addrs.
2023-03-27 14:15:03 -07:00
Erik Eckstein
0a4b0a8da7 PerformanceInliner: protect against misuse of @inline(__always)
Inline-always should only be used on relatively small functions. It must not be used on recursive functions.
Add a check that prevents that inlining of large @inline(__always) functions.

https://github.com/apple/swift/issues/64319
rdar://106655649
2023-03-27 17:29:37 +02:00
Nate Chandler
4f0d1dab5e [CopyPropagation] Canonicalize copies of lexical.
Currently, CopyPropagation only canonicalizes defs that are "canonical",
that is, the root of the copy_value tree.  When that canonical
def is lexical, however, the canonicalization respects deinit barriers.
But copies of lexical values are not themselves lexical, so their
lifetimes can be shortened without respect to deinit barriers.

Here, immediate copies of lexical values are canonicalized before the
lexical values themselves are.

rdar://107197935
2023-03-27 07:08:01 -07:00
Nate Chandler
ec3f005f31 [CanonOSSALifetime] Run on lexical lifetimes.
Previously, the utility bailed out on lexical lifetimes because it
didn't respect deinit barriers.  Here, deinit barriers are found and
added to liveness if the value is lexical.  This enables copies to be
propagated without hoisting destroys over deinit barriers.

rdar://104630103
2023-03-25 21:17:26 -07:00
Nate Chandler
4d4042931b [Reachability] NFC: Allow more initial blocks.
Allow clients to specify any number (an array) of blocks beyond which
dataflow won't propagate rather than 1 or 0 (a pointer).
2023-03-25 12:27:57 -07:00
Andrew Trick
119e712c32 Merge pull request #64534 from atrick/liveblocks-bitfield
Cleanup PrunedLiveBlocks
2023-03-22 16:33:08 -07:00
Andrew Trick
15796e3ff9 PrunedLiveness: add a SILFunction argument
So that liveness can migrate to using a SILBitfield.
2023-03-22 01:36:48 -07:00
nate-chandler
cee389033d Merge pull request #64495 from nate-chandler/copy-propagation/canonicalize-move-source
[CopyPropagation] Canonicalize moved-from values.
2023-03-21 12:14:11 -07:00
Erik Eckstein
8c05024ea6 SIL: move the SILInstruction::MemoryBehavior enum out of SILInstruction into the swift namespace 2023-03-21 15:33:09 +01:00
Nate Chandler
6b1bee7324 [CopyPropagation] Canonicalize moved-from values.
If a move_value is determined to be redundant and removed, take the
opportunity its removal makes available to canonicalize the moved-from
value without the obstruction of the move_value.
2023-03-20 18:04:57 -07:00
Anthony Latsis
e8be44d14e Merge pull request #64324 from AnthonyLatsis/cse-open-exist
SILOptimizer: Fix some issues with CSE of `open_existential_ref`
2023-03-17 17:26:09 +03:00
nate-chandler
3644d98d5f Merge pull request #64400 from nate-chandler/copy-propagation/run-side-effect-analysis-first
CopyPropagation: Compute side-effects first.
2023-03-16 18:17:39 -07:00
nate-chandler
1f3623d570 Merge pull request #64339 from nate-chandler/copy-propagation/redundant-move-elim
[CopyPropagation] Eliminate redundant moves.
2023-03-16 17:02:25 -07:00
Nate Chandler
ade29db6bd CopyPropagation: Compute side-effects first.
Add a run of ComputeSideEffects before the first run of CopyPropagation.
Allow hoisting over applies of functions that are able to be analyzed
not to be deinit barriers at this early point.
2023-03-16 13:01:05 -07:00
nate-chandler
1208d32d80 Merge pull request #64356 from nate-chandler/rdar106224845
[Mem2Reg] Instantiate arbitrary empty types.
2023-03-16 10:56:23 -07:00
Nate Chandler
16216924b1 [CopyPropagation] Eliminate redundant moves.
SemanticARCOpts already eliminates move values that are redundant that
block its optimizations.  But it's always run after CopyPropagation.

Because move_values divide copy-extended lifetimes, move_values obstruct
lifetime canonicalization.  If a move_value isn't separating lifetimes
with different characteristics (specifically: lexicallity, escaping),
then it is only obstructing lifetime canonicalization.  Remove it
before canonicalizing the lifetime of the moved-from value.
2023-03-15 11:56:27 -07:00
Konrad `ktoso` Malawski
41f99fc2ae [Executors][Distributed] custom executors for distributed actor (#64237)
* [Executors][Distributed] custom executors for distributed actor

* harden ordering guarantees of synthesised fields

* the issue was that a non-default actor must implement the is remote check differently

* NonDefaultDistributedActor to complete support and remote flag handling

* invoke nonDefaultDistributedActorInitialize when necessary in SILGen

* refactor inline assertion into method

* cleanup

* [Executors][Distributed] Update module version for NonDefaultDistributedActor

* Minor docs cleanup

* we solved those fixme's

* add mangling test for non-def-dist-actor
2023-03-15 23:42:55 +09:00
Nate Chandler
e9294539f0 [NFC] Switched to StackList.
No need for a worklist of any sort, a simple list suffices.
2023-03-15 07:38:59 -07:00
Nate Chandler
e089e95d09 [Mem2Reg] Instantiate arbitrary empty types.
Currently, memory locations whose type is empty (`SILType::isEmpty`) are
regarded as viable sources for loads.

Previously, though, Mem2Reg only handled loads from empty types formed
only by tupling.  Here, support is added for types formed also by
struct'ing.  As before, this entails recursively instantiating the empty
types until reaching the innermost empty types (which aggregate nothing)
and then aggregating the resulting instances.

rdar://106224845
2023-03-14 10:54:22 -07:00
Anthony Latsis
d650ce47f3 SILOptimizer: Fix some issues with CSE of open_existential_ref
* A direct user might have a dependent result
* An indirect user can also be a terminator instruction
2023-03-13 21:41:02 +03:00
Erik Eckstein
96049626bc SILOptimizer: add complexity limit in ARCCodeMotion and DeadStoreElimination
Add an emergency exit to avoid bad compile time problems in rare corner cases.
The introduced limit is more than enough for "real world" code. Even large functions have < 100 locations.
But in some corner cases - especially in generated code - we can run into quadratic complexity for large functions without that limit.

Fixes a compile time problem.
Unfortunately I don't have isolated test cases for these problems.

rdar://106516360
2023-03-13 18:46:27 +01:00
Meghana Gupta
df90e2ac46 Don't DCE lexical phis with only destroy users 2023-03-10 00:27:48 -08:00
Erik Eckstein
b741aa0018 SILOptimizer: fix a stack overflow in DCE
For very large control flow graphs the markControllingTerminatorsLive can stack overflow.
Fix this by doing the work iteratively instead of recursively.

rdar://106198943
2023-03-08 12:20:45 +01:00
nate-chandler
ebdeecfe4d Merge pull request #64013 from nate-chandler/mandatory-generic-specializer/partial-apply-stack-discipline
[MandatoryGenericSpecializer] Fix stack nesting when lowering OSSA during inlining.
2023-03-02 06:58:37 -08:00
nate-chandler
7ba396a1cc Merge pull request #64005 from nate-chandler/cse/partial-apply-stack-discipline
[CSE] Stack nest at OSSA lowering after inlining.
2023-03-01 18:09:05 -08:00
Nate Chandler
1dda30e6ba [GenericSpecializer] Nest at inline+lower OSSA.
MandatoryGenericSpecializer inlines transparent functions that it
specializes.

Now that in OSSA `partial_apply [on_stack]`s are represented as owned
values rather than stack locations, it is possible for their destroys to
violate stack discipline.  A direct lowering of the instructions to
non-OSSA would violate stack nesting.

Previously, when inlining during MandatoryGenericSpecializer, it was
assumed that the callee maintained stack discipline.  And, when inlining
an OSSA function into a non-OSSA function, OSSA instructions were
lowered directly.  The result was that stack discipline would be
violated when directly lowering callees with `partial_apply [on_stack]`s
that violate stack discipline.

Here, when MandatoryGenericSpecializer inlines a specialized generic
function in OSSA form into a function lowered out of OSSA form, stack
nesting is fixed up.
2023-03-01 15:30:47 -08:00
Nate Chandler
1a2b781d3e [CSE] Stack nest at OSSA lowering after inlining.
CSE inlines a portion of lazy property getters.

Now that in OSSA `partial_apply [on_stack]`s are represented as owned
values rather than stack locations, it is possible for their destroys to
violate stack discipline.  A direct lowering of the instructions to
non-OSSA would violate stack nesting.

Previously, when inlining during CSE, it was assumed that the callee
maintained stack discipline.  And, when inlining an OSSA function into a
non-OSSA function, OSSA instructions were lowered directly.  The result
was that stack discipline could be violated when directly lowering
callees with `partial_apply [on_stack]`s that violate stack discipline
upon direct lowering.

Here, when CSE inlining a lazy property getter in OSSA form into a
function lowered out of OSSA form, stack nesting is fixed up.
2023-03-01 11:46:06 -08:00
Nate Chandler
a8c5d4e4ce [PerformanceInliner] Stack nest at OSSA lowering.
Now that in OSSA `partial_apply [on_stack]`s are represented as owned
values rather than stack locations, it is possible for their destroys to
violate stack discipline.  A direct lowering of the instructions to
non-OSSA would violate stack nesting.

Previously, when inlining, it was assumed that non-coroutine callees
maintained stack discipline.  And, when inlining an OSSA function into a
non-OSSA function, OSSA instructions were lowered directly.  The result
was that stack discipline could be violated.

Here, when inlining a function in OSSA form into a function lowered out
of OSSA form, stack nesting is fixed up.
2023-02-28 15:40:46 -08:00
Nate Chandler
32685ce68e [Inliner] Add per-inlining verification.
Previously, there was an -Xllvm option to verify after all inlining to a
particlar caller.  That makes it a chore to track down which apply's
inlining resulted in invalid code.  Here, a new option is added that
verifies after each run of the inliner.
2023-02-28 15:40:46 -08:00
Meghana Gupta
a0d1b08dd5 Ensure isEqual and getHashValue() are in sync with an invariant in CSE 2023-02-23 12:07:33 -08:00
swift-ci
4ab5024b3c Merge pull request #63791 from meg-gupta/csebug
Fix CSE `isEqual` and `HashVisitor` for escaped values
2023-02-23 03:54:38 -08:00
Meghana Gupta
619b4cd539 CSE: Don't look through ownership instructions for escaped values
CSE relies on OSSA RAUW for lifetime extension when replacing a redundant instruction.
OSSA RAUW however does not handle lifetime extension for escaped base values.
Values escape from ownership via pointer escape, bitwise escape, forwarding unowned operations
and have none or unowned ownership. For all such values do not look through ownership instructions
while determining equality. It is possible to CSE such values with equivalent operands, because the
operand use guarantees lifetime of the base operand.
2023-02-22 21:11:03 -08:00
Michael Gottesman
1dd896ded9 [move-only] Implement escaping closure semantics.
NOTE: A few of the test patterns need to be made better, but this patch series
is large enough, I want to get it into tree and iterate.
2023-02-20 11:04:21 -08:00
Michael Gottesman
f4e1b2a8f2 [move-only] Update SILGen/MoveCheckers so that vars are emitted in eagerly projected box form.
This is the first slice of bringing up escaping closure support. The support is
based around introducing a new type of SILGen VarLoc: a VarLoc with a box and
without a value. Because the VarLoc only has a box, we have to in SILGen always
eagerly reproject out the address from the box. The reason why I am doing this
is that it makes it easy for the move checker to distinguish in between
different accesses to the box that we want to check separately. As such every
time that we open the box, we insert a mark_must_check
[assignable_but_not_consumable] on that project. If allocbox_to_stack manages to
determine that the box can be stack allocated, we eliminate all of the
mark_must_check and place a new mark_must_check [consumable_and_assignable] on
the alloc_stack.  The end result is that we get the old model that we had before
and also can support escaping closures.
2023-02-20 11:04:21 -08:00
Michael Gottesman
ecb864c159 Merge pull request #63755 from gottesmm/pr-dac78af5673ab6d4a9bebea882b8440c37c9457c
[move-only] A few small changes in preparation for a larger patch
2023-02-18 17:03:50 -08:00
Michael Gottesman
969d776c15 [allocbox-to-stack] When we promote a heap -> stack of noncopyable type, move mark_must_check onto alloc_stack and always
ensure that we use consumable_to_assign.

What this patch is does is add an extra phase after alloc_box runs where we look
at uses of the alloc_stack and if we see any mark_must_check of any kind, we
delete them and rewrite a single mark_must_check [consumable_and_assignable] on
the alloc_stack and make all uses of the alloc_stack go through the
mark_must_check.

This has two effects:

1. In a subsequent PR when I add noncopyable semantics for escaping closures,
this will cause allocbox to stack to convert such boxes from having escaping
semantics to having non-escaping semantics. Escaping semantics means that we
always reproject out from the box and use mark_must_check
[assignable_but_not_consumable] (since we can't consume from the box, but can
assign to it). In contrast, non-escaping semantics means that the box becomes an
alloc_stack and we use the traditional var checker semantics. NOTE: We can do
this for lets represented as addresses and vars since the typechecker will
validate that the let is never actually written to even if at the SIL level we
would allow that.

2. In cases where we are implementing simple mark_must_check
[consumable_and_assignable] on one of the project_box and capture the box, we
used to have a problem where the direct box uses would be on the alloc_stack and
not go through the mark_must_check. Now, all uses after allocbox_to_stack occur
go through the mark_must_check. This is why I was able to remove instances of
the "compiler does not understand this pattern" errors... since the compiler
with this change can now understand them.
2023-02-18 12:38:38 -08:00