Commit Graph

76 Commits

Author SHA1 Message Date
Meghana Gupta
0c29ebb57d Fix typo 2023-01-08 00:15:17 -08:00
Meghana Gupta
cdeb55a20a Fix DCE of begin_borrow with @guaranteed operand
For the lower most begin_borrows with @guaranteed operands, there
was no @guaranteed phi computation, restructure the code and fix this case.
2023-01-06 09:23:42 -08:00
Nate Chandler
e1cb0b5522 [MemAccessUtils] Look thru nested for guar roots.
Previously, findGuaranteedReferenceRoots always stopped searching when
finding a begin_borrow, because it's not an ownership-forwarding
instruction.  Here, it is conditionally allowed to keep search through
the borrowee of that begin_borrow if it itself is guaranteed.
2022-12-08 18:29:14 -08: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
Meghana Gupta
d6399e2626 Don't generate end_borrow for GuaranteedForwardingPhi in DCE 2022-10-21 11:53:50 -07:00
Meghana Gupta
5ede08ca3c Update DCE for @guaranteed forwarding phi support 2022-10-19 19:54:28 -07:00
Meghana Gupta
a1bcf17b26 Avoid optimizing lexical borrow scopes in DCE 2022-09-15 16:42:23 -07:00
Meghana Gupta
6c0c3dd1e1 Rename hasEscaped -> hasPointerEscape, and don't consider OperandOwnership::BitwiseEscape as a pointer escape 2022-09-15 16:40:39 -07:00
Meghana Gupta
88782ac939 Don't shrink escaped borrow scopes in DCE 2022-09-14 21:02:02 -07:00
Michael Gottesman
1e6187c4f4 [sil] Update all usages of old API SILValue::getOwnershipKind() in favor of new ValueBase::getOwnershipKind().
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.
2022-07-26 11:46:23 -07:00
Erik Eckstein
777b42180d SILOptimizer: use the new set data structures in various optimizations 2022-07-13 14:27:50 +02:00
Andrew Trick
2fd4de411e [SIL-opaque] Removed [Unconditional]CheckedCastValue 2022-03-22 17:04:13 -07:00
Andrew Trick
83b01d8ebe Improve the SILPhiArgument API
This subclass of SILArgument should be eliminated--it's not always a
phi, and whether it is a "phi argument" has nothing whatsoever to do
with the opcode. That is a property of a value's uses, not a property of the
value.

Until then, provide a logical and useful API within the type. This
often avoids the need to explicitly cast to a SILPhiArgument type and
avoids a lot of boilerplate in code that deals with phis.

Note: PhiOperand and PhiValue are improved abstractions on top of this
API. But the SILArgument-level API is still an important bridge
between SILArgument and other phi abstractions.
2022-02-15 13:28:46 -08:00
Nate Chandler
e3fbadf7b7 [SILOptimizer] Let visitTransitiveEndBorrows take SILValues.
Previously, visitTransitiveEndBorrows took BorrowedValues.  However,
there is at least one kind of borrow--namely,
unchecked_ownership_conversion insts--that is not currently permitted by
the BorrowedValue API.  The long term fix is to make BorrowedValue
handle such instructions.  For now, change visitTransitiveEndBorrows to
take SILValues so that unchecked_ownership_conversion can be passed to
the API.

rdar://87985420
2022-01-25 15:55:08 -08:00
Andrew Trick
a50108ff46 Fix a debug location in DCE.
Fixes SR-15300: Compiler crash when using Builtin.unreachable in
initializers

Otherwise, this triggers an debug info verification assert that
invalid locations must only be on unreachable instructions.

This is why generating lifetime cleanup code should never inherit its
location from its insertion point.
2021-12-13 21:35:14 -08:00
Nate Chandler
0a18c62783 [DCE] Keep outer borrows alive when reborrowing.
Previously, when encountering a borrow of a guaranteed value, the
end_borrows of that reborrow were marked alive.  Only doing that enables
end_borrows of the outer borrow scope can be marked as dead.  The result
is that uses of the reborrowed value (including its end_borrow) can
outstrip the outer borrow scope, which is illegal.

Here, the outer borrow scope's end_borrows are marked alive.  To do
that, the originally borrowed values have to be identified via
findGuaranteedReferenceRoots.
2021-10-27 13:55:08 -07:00
Nate Chandler
30a159b1be [NFC] Used already cast value. 2021-10-27 10:44:33 -07:00
Nate Chandler
4d92cceda7 [DCE] Tweaked code to end borrows before destroys.
If a phi argument is dead and it reborrowing it was dependent on some
other value, that other value on which it was dependent may have already
itself been deleted.  In that case, the destroy_value would have been
added just before the terminator of the predecessors of the block which
contained the dead phi.  So, when deciding where to insert the
end_borrow, iterate backwards from the end of the block, skipping the
terminator updating the insertion point every time a destroy_value
instruction is encountered until we hit an instruction with a different
opcode.  This ensures that no matter how many destroy_values may have
been added just before the terminator, the end_borrow will preceed them.

