Commit Graph

167 Commits

Author SHA1 Message Date
Andrew Trick
8cc013ed3f Fix LICM debug output typo. 2019-05-14 10:45:53 -07:00
Michael Gottesman
8feb1a1000 [sil] Replace some nstances of SILBuilder(...) with SILBuilderWithScope(...).
The main thing to notice about these changes is that I always picked the debug
scope associated with the location we were using. They should always be in
sync.
2019-04-05 12:32:31 -07:00
Erik Eckstein
c2a8c71191 SILOptimier: Fix a miscompile in COWArrayOpt.
If a make_mutable operation is done conditionally in a loop, the hoisting of this operation can cause an over-release of the array buffer in some cases.

rdar://problem/48906146
2019-03-19 13:23:38 -07:00
Joe Shajrawi
d80f2d2e6e [exclusivity] teach LICM how to handle static markers 2019-03-14 12:39:21 -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
Andrew Trick
958dd9701d Prevent FunctionSignatureOptimization from rerunning on its own thunk.
This is a bug fix that just bails out of FSO, which is exactly what we
should be doing in this case anyway.

This issue will be exposed in stdlib builds once I fix another bug in
the passmanager. Once the pass pipeline restart works as intended, we
will perform FSO on `F`, then devirtualization will discover a new
reference to `F`, causing it to be pushed back on the function pass
pipeline.
2019-02-06 13:32:27 -08: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
d42f654aa7 LoopUnroll: handle more variations of the comparison builtin
Handle !=, <, <= in addition to ==, >, >=.

This enables loop unrolling if the loop is written as 'while i < e { }'.

rdar://problem/46606173
2018-12-11 13:20:03 -08:00
Adrian Prantl
ff63eaea6f Remove \brief commands from doxygen comments.
We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.

Patch produced by

      for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
2018-12-04 15:45:04 -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
Arnold Schwaighofer
7e32c68e1d Add new SIL instruction for calling dynamically_replaceable funtions
%0 = dynamic_function_ref @dynamically_replaceable_function
  apply %0()
  Calls a [dynamically_replaceable] function.

  %0 = prev_dynamic_function_ref @dynamic_replacement_function
  apply %0
  Calls the previous implementation that dynamic_replacement_function
  replaced.
2018-11-06 09:53:22 -08:00
swift-ci
8d1ac7b638 Merge pull request #20204 from shajrawi/licm_faster 2018-10-31 18:37:15 -07:00
Joe Shajrawi
45b61d11d7 [LICM] Only add dynamic begin_access checks to the list of access scopes to be analyzed
This should provide slight compile-time improvement
2018-10-31 17:31:29 -07:00
Andrew Trick
2aa8427dc6 SILCloner: rename 'remapValue' to 'getMappedValue' to avoid confusion.
A follow up commit adds an API for SILCloner clients to set mapped
values. Calling the map lookup "remap" would be unacceptably misleading.
2018-10-27 16:30:37 -07:00
Andrew Trick
077757858b LoopUnroll comment 2018-10-26 23:18:37 -07:00
Erik Eckstein
15b01ab792 SIL: Remove array.owner semantic function
Also remove the getOwner functions from ArraySlide.
These functions are not needed anymore with accessors.

rdar://problem/44184810
2018-10-15 09:44:52 -07:00
Andrew Trick
bd28b0ea1b SILCloner and SILInliner rewrite.
Mostly functionally neutral:
- may fix latent bugs.
- may reduce useless basic blocks after inlining.

This rewrite encapsulates the cloner's internal state, providing a
clean API for the CRTP subclasses. The subclasses are rewritten to use
the exposed API and extension points. This makes it much easier to
understand, work with, and extend SIL cloners, which are central to
many optimization passes. Basic SIL invariants are now clearly
expressed and enforced. There is no longer a intricate dance between
multiple levels of subclasses operating on underlying low-level data
structures. All of the logic needed to keep the original SIL in a
consistent state is contained within the SILCloner itself. Subclasses
only need to be responsible for their own modifications.

The immediate motiviation is to make CFG updates self-contained so
that SIL remains in a valid state. This will allow the removal of
critical edge splitting hacks and will allow general SIL utilities to
take advantage of the fact that we don't allow critical edges.

This rewrite establishes a simple principal that should be followed
everywhere: aside from the primitive mutation APIs on SIL data types,
each SIL utility is responsibile for leaving SIL in a valid state and
the logic for doing so should exist in one central location.

This includes, for example:
- Generating a valid CFG, splitting edges if needed.
- Returning a valid instruction iterator if any instructions are removed.
- Updating dominance.
- Updating SSA (block arguments).

(Dominance info and SSA properties are fundamental to SIL verification).

LoopInfo is also somewhat fundamental to SIL, and should generally be
updated, but it isn't required.

This also fixes some latent bugs related to iterator invalidation in
recursivelyDeleteTriviallyDeadInstructions and SILInliner. Note that
the SILModule deletion callback should be avoided. It can be useful as
a simple cache invalidation mechanism, but it is otherwise bug prone,
too limited to be very useful, and basically bad design. Utilities
that mutate should return a valid instruction iterator and provide
their own deletion callbacks.
2018-10-08 19:30:09 -07:00
Erik Eckstein
506a14b9f0 COWArrayOpts: make the optimization work again for two-dimensional arrays.
With removing of pinning and with addressors, the pattern matching did not work anymore.
The good thing is that the SIL is now much simpler and we can handle the 2D case without pattern matching at all.
This removes a lot of code from COWArrayOpts.

rdar://problem/43863081
2018-10-05 08:26:14 -07:00
Erik Eckstein
b2a5fd69be COWArrayOpts: remove the -view-cfg-before-cow-for option for debugging
This option is very old. The same effect can now be achieved with pass-manager options, like -sil-print-before
2018-10-05 08:26:14 -07:00
Michael Gottesman
d57a88af0d [gardening] Rename references to SILPHIArgument => SILPhiArgument. 2018-09-25 22:23:34 -07:00
Erik Eckstein
87cf7eff03 SIL optimizer: fix a compiler non-determinism in LICM.
SR-8844
rdar://problem/44762620
2018-09-25 12:58:42 -07:00
Mike Ash
798edb9d0e [Runtime][Stdlib][Overlays] Rename various Objective-C classes and methods that would conflict when loading old Swift libraries into a process alongside ABI-stable libraries.
rdar://problem/35768222
2018-09-13 16:55:10 -04:00
Erik Eckstein
584ed9710f SILOptimizer: update bounds check and uniqueness check hoisting optimizations for using _modify in Array subscript.
The optimizations now handle the ref_tail_addr instructions for detecting element addresses
(in addition to the array semantics function _getElementAddress).
After _modify for Array subscript lands, we can get rid of _getElementAddress at all.
2018-09-06 16:58:06 -07:00
Joe Shajrawi
a9df5863d0 Merge pull request #19119 from shajrawi/mayrelease
[Exclusivity] Handle mayRelease instructions conservatively in AccessnforcementOpts and LICM
2018-09-04 17:41:17 -07:00
Joe Shajrawi
c6a4e2cdd2 [Exclusivity] Handle mayRelease instructions conservatively in AccessEnforcementOpts and LICM 2018-09-04 13:23:22 -07:00
Andrew Trick
1e88e44ce8 Add critical edge verification and fix SIL passes.
SIL passes were violating the existing invariant on non-cond-br
critical edges in several places. I fixed the places that I could
find.  Wherever there was a post-pass to "clean up" critical edges, I
replaced it with a a call to verification that the critical edges
aren't broken in the first place.

We still need to eliminate critical edges entirely before enabling
ownership SIL.
2018-08-30 13:01:39 -07:00
Andrew Trick
9d2af79975 Simplify SILPHIArgument::getIncomingValue.
The client of this interface naturally expects to get back the
incoming phi value. Ignoring dominance and SIL ownership, the incoming
phi value and the block argument should be substitutable.

This method was actually returning the incoming operand for
checked_cast and switch_enum terminators, which is deeply misleading
and has been the source of bugs.

If the client wants to peek though casts, and enums, it should do so
explicitly. getSingleTerminatorOperand[s]() will do just that.
2018-08-30 13:01:39 -07:00
Joe Shajrawi
95344f6591 [LICM/Exclusivity] Hoist (some) conflicting begin_accesses out of loops
Consider the attached test cases:

We have a begin_access [dynamic] to a global inside of a loop

There’s a nested conflict on said access due to an apply() instruction between the begin and end accesses.

LICM is currently very conservative: If there are any function calls inside of the loop that conflict with begin and end access, we do not hoist out of the loop.

However, if all conflicting applies are “sandwiched” between the begin and end access. So there’s no reason we can’t hoist out of the loop.

See radar rdar://problem/43660965 - this improves some internal benchmarks by over 3X
2018-08-28 11:51:16 -07:00
Joe Shajrawi
8e935f6046 Fix a warning in LICM in release builds 2018-08-27 10:11:23 -07:00
Joe Shajrawi
5e2f3d8448 [LICM]: support hosting ref_element_addr even if they are not guaranteed to be executed
In some instances, some instructions, like ref_element_addr, can be hoisted outside of loops even if they are not guaranteed to be executed.

We currently don’t support that / bail. We only try to do so / do further analysis only for begin_access because they are extremely heavy.

However, we need to support hosting of ref_element_addr in that case, if it does not have a loop dependent operand, in order to be able to hoist begin_access instructions in some benchmarks.

Initial local testing shows that this PR, when we enable exclusivity, improves the performance of a certain internal benchmark by over 40%

See rdar://problem/43623829
2018-08-23 14:13:37 -07:00
Joe Shajrawi
7281a76deb [AccessEnforcementOpts] Add mergeAccesses optimization 2018-08-09 16:15:25 -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
swift-ci
9b2d9606f6 Merge pull request #17614 from shajrawi/licm_asan 2018-06-28 17:02:08 -07:00
Joe Shajrawi
3d411d22e0 [LICM] Fix an ASAN use-after-free bug in rewrite 2018-06-28 15:46:05 -07:00
Joe Shajrawi
437b0d8e13 [LICM] Array Semantics: only hoist kGetCount and kGetCapacity
We can’t hoist everything that is hoist-able

The canHoist method does not do all the required analysis

Some of the work is done at COW Array Opt

TODO: Refactor COW Array Opt + canHoist - radar 41601468
2018-06-28 14:42:20 -07:00
swift-ci
b34c087cf4 Merge pull request #17194 from shajrawi/licm2 2018-06-27 22:59:33 -07:00
Joe Shajrawi
c3ddaf92cb [LICM] Further refactoring: Simplify hosting of begin access instructions - get rid of HoistPairSet and hoistAndSinkInstructionPair 2018-06-27 20:54:24 -07:00
Michael Gottesman
9e70b855e4 [cmake] Use a helper macro to simplify adding sources to the SILOptimizer library.
All this does is automate the creation of the ${DIRNAME}_SOURCES variables that we already create and allows for the author to avoid having to prefix with the directory name, i.e.:

set(FOOBAR_SOURCES
  FooBar/Source.cpp
  PARENT_SCOPE)

=>

silopt_register_sources(
  Source.cpp)

Much easier and cleaner to read. I put the code that implements this in the
CMakeLists.txt file just for the SILOptimizer.
2018-06-27 17:48:59 -07:00
Joe Shajrawi
f56b5d8730 [LICM] Add support for Hosting <Instruction, Instruction Set> Pairs
Support having the target of each hoist instruction as multiple sinks.
2018-06-27 16:25:35 -07:00
Joe Shajrawi
bc59eaad70 [LICM] Refactoring + Improvements + Exclusivity Support
Major refactoring + tuning of LICM. Includes:
Support for hosting more array semantic calls
Remove restrictions for sinking instructions
Add support for hoisting and sinking instruction pairs (begin and end accesses)

Testing with Exclusivity enabled on a couple of benchmarks shows:
ReversedArray 7x improvement
StringWalk 2.6x improvement
2018-06-26 13:26:37 -07:00
Joe Shajrawi
19a6bb5bdb [LICM] Code Hygiene - rip out sinkCondFail
Removing this optimization from SIL: It is not worth the extra code complexity and compilation time.

More in-depth explanation for the reasoning behind my decision:
1) What is being done there is obviously not LICM (more below) - even if it is useful it should be its own separate optimization
2) The regression that caused us to add this code is no longer there in most cases - 10% in only one specific corner-case
3) Even if the regression was still there, this is an extremely specific code pattern that we are pattern-matching against. Said pattern would be hard to find in any real code.

There is a small code snippet in rdar://17451529 that caused us to add this optimization. Looking at it now we see that the only difference is in loop1 example -

The only difference in SIL level is in loop 1:
  %295 = tuple_extract %294 : $(Builtin.Int64, Builtin.Int1), 0
  %296 = tuple_extract %294 : $(Builtin.Int64, Builtin.Int1), 1
  cond_fail %296 : $Builtin.Int1
  %298 = struct $Int (%295 : $Builtin.Int64)
  store %298 to %6 : $*Int
  %300 = builtin "cmp_eq_Int64"(%292 : $Builtin.Int64, %16 : $Builtin.Int64) : $Builtin.Int1
  cond_br %300, bb1, bb12

The cond_fail instruction in said loop is moved below the store instruction / above the builtin.

Looking at the resulting IR. And how LLVM optimizes it. It is almost the same.

If we look at the assembly code being executed then, before removing this optimization, we have:
LBB0_11:
	testq	%rcx, %rcx
	je	LBB0_2
	decq	%rcx
	incq	%rax
	movq	%rax, _$S4main4sum1Sivp(%rip)
	jno	LBB0_11

After removing it we have:
LBB0_11:
	incq	%rax
	testq	%rcx, %rcx
	je	LBB0_2
	decq	%rcx
	movq	%rax, %rdx
	incq	%rdx
	jno	LBB0_11

There is no extra load/movq which was mentioned the radar.
2018-06-14 11:10:11 -07:00
David Zarzycki
8c0c55539f [SIL] NFC: Rename misleading getSwiftRValueType() to getASTType()
Reference storage types are not RValues. Also, use more SILType helper
methods to avoid line wrap.
2018-05-04 08:14:38 -04:00
Andrew Trick
cdcb7c7a2c [NFC] SideEffectAnalysis refactoring and cleanup.
Make this a generic analysis so that it can be used to analyze any
kind of function effect.

FunctionSideEffect becomes a trivial specialization of the analysis.

The immediate need for this is to introduce an new
AccessedStorageAnalysis, although I foresee it as a generally very
useful utility. This way, new kinds of function effects can be
computed without adding any complexity or compile time to
FunctionSideEffects. We have the flexibility of computing different
kinds of function effects at different points in the pipeline.

In the case of AccessedStorageAnalysis, it will compute both
FunctionSideEffects and FunctionAccessedStorage in the same pass by
implementing a simple wrapper on top of FunctionEffects.

This cleanup reflects my feeling that nested classes make the code
extremely unreadable unless they are very small and either private or
only used directly via its parent class. It's easier to see how these
classes compose with a flat type system.

In addition to enabling new kinds of function effects analyses, I
think this makes the implementation of side effect analysis easier to
understand by separating concerns.
2018-04-16 17:05:04 -07:00
Davide Italiano
b4d563802b [SILInstruction] Introduce isDebugInstruction().
This is a property of an instruction and should be a member
function of `SILInstruction` and not a free function in
`DebugUtils`. Discussed with Adrian.
2018-04-11 10:14:21 -07:00
Slava Pestov
e1f50b2d36 SE-0193: Rename @_inlineable to @inlinable, @_versioned to @usableFromInline 2018-03-30 21:55:30 -07:00
Alex Blewitt
b13c8dede3 [SR-7043] Remove duplicate if statement 2018-02-20 19:25:10 +00:00
Erik Eckstein
db69b8d433 SideEffectAnalysis: don't assume the worst side-effects for a release instruction
Instead let the client decide what to do with this.
Sometimes the client knows what side effect a release instruction really has.
2018-01-19 11:32:35 -08:00
eeckstein
b126b62256 Revert "Optimization changes to completely fold OptionSet literals" 2018-01-18 22:05:07 -08:00
Erik Eckstein
9907ffc09d SideEffectAnalysis: don't assume the worst side-effects for a release instruction
Instead let the client decide what to do with this.
Sometimes the client knows what side effect a release instruction really has.
2018-01-18 18:27:17 -08:00