Commit Graph

112 Commits

Author SHA1 Message Date
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
Michael Gottesman
6df5462ee2 [sil] Add support for multiple value instructions by adding MultipleValueInstruction{,Result}.
rdar://31521023
2017-10-24 18:36:37 -07:00
John McCall
ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00
practicalswift
492f5cd35a [gardening] Remove redundant repetition of type names (DRY): RepeatedTypeName foo = dyn_cast<RepeatedTypeName>(bar)
Replace `NameOfType foo = dyn_cast<NameOfType>(bar)` with DRY version `auto foo = dyn_cast<NameOfType>(bar)`.

The DRY auto version is by far the dominant form already used in the repo, so this PR merely brings the exceptional cases (redundant repetition form) in line with the dominant form (auto form).

See the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es11-use-auto-to-avoid-redundant-repetition-of-type-names) for a general discussion on why to use `auto` to avoid redundant repetition of type names.
2017-05-05 09:45:53 +02:00
practicalswift
5e255e07d7 [gardening] Remove redundant logic 2017-04-11 23:04:55 +02:00
Andrew Trick
be1881aa1f Remove redundant Transform.getName() definitions.
At some point, pass definitions were heavily macro-ized. Pass
descriptive names were added in two places. This is not only redundant
but a source of confusion. You could waste a lot of time grepping for
the wrong string. I removed all the getName() overrides which, at
around 90 passes, was a fairly significant amount of code bloat.

Any pass that we want to be able to invoke by name from a tool
(sil-opt) or pipeline plan *should* have unique type name, enum value,
commend-line string, and name string. I removed a comment about the
various inliner passes that contradicted that.

Side note: We should be consistent with the policy that a pass is
identified by its type. We have a couple passes, LICM and CSE, which
currently violate that convention.
2017-04-09 15:20:28 -07:00
Joe Shajrawi
1f626304f1 Add support for conditional checked cast instruction for opaque value types + SILGen support for it 2017-03-06 16:35:27 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Michael Gottesman
19f0f6e686 [semantic-sil] Reify the split in SILArgument in between function and block arguments via subclasses.
For a long time, we have:

1. Created methods on SILArgument that only work on either function arguments or
block arguments.
2. Created code paths in the compiler that only allow for "function"
SILArguments or "block" SILArguments.

This commit refactors SILArgument into two subclasses, SILPHIArgument and
SILFunctionArgument, separates the function and block APIs onto the subclasses
(leaving the common APIs on SILArgument). It also goes through and changes all
places in the compiler that conditionalize on one of the forms of SILArgument to
just use the relevant subclass. This is made easier by the relevant APIs not
being on SILArgument anymore. If you take a quick look through you will see that
the API now expresses a lot more of its intention.

The reason why I am performing this refactoring now is that SILFunctionArguments
have a ValueOwnershipKind defined by the given function's signature. On the
other hand, SILBlockArguments have a stored ValueOwnershipKind. Rather than
store ValueOwnershipKind in both instances and in the function case have a dead
variable, I decided to just bite the bullet and fix this.

rdar://29671437
2016-12-18 01:11:28 -08:00
Michael Gottesman
38ec08f45f [gardening] Standardize SILBasicBlock successor/predecessor methods that deal with blocks rather than the full successor data structure to have the suffix 'Block'.
This was already done for getSuccessorBlocks() to distinguish getting successor
blocks from getting the full list of SILSuccessors via getSuccessors(). This
commit just makes all of the successor/predecessor code follow that naming
convention.

Some examples:

getSingleSuccessor() => getSingleSuccessorBlock().
isSuccessor() => isSuccessorBlock().
getPreds() => getPredecessorBlocks().

Really, IMO, we should consider renaming SILSuccessor to a more verbose name so
that it is clear that it is more of an internal detail of SILBasicBlock's
implementation rather than something that one should consider as apart of one's
mental model of the IR when one really wants to be thinking about predecessor
and successor blocks. But that is not what this commit is trying to change, it
is just trying to eliminate a bit of technical debt by making the naming
conventions here consistent.
2016-11-27 12:32:51 -08:00
Michael Gottesman
96837babda Merge pull request #5920 from gottesmm/vacation_gardening
Vacation gardening
2016-11-25 09:17:21 -06:00
Michael Gottesman
bf6920650c [gardening] Drop BB from all argument related code in SILBasicBlock.
Before this commit all code relating to handling arguments in SILBasicBlock had
somewhere in the name BB. This is redundant given that the class's name is
already SILBasicBlock. This commit drops those names.

Some examples:

getBBArg() => getArgument()
BBArgList => ArgumentList
bbarg_begin() => args_begin()
2016-11-25 01:14:36 -06:00
practicalswift
797b80765f [gardening] Use the correct base URL (https://swift.org) in references to the Swift website
Remove all references to the old non-TLS enabled base URL (http://swift.org)
2016-11-20 17:36:03 +01:00
practicalswift
5a3067e24e [gardening] Fix plural issues. 2016-05-21 18:45:31 +02:00
practicalswift
fa1d5d231a [gardening] Fix recently introduced typo: "althouth" → "although" 2016-04-01 23:14:16 +02:00