This commit just tweaks the preexisting logic that checked for this
condition.  Specifically, the previous code didn't handle the case where
the block contains only a terminator and a destroy_value.
2021-10-19 12:05:38 -07:00
Min-Yih Hsu
343d842394 [SIL][DebugInfo] PATCH 3/3: Deprecate debug_value_addr SIL instruciton
This patch removes all references to DebugValueAddrInst class and
debug_value_addr instruction in textual SIL files.
2021-08-31 12:01:04 -07:00
Min-Yih Hsu
9a8f2ed642 [SILOptimizer][DebugInfo] Preliminary support for DIExpression in SROA and Mem2Reg
SROA and Mem2Reg now can leverage DIExpression -- op_fragment, more
specifically -- to generate correct debug info for optimized SIL. Some
important highlights:
 - The new swift::salvageDebugInfo, similar to llvm::salvageDebugInfo,
   tries to restore / transfer debug info from a deleted instruction.
   Currently I only implemented this for store instruction whose
   destination is an alloc_stack value.
 - Since we now have source-variable-specific SIL location inside a
   `debug_value` instruction (and its friends), this patch teaches
   SILCloner and SILInliner to remap the debug scope there in addition
   to debug scope of the instruction.
 - DCE now does not remove `debug_value` instruction whose associating
   with a function argument SSA value that is not used elsewhere. Since
   that SSA value will not disappear so we should keep the debug info.
2021-08-05 17:27:45 -07:00
Meghana Gupta
0d16eda695 Add support for end_lifetime in DCE 2021-07-08 13:53:03 -07:00
Erik Eckstein
4affa11604 OwnershipUtils: let visitTransitiveEndBorrows work with a BorrowedValue.
... and not only with a begin_borrow
2021-05-18 08:56:22 +02:00
Andrew Trick
f470b29747 Disable fix_lifetime DCE.
Unless the type is a trivial scalar. As a follow-up we could try to
prove that the referenced object is unique, but that seems more
natural for DeadObjectElimination.

This optimization was never correct because references may alias. See
rdar://36038096 ([SR-6608] DeadCodeElimination removes fix_lifetime
instructions.)

Fixes rdar://74759728 (The compiler/optimizer seems to be shortening
the lifetime too early)
2021-02-26 11:06:10 -08:00
Erik Eckstein
fe10f98cf0 SIL: rename the SILBitfield.h header file to BasicBlockBits.h
NFC
2021-02-12 11:15:55 +01:00
Meghana Gupta
d3acfee433 When DCE removes a dead terminator, insert appropriate lifetime ends 2021-02-03 11:38:43 -08:00
Meghana Gupta
a78acfe4b0 Disable handling of nested borrows in DCE
Nested borrow handling can be complex in the presence of reborrows. So
it is not handled currently.
2021-02-03 11:38:40 -08:00
Meghana Gupta
234d29ab51 Insert end_borrow before any destroy_value while ending lifetime of a reborrow with dependencies 2021-02-03 11:38:11 -08:00
Meghana Gupta
180b3bdcca Add reborrow dependencies to DCE
A reborrow's base value may change if the base value is also passed as
an operand on a branch. Record reborrow dependencies so that we can mark
the base value as live, if the reborrow was also live. This ensures we
do not insert destroy_value on the base value prematurely before the
lifetime of the reborrow ends.
2021-02-03 11:38:11 -08:00
Meghana Gupta
df82a1a92c Allow DCE of load [copy] 2021-02-02 14:01:37 -08:00
Erik Eckstein
bb7844cd6b DeadCodeElimination: a small cleanup
Split `markValueLive(SILNode *)` into `markValueLive(SILValue)` and `markInstructionLive(SILInstruction*)`
2021-01-27 16:40:14 +01:00
Erik Eckstein
4d61dad616 DeadCodeElimination: Make DCE a separate class, called by DCEPass::run().
Instead of manually managing the internal state of the pass.
Also, use BasicBlockSet instead of SmallPtrSet.
2021-01-27 10:31:17 +01:00
Eric Miotto
8e7f9c9cbd Revert "SIL: let SingleValueInstruction only inherit from a single SILNode." 2021-01-26 10:02:24 -08:00
Meghana Gupta
45e210bc2f Merge pull request #35591 from meg-gupta/fixdcebug
Use erasePhiArgument instead of eraseArgument in DCE
2021-01-25 19:39:39 -08:00
Meghana Gupta
c63a1c0bdf Use erasePhiArgument instead of eraseArgument in DCE
Fixes rdar://73500476
2021-01-25 13:00:55 -08:00
Erik Eckstein
ff1991740a SIL: let SingleValueInstruction only inherit from a single SILNode.
This removes the ambiguity when casting from a SingleValueInstruction to SILNode, which makes the code simpler. E.g. the "isRepresentativeSILNode" logic is not needed anymore.
Also, it reduces the size of the most used instruction class - SingleValueInstruction - by one pointer.

Conceptually, SILInstruction is still a SILNode. But implementation-wise SILNode is not a base class of SILInstruction anymore.
Only the two sub-classes of SILInstruction - SingleValueInstruction and NonSingleValueInstruction - inherit from SILNode. SingleValueInstruction's SILNode is embedded into a ValueBase and its relative offset in the class is the same as in NonSingleValueInstruction (see SILNodeOffsetChecker).
This makes it possible to cast from a SILInstruction to a SILNode without knowing which SILInstruction sub-class it is.
Casting to SILNode cannot be done implicitly, but only with an LLVM `cast` or with SILInstruction::asSILNode(). But this is a rare case anyway.
2021-01-25 09:30:04 +01:00
Erik Eckstein
baab92345c DeadCodeElimination: a small cleanup
Split `markValueLive(SILNode *)` into `markValueLive(SILValue)` and `markInstructionLive(SILInstruction*)`
2021-01-25 09:30:04 +01:00
Meghana Gupta
341facf0b3 Replace some instances of check isTrivial with check OwnershipKind::None 2021-01-21 16:27:40 -08:00
Meghana Gupta
f2760bbea3 Enable DCE on OSSA 2021-01-21 11:12:00 -08:00
Joe Groff
a664a33b52 SIL: Add instructions to represent async suspend points.
`get_async_continuation[_addr]` begins a suspend operation by accessing the continuation value that can resume
the task, which can then be used in a callback or event handler before executing `await_async_continuation` to
suspend the task.
2020-10-01 14:21:52 -07:00
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
zoecarver
e22e7bcb20 [LVA] Support access instructions in DCE.
Simple check for the following pattern:
x = begin_access
end_access x
2020-05-11 23:18:00 -07:00
Erik Eckstein
380db3761a DeadCodeElimination: replace recursive post-dominator walks with iterative worklist algorithms.
This fixes stack-overflow crashes when compiling large functions.

rdar://problem/56268570
2020-04-08 11:46:51 +02:00
Slava Pestov
efe4883eef SILOptimizer: Fix to deal with casts involving dynamic Self
The cast optimizer was too eager to fold casts where the source and
target lowered types were the same, even though the formal types
might be different. Move the classifyFeasibility() check to deal
with this case.

Also in dead code elimination we have to mark all operands of a
cast branch instruction as live, not just the first operand,
otherwise we miss the special 'type dependent' self metadata
operand and replace it with 'undef'.
2019-11-22 16:39:17 -05:00
Andrew Trick
bddc69c8a6 Organize SILOptimizer/Utils headers. Remove Local.h.
The XXOptUtils.h convention is already established and parallels
the SIL/XXUtils convention.

New:
- InstOptUtils.h
- CFGOptUtils.h
- BasicBlockOptUtils.h
- ValueLifetime.h

Removed:
- Local.h
- Two conflicting CFG.h files

This reorganization is helpful before I introduce more
utilities for block cloning similar to SinkAddressProjections.

Move the control flow utilies out of Local.h, which was an
unreadable, unprincipled mess. Rename it to InstOptUtils.h, and
confine it to small APIs for working with individual instructions.
These are the optimizer's additions to /SIL/InstUtils.h.

Rename CFG.h to CFGOptUtils.h and remove the one in /Analysis. Now
there is only SIL/CFG.h, resolving the naming conflict within the
swift project (this has always been a problem for source tools). Limit
this header to low-level APIs for working with branches and CFG edges.

Add BasicBlockOptUtils.h for block level transforms (it makes me sad
that I can't use BBOptUtils.h, but SIL already has
BasicBlockUtils.h). These are larger APIs for cloning or removing
whole blocks.
2019-10-02 11:34:54 -07:00
Slava Pestov
c791c4a137 SIL: SILUndef must be aware of the resilience expansion
The ownership kind is Any for trivial types, or Owned otherwise, but
whether a type is trivial or not will soon depend on the resilience
expansion.

This means that a SILModule now uniques two SILUndefs per type instead
of one, and serialization uses two distinct sentinel IDs for this
purpose as well.

For now, the resilience expansion is not actually used here, so this
change is NFC, other than changing the module format.
2019-03-12 00:30:35 -04:00
Michael Gottesman
d78e83c010 [ownership] Do some preliminary work for moving OME out of the diagnostics pipeline.
This disables a bunch of passes when ownership is enabled. This will allow me to
keep transparent functions in ossa and skip most of the performance pipeline without
being touched by passes that have not been updated for ownership.

This is important so that we can in -Onone code import transparent functions and
inline them into other ossa functions (you can't inline from ossa => non-ossa).
2019-01-31 13:38:05 -08:00
Jordan Rose
cefb0b62ba Replace old DEBUG macro with new LLVM_DEBUG
...using a sed command provided by Vedant:

$ find . -name \*.cpp -print -exec sed -i "" -E "s/ DEBUG\(/ LLVM_DEBUG(/g" {} \;
2018-07-20 14:37:26 -07:00
Erik Eckstein
649c2d0664 dead code elimination: Fixed a crash when trying to get the immediate post-dominating block in an infinite loop.
SR-7805
rdar://problem/40650953
2018-05-30 13:02:20 -07:00
John McCall
3c54c0edfc IRGen and basic optimizer support for coroutines. 2018-01-09 11:35:09 -05:00
John McCall
14d6390352 Add "yield" and "unwind" instructions to SIL. 2017-11-07 03:51:54 -05:00