Commit Graph

79 Commits

Author SHA1 Message Date
Meghana Gupta
996fd8b978 Bail out from deleting a dead objection on seeing stores with lexical non-trivial source 2023-08-08 10:48:09 -07:00
Meghana Gupta
abdb9f0dba DeadObjectElimination: Handle allocating apply in ossa 2023-08-07 14:58:57 -07:00
Meghana Gupta
2831f2f528 Add findPointerEscape check on store source, before shortening its lifetime by inserting destroy at the store 2023-08-07 10:21:40 -07:00
Meghana Gupta
c3c78fa8f8 DeadObjectElimination: Handle alloc_ref in ossa 2023-08-07 10:21:40 -07:00
Meghana Gupta
f5c5c9e36b In non-ossa, ban non-trivial stores to alloc_ref's projections even the dtor is not inlined
There is no implementation to handle insertion of compensating releases of the non-trivial store's src for this case.
This never really happens, because destructor analysis is very limited and we end up banning alloc_ref with ref count instructions.
2023-08-07 10:21:40 -07:00
Meghana Gupta
768d98e1c4 Add a TODO in destructor analysis 2023-08-07 10:21:40 -07:00
Meghana Gupta
15e5364d25 DeadObjectElimination: Handle keypaths with non-trivial operands in OSSA 2023-08-07 10:21:40 -07:00
Meghana Gupta
41697b061c DeadObjectElimination: Handle non-trivial stores while processing alloc_stack 2023-08-07 10:21:40 -07:00
Erik Eckstein
5c5cd9f58e DeadObjectElimination: ignore begin_access and end_access instructions
Don't let access instructions prevent eliminating dead allocations

https://github.com/apple/swift/issues/66496
2023-06-14 07:17:56 +02:00
Erik Eckstein
2c1d48b69c SIL: add type-dependent operands to the keypath instruction
It's need to correctly maintain dependencies from an open-existential instruction to a `keypath` instruction which uses the opened type.
Fixes a SILVerifier crash.

rdar://105517521
2023-02-17 17:48:55 +01: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
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
8fd17764e4 DeadObjectElimination: fix a bug which caused wrong inserted release instructions.
This bug triggered a "instruction isn't dominated by its operand" verifier crash.
Or - if the verifier doesn't run - a crash later in IRGen.

rdar://94376582
2022-06-20 20:24:32 +02: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
Erik Eckstein
edc600f754 DeadObjectElimination: handle dead arrays for which the destructor is not inlined
So far, DeadObjectElimination could remove dead arrays if the destructor of the buffer is inlined and the "destroyArray" builtin is visible in the array's user list.
Now, don't rely of inlining the destructor, but instead extend the destructor analysis to find the "destroyArray".

https://bugs.swift.org/browse/SR-14774
rdar://79302972
2021-06-22 07:28:04 +02:00
Erik Eckstein
76ab1c37be DeadObjectElimination: use InstructionDeleter to solve the instruction iterator invalidation problem
This simplifies the instruction iteration in processFunction().
2021-06-03 17:20:56 +02:00
Andrew Trick
0f88e0f3cc Rewrite instruction deletion logic in many passes
Fix innumerable latent bugs with iterator invalidation and callback invocation.

Removes dead code earlier and chips away at all the redundant copies the compiler generates.
2021-06-02 07:38:27 -07:00
Erik Eckstein
4977850092 SIL: remove the notifyDeleteHandlers mechanism
It's not needed anymore with delayed instruction deletion.
It was used for two purposes:
1. For analysis, which cache instructions, to avoid dangling instruction pointers
2. For passes, which maintain worklists of instructions, to remove a deleted instructions from the worklist. This is now done by checking SILInstruction::isDeleted().
2021-05-26 21:57:54 +02:00
Erik Eckstein
5a7615444b DeadObjectAllocation: fix a use-after free crash
The optimization tried to optimized a keypath instruction which was already deleted in a previous iteration.

rdar://77180080
2021-04-29 18:59:12 +02:00
Erik Eckstein
028afc0fb2 DeadObjectElimination: delete dead arrays for which the "destroyArray" builtin is inlined.
This is needed for non-OSSA SIL: in case we see a destroyArray builtin, we can safely remove the otherwise dead array.
This optimization kicks in later in the pipeline, after array semantics are already inlined (for early SIL, DeadObjectElimination can remove arrays based on semantics).

rdar://73569282
https://bugs.swift.org/browse/SR-14100
2021-02-04 07:53:32 +01:00
Meghana Gupta
845e63f901 Support ownershipKind in SILSSAUpdater 2021-01-21 16:27:50 -08:00
Erik Eckstein
92ab19052a DeadObjectElimination: don't remove a dead alloc_ref which has a store to a non-trivial property.
In non-OSSA we cannot reliably track the lifetime of non-trivial stored properties, in case the deallocation is inlined.
Removing such a dead alloc_ref might leak a property value (or crash the compiler).

rdar://70689545
2020-12-11 17:26:51 +01:00
Andrew Trick
85ff15acd3 Add indexTrieRoot to the SILModule to share across Analyses.
...and avoid reallocation.

This is immediately necessary for LICM, in addition to its current
uses. I suspect this could be used by many passes that work with
addresses. RLE/DSE should absolutely migrate to it.
2020-10-16 15:00:09 -07:00
Andrew Trick
5ae231eaab Rename getFieldNo() to getFieldIndex().
Do I really need to justify this?
2020-09-24 22:44:13 -07:00
Michael Gottesman
d064241599 [ssa-updater] Modernize style before adding support for guaranteed parameters.
Specifically:

1. I made methods, variables camelCase.
2. I expanded out variable names (e.x.: bb -> block, predBB -> predBlocks, U -> wrappedUse).
3. I changed typedef -> using.
4. I changed a few c style for loops into for each loops using llvm::enumerate.

NOTE: I left the parts needed for syncing to LLVM in the old style since LLVM
needs these to exist for CRTP to work correctly for the SILSSAUpdater.
2020-08-06 15:41:00 -07:00
Erik Eckstein
3f42ad704c DeadObjectElimination: don't let fix_lifetime prevent dead array elimination 2020-05-26 18:01:17 +02:00
Erik Eckstein
2403e56eb5 SIL: new "array.end_mutation" and "array.finalize_intrinsic" array semantics
Used to "finalize" an array literal. It's not used, yet. So this is NFC.
Also handle the "array.finalize_intrinsic" function in various array specific optimizations.
2020-05-26 18:01:17 +02:00
Erik Eckstein
cceb2a4b66 DeadObjectElimination: reuse code
NFC
2020-05-14 14:38:44 +02:00
Erik Eckstein
93d3226790 DeadObjectElimination: handle init_existential_addr instructions.
This allows to eliminate a dead stack location which contains an existential.

rdar://problem/32272199
2020-02-18 19:23:17 +01:00
Ravi Kandhadai
a6bed21d9e [SIL Optimization] Make ArraySemantics.cpp aware of "array.uninitialized_intrinsic"
semantics attribute that is used by the top-level array initializer (in ArrayShared.swift),
which is the entry point used by the compiler to initialize array from array literals.
This initializer is early-inlined so that other optimizations can work on its body.

Fix DeadObjectElimination and ArrayCOWOpts optimization passes to work with this
semantics attribute in addition to "array.uninitialized", which they already use.

Refactor mapInitializationStores function from ArrayElementValuePropagation.cpp to
ArraySemantic.cpp so that the array-initialization pattern matching functionality
implemented by the function can be reused by other optimizations.
2020-02-05 14:28:34 -08: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
Erik Eckstein
5f8a5054c3 DeadObjectElimination: remove dead keypath instructions 2019-05-21 09:44:59 -07:00
Slava Pestov
8915f96e3e SIL: Replace SILType::isTrivial(SILModule) with isTrivial(SILFunction) 2019-03-12 01:16:04 -04: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
Erik Eckstein
36d3311c9a DeadObjectElimination: enable removal of dead alloc_stack locations which contain a non-payload resilient enum case
If the enum does not have a payload, i.e. there is no init_enum_data_addr involved, we can remove the alloc_stack (if there is no read from it).
2018-12-10 16:14:15 -08:00
Michael Gottesman
c9bb5161a1 [ownership] Change SILUndef to return Any ownership for trivial values and owned for non-trivial values.
This is in preparation for verifying that when ownership verification is enabled
that only enums and trivial values can have any ownership. I am doing this in
preparation for eliminating ValueOwnershipKind::Trivial.

rdar://46294760
2018-11-27 17:31:08 -08:00
Jordan Rose
de7b8ff071 Replace 'delete's with std::unique_ptr throughout SILOptimizer 2018-09-18 09:44:01 -07:00
Erik Eckstein
99a9ed5535 SIL: remove the pinning instructions: strong_pin, strong_unpin, is_unique_or_pinned
They are not used anymore after removing the pinning addressors.
2018-08-23 12:47:56 -07:00
Bob Wilson
8e330ee344 NFC: Fix indentation around the newly renamed LLVM_DEBUG macro.
Jordan used a sed command to rename DEBUG to LLVM_DEBUG. That caused some
lines to wrap and messed up indentiation for multi-line arguments.
2018-07-21 00:56:18 -07: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
80a734ab30 DeadObjectElimination: handle objects for which the destructor is de-virtualized and inlined
Also: add an additional DeadObjectElimination pass in the low level pipeline because
redundant load elimination (which runs before) can turn an object into a dead object.
2018-01-19 11:33:26 -08:00
eeckstein
b126b62256 Revert "Optimization changes to completely fold OptionSet literals" 2018-01-18 22:05:07 -08:00
Erik Eckstein
442171bca6 DeadObjectElimination: handle objects for which the destructor is de-virtualized and inlined
Also: add an additional DeadObjectElimination pass in the low level pipeline because
redundant load elimination (which runs before) can turn an object into a dead object.
2018-01-18 18:27:17 -08:00
Michael Gottesman
ecc1ed4589 [dead-array] Handle initialization where we pass in an alloc_ref/apply in a +0 context.
rdar://34222540
2018-01-07 00:13:38 -08: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
Erik Eckstein
6377cc095a SIL: Replace TransitivelyUnreachableBlocks with DeadEndBlocks
We had both utilities doing the same thing.
NFC
2017-07-24 09:50:42 -07:00
Erik Eckstein
a0e6082d25 SILOptimizer: change the way how ValueLifetimeAnalysis handles dead-end (unreachable) CFG paths.
In dead-array elimination we assume that the array allocation is post-dominated by all its final releases.
The only exception are branches to dead-end ("unreachable") blocks. So we just ignored all paths which didn't end up in a final release.
Now we explicitly pass the set of dead-end blocks and just ignore those blocks.
This is safer and it's also needed in the upcoming re-write of StackPromotion.
2017-07-21 10:46:03 -07:00
Devin Coughlin
2896d5b93f [SIL Utils] Move IndexTrieNode into its own header in Utils. NFC.
Move IndexTrieNode from DeadObjectElimination into its own header. I plan to
use this data structure when diagnosing static violations of exclusive access.
2017-06-14 21:23:14 -07: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