Commit Graph

316 Commits

Author SHA1 Message Date
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
Andrew Trick
5826e75b00 Generalize the MemAccessUtils API.
For use outside access enforcement passes.

Add isUniquelyIdentifiedAfterEnforcement.

Rename functions for clarity and generality.

Rename isUniquelyIdentifiedOrClass to isFormalAccessBase.

Rename findAccessedStorage to identifyFormalAccess.

Rename findAccessedStorageNonNested to findAccessedStorage.

Part of generalizing the utility for use outside the access
enforcement passes.
2020-07-17 10:13:20 -07:00
Erik Eckstein
71a642e51b stdlib, SIL optimizer: use the SIL copy-on-write representation in the Array types.
Use the new builtins for COW representation in Array, ContiguousArray and ArraySlice.
The basic idea is to strictly separate code which mutates an array buffer from code which reads from an array.
The concept is explained in more detail in docs/SIL.rst, section "Copy-on-Write Representation".

The main change is to use beginCOWMutation() instead of isUniquelyReferenced() and insert endCOWMutation() at the end of all mutating functions. Also, reading from the array buffer must be done differently, depending on if the buffer is in a mutable or immutable state.

All the required invariants are enforced by runtime checks - but only in an assert-build of the library: a bit in the buffer object side-table indicates if the buffer is mutable or not.

Along with the library changes, also two optimizations needed to be updated: COWArrayOpt and ObjectOutliner.
2020-06-08 15:02:22 +02:00
Erik Eckstein
1559fe333f SIL: a new library intrinsic to "finalize" array literals
For COW support in SIL it's required to "finalize" array literals.
_finalizeUninitializedArray is a compiler known stdlib function which is called after all elements of an array literal are stored.
This runtime function marks the array literal as finished.

  %uninitialized_result_tuple = apply %_allocateUninitializedArray(%count)
  %mutable_array = tuple_extract %uninitialized_result_tuple, 0
  %elem_base_address = tuple_extract %uninitialized_result_tuple, 1
  ...
  store %elem_0 to %elem_addr_0
  store %elem_1 to %elem_addr_1
  ...
  %final_array = apply %_finalizeUninitializedArray(%mutable_array)

In this commit _finalizeUninitializedArray is still a no-op because the COW support is not used in the Array implementation yet.
2020-06-08 10:24:29 +02:00
Anthony Latsis
267e32dcd8 Merge pull request #32118 from AnthonyLatsis/post-increment-cleanup
[NFC] Pre- increment and decrement where possible
2020-06-02 20:10:29 +03:00
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
Varun Gandhi
c14e934563 [NFC] Remove redundant includes for llvm/ADT/SmallSet.h. 2020-05-31 13:07:45 -07: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
Saleem Abdulrasool
cebe79d482 SIL: use object libraries instead of globbing
This simplifies the handling of the subdirectories in the SIL and
SILOptimizer paths.  Create individual libraries as object libraries
which allows the analysis of the source changes to be limited in scope.
Because these are object libraries, this has 0 overhead compared to the
previous implementation.  However, string operations over the filenames
are avoided.  The cost for this is that any new sub-library needs to be
added into the list rather than added with the special local function.
2020-05-18 18:56:34 +00:00
Erik Eckstein
ba4da8e0d3 LICM: enable more stores to moved out of a loop
Even if a store is not dominating the loop exits, it makes sense to move it out of the loop if the pre-header also as a store to the same memory location.
When this is done, dead-store-elimination can then most likely remove the store in the pre-header.
2020-05-18 15:31:34 +02:00
Erik Eckstein
54e54ae4fe COWArrayOpts: fix a mis-compile related to owned function arguments
COWArrayOpts wrongly assumed that an 'owned' argument is released in the function.

https://bugs.swift.org/browse/SR-12440
rdar://problem/62201043
2020-05-04 17:30:40 +02:00
Andrew Trick
1c12de3241 Fix LICM combined load/store hoisting/sinking optimization.
This loop optimization hoists and sinks a group of loads and stores to
the same address.

Consider this SIL...

PRELOOP:
  %stackAddr = alloc_stack $Index
  %outerAddr1 = struct_element_addr %stackAddr : $*Index, #Index.value
  %innerAddr1 = struct_element_addr %outerAddr1 : $*Int, #Int._value

  %outerAddr2 = struct_element_addr %stackAddr : $*Index, #Index.value
  %innerAddr2 = struct_element_addr %outerAddr2 : $*Int, #Int._value

LOOP:
  %_ = load %innerAddr2 : $*Builtin.Int64
  store %_ to %outerAddr2 : $*Int
  %_ = load %innerAddr1 : $*Builtin.Int64

There are two bugs:

1) LICM miscompiles code during combined load/store hoisting and sinking.

When the loop contains an aliasing load from a difference projection
value, the optimization sinks the store but never replaces the
load. At runtime, the load reads a stale value.

FIX: isOnlyLoadedAndStored needs to check for other load instructions
before hoisting/sinking a seemingly unrelated set of
loads/stores. Checking side effect instructions is insufficient. The
same bug could happen with stores, which also do not produce side
effects.

Fixes <rdar://61246061> LICM miscompile:
Combined load/store hoisting/sinking with aliases

2) The LICM algorithm is not robust with respect to address projection
   because it identifies a projected address by its SILValue. This
   should never be done! It is trivial to represent a project path
   using an IndexTrieNode (there is also an abstraction called
   "ProjectionPath", but it should _never_ actually be stored by an
   analysis because of the time and space complexity of doing so).

The second bug is not necessary to fix for correctness, so will be
fixed in a follow-up commit.
2020-04-03 08:25:20 -07:00
Andrew Trick
73ee38c162 Add tracing to LICM for reloaded store/restored load optimization. 2020-04-03 08:25:20 -07:00
Erik Eckstein
287619445b LoopRotate: limit the size of the block to be duplicated.
This avoids significant code size regressions if the loop block to be duplicated is very large.

Also remove the ShouldRotate option. It's not needed anymore as disabling the pass can be done by -sil-disable-pass.

rdar://problem/33970453
2020-04-01 10:02:43 +02:00
Erik Eckstein
3ad7d548c2 LICM: hoist calls to global_init functions
Global initializers are executed only once.
Therefore it's possible to hoist such an initializer call to a loop pre-header - in case there are no conflicting side-effects in the loop before the call.
Also, the call must post-dominate the loop pre-header. Otherwise it would be executed speculatively.
2020-03-23 16:08:56 +01:00
Fred Riss
259d78a350 Adapt to llvm.org StringRef API change 2020-03-13 19:08:22 +01:00
swift-ci
e7e6d27ac9 Merge remote-tracking branch 'origin/master' into master-rebranch 2020-02-08 10:24:29 -08:00
Ravi Kandhadai
ec9844b2d9 [SIL Optimization] Add a new mandatory pass for unrolling forEach
calls over arrays created from array literals. This enables optimizing
further the output of the OSLogOptimization pass, and results in
highly-compact and optimized IR for calls to the new os log API.

<rdar://58928427>
2020-02-07 20:06:29 -08:00
swift-ci
70ebdb7629 Merge remote-tracking branch 'origin/master' into master-rebranch 2020-02-05 17:44:45 -08: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
swift-ci
fa7f0b9c2e Merge remote-tracking branch 'origin/master' into master-rebranch 2020-02-03 10:02:55 -08:00
Meghana Gupta
fbc8457f2d Add profitability check to array-property-opt (#29236)
* Add profitability check to array-property-opt

This change adds additional heuristics to array-property-opt to avoid
code size increase in cases where the optimization may not be
beneficial. With this change, we do not specialize a loop if it has any
opaque function calls or the instruction count exceeds a predefined threshold.
2020-02-03 09:59:04 -08:00
swift-ci
dd37d48671 Merge remote-tracking branch 'origin/master' into master-rebranch 2020-01-29 12:23:56 -08:00
Andrew Trick
17d9d20275 Improve one of the comments in COWArrayOpts. 2020-01-29 10:24:28 -08:00
swift_jenkins
47af5bcec0 Merge remote-tracking branch 'origin/master' into master-next 2019-12-18 17:39:43 -08:00
Ravi Kandhadai
935686460c [SIL Optimization] Create a new utility InstructionDeleter to delete instructions
and eliminate dead code. This is meant to be a replacement for the utility:
recursivelyDeleteTriviallyDeadInstructions. The new utility performs more aggresive
dead-code elimination for ownership SIL.

This patch also migrates most non-force-delete uses of
recursivelyDeleteTriviallyDeadInstructions to the new utility.
and migrates one force-delete use of recursivelyDeleteTriviallyDeadInstructions
(in IRGenPrepare) to use the new utility.
2019-12-18 13:17:17 -08:00
Joe Groff
fb34044408 Merge remote-tracking branch 'origin/master' into master-next 2019-12-10 12:46:41 -08:00
Andrew Trick
4da33e15ad Cleanup: move ArrayPropertyOpt out of COWArrayOpt.cpp.
These are separate, mostly unrelated passes. Putting them in their own
files makes it easier to read the code, understand how to control the
passes, and makes it possible to independently trace, and debug them.
2019-11-25 11:53:49 -08:00
swift_jenkins
b9f998ffa4 Merge remote-tracking branch 'origin/master' into master-next 2019-11-15 15:56:48 -08:00
Andrew Trick
71523642ce Fix logic related to isTriviallyDuplicatable.
In SILInstruction::isTriviallyDuplicatable():

- Make deallocating instructions trivially duplicatable. They are by
  any useful definition--duplicating an instruction does not imply
  reordering it. Tail duplication was already treating deallocations
  as duplicatable, but doing it inconsistently. Sometimes it checks
  isTriviallyDuplicatable, and sometimes it doesn't, which appears to
  have been an accident. Disallowing duplication of deallocations will
  cause severe performance regressions. Instead, consistently allow
  them to be duplicated, making tail duplication more powerful, which
  could expose other bugs.

- Do not duplicate on-stack AllocRefInst (without special
  consideration). This is a correctness fix that apparently was never
  exposed.

Fix SILLoop::canDuplicate():

- Handle isDeallocatingStack. It's not clear how we were avoiding an
  assertion before when a stack allocatable reference was confined to
  a loop--probably just by luck.

- Handle begin/end_access inside a loop. This is extremely important
  and probably prevented many loop optimizations from working with
  exclusivity.

Update LoopRotate canDuplicateOrMoveToPreheader(). This is NFC.
2019-11-13 18:39:23 -08:00
swift-ci
64f712b1b4 Merge remote-tracking branch 'origin/master' into master-next 2019-11-01 11:09:36 -07:00
Erik Eckstein
c29cdd972b LICM: add an optimization to move multiple loads and stores from/to the same memory location out of a loop.
This is a combination of load hoisting and store sinking, e.g.

  preheader:
    br header_block
  header_block:
    %x = load %not_aliased_addr
    // use %x and define %y
    store %y to %not_aliased_addr
    ...
  exit_block:

is transformed to:

  preheader:
    %x = load %not_aliased_addr
    br header_block
  header_block:
    // use %x and define %y
    ...
  exit_block:
    store %y to %not_aliased_addr
2019-10-31 19:07:17 +01:00
Erik Eckstein
6c6b6849e0 LICM: rename MayWrites -> SideEffectInsts
Because the set includes all side-effect instructions, also may-reads.
NFC
2019-10-31 12:52:25 +01:00
swift-ci
90fcb675dc Merge remote-tracking branch 'origin/master' into master-next 2019-10-30 09:50:07 -07:00
eeckstein
7df5feb697 Revert "LICM: add an optimization to move multiple loads and stores from/to the same memory location out of a loop." 2019-10-30 17:26:49 +01:00
swift-ci
e981f7fa0d Merge remote-tracking branch 'origin/master' into master-next 2019-10-30 04:29:59 -07:00
Erik Eckstein
584581e9b9 LICM: add an optimization to move multiple loads and stores from/to the same memory location out of a loop.
This is a combination of load hoisting and store sinking, e.g.

  preheader:
    br header_block
  header_block:
    %x = load %not_aliased_addr
    // use %x and define %y
    store %y to %not_aliased_addr
    ...
  exit_block:

is transformed to:

  preheader:
    %x = load %not_aliased_addr
    br header_block
  header_block:
    // use %x and define %y
    ...
  exit_block:
    store %y to %not_aliased_addr
2019-10-29 16:49:48 +01:00
Erik Eckstein
4e8cfdeabb LICM: rename MayWrites -> SideEffectInsts
Because the set includes all side-effect instructions, also may-reads.
NFC
2019-10-29 10:21:16 +01:00
swift-ci
ded4197d59 Merge remote-tracking branch 'origin/master' into master-next 2019-10-02 13:29:41 -07:00
Andrew Trick
22500e7e6b Update the coding style for all code moved in the previous commit.
Requested by gottesmm during review.

Update the variable naming conventions to lower-camel.

Run clang-format.

I'm sure I missed some local variables somewhere--this was a best
effort.
2019-10-02 11:34:54 -07: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
Jonas Devlieghere
b4d268e9e1 Migrate llvm::make_unique to std::make_unique
Now that we've moved to C++14, we no longer need the llvm::make_unique
implementation from STLExtras.h. This patch is a mechanical replacement
of (hopefully) all the llvm::make_unique instances in the swift repo.
2019-08-15 11:32:39 -07:00
Michael Gottesman
7691ce35cc Merge pull request #26500 from gottesmm/pr-95a6aafeaf8ec7c5f984c7763edc8edf91dbfa40
[patternmatch] Add InstructionOperand_match to support for matching a…
2019-08-05 18:59:21 -07:00
Michael Gottesman
b6b61ddd6a [ownership] Skip functions with ownership in LICM. 2019-08-05 17:36:46 -07:00
Michael Gottesman
9c58e4b0a3 [patternmatch] Add InstructionOperand_match to support for matching against instructions with misc number of operands.
NOTE:

1. To test this I changed UnaryOp_match to use this under the hood.

2. These types of m_##ID##Inst matchers now will only accept compound types and
I added a static assert to verify that this mistake doesn't happen. We
previously had matchers that would take an int or the like to match tuple
extract patterns. I converted those to use TupleExtractOperation that also
properly handles destructures.
2019-08-05 17:26:02 -07:00
Erik Eckstein
237a3ef77f SIL: Extend cond_fail by a second operand, which is a static string literal, indicating the failure reason. 2019-07-16 12:31:10 +02:00
Brent Royal-Gordon
d5a2912a26 Revert "Better runtime failure messages (not yet enabled by default)" 2019-07-15 13:42:40 -07:00
Erik Eckstein
e2d313ef68 SIL: Extend cond_fail by a second operand, which is a static string literal, indicating the failure reason. 2019-07-12 14:03:13 +02:00
Arnold Schwaighofer
c187c8ac13 SIL: Replace uses of getReferencedFunction() by getReferencedFunctionOrNull() and getInitialReferencedFunction()
With the advent of dynamic_function_ref the actual callee of such a ref
my vary. Optimizations should not assume to know the content of a
function referenced by dynamic_function_ref. Introduce
getReferencedFunctionOrNull which will return null for such function
refs. And getInitialReferencedFunction to return the referenced
function.
Use as appropriate.

rdar://50959798
2019-05-26 08:58:14 -07:00
Andrew Trick
8cc013ed3f Fix LICM debug output typo. 2019-05-14 10:45:53 -07:00