Commit Graph

180 Commits

Author SHA1 Message Date
Adam Nemet
5d7b8106c3 Add opt-remarks to the Speculative Devirtualizer pass 2017-12-18 13:29:46 -08:00
Adam Nemet
3a9012d742 Add opt-remarks to the Devirtualizer pass 2017-12-18 10:18:13 -08:00
Slava Pestov
47a3a66e52 SILOptimizer: Kill off duplicated getAllSubclasses() algorithm 2017-11-27 22:20:14 -08:00
swift-ci
012cc4a6e7 Merge pull request #12933 from anemet/opt-remark-generic-specialization 2017-11-17 10:05:22 -08:00
Adam Nemet
bd8764caaa Add opt remarks to Generic Specializer pass
Adds a combined API to output both debug message and optimization remarks.

The previously added test partial_specialization_debug.sil ensures that it's an
NFC for debug output.
2017-11-16 10:10:24 -08:00
Michael Gottesman
49adf11a00 [cfg] Add back in bool return value, returning a value to it this time. 2017-11-15 21:52:50 -08:00
Slava Pestov
2aa126e680 SILOptimizer: Fix a warning 2017-11-15 20:58:58 -08:00
Michael Gottesman
1c33bc19c4 [cfg] Add Ownership SIL utility method splitAllCondBrCriticalEdgesWithNonTrivialArgs.
Currently, the ownership verifier assumes that all cond_br with critical edges
do not have non-trivial arguments. This utility method fixes any such issues and
should be run /after/ any passes that mess with the CFG in ownership SIL if this
could come up.

Chopping this off of a larger commit.

rdar://31521023
2017-11-14 12:04:58 -08:00
Michael Gottesman
1288bff937 [cfg] Add utility method completeJointPostDominanceSet.
This helper utility given a set of uses/defs determines the set of blocks that
together with the user blocks jointly post-dominate the def blocks. In a sense
this is completing the providing set of user blocks to a joint-post dominating
set. This completion is not unique.

I am adding this method because often times when working with Ownership SIL, one
needs to hoist/sink operations and then compensate to ensure that ownership
properties are still preserved.

I think with a little bit of work I can get the ownership model eliminator to
use this routine (since the condition for ownership to be correct on an @owned
value is an empty joint-post dominating completion. I wrote it b/c I need it in
pred-memopts and I expect it to be a general useful routine for Ownership SIL.

rdar://31521023
2017-11-14 09:46:51 -08:00
John McCall
14d6390352 Add "yield" and "unwind" instructions to SIL. 2017-11-07 03:51:54 -05:00
Michael Gottesman
4c80c4d66f Address John's feedback.
Specifically to commits:

36a8d0d5c0
6df5462ee2

rdar://31521023
2017-10-25 13:48:51 -07: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
Michael Gottesman
baf293a0f6 Merge pull request #11846 from gottesmm/pr-0b7638743feaaad8531e324038be3fe1cd536022
[mandatory-inlining] Make fixupReferenceCounts not delete instructions.
2017-09-12 14:15:46 -07:00
Roman Levenstein
f0a39e9e14 Add support for collecting various SIL optimizer counters
This patch implements collection and dumping of statistics about SILModules, SILFunctions and memory consumption during the execution of SIL optimization pipelines.

The following statistics can be collected:
  *  For SILFunctions: the number of SIL basic blocks, the number of SIL instructions, the number of SIL instructions of a specific kind, duration of a pass
  *  For SILModules: the number of SIL basic blocks, the number of SIL instructions, the number of SIL instructions of a specific kind, the number of SILFunctions, the amount of memory used by the compiler, duration of a pass

By default, any collection of statistics is disabled to avoid affecting compile times.

One can enable the collection of statistics and dumping of these statistics for the whole SILModule and/or for SILFunctions.

To reduce the amount of produced data, one can set thresholds in such a way that changes in the statistics are only reported if the delta between the old and the new values are at least X%. The deltas are computed as using the following formula:

   Delta = (NewValue - OldValue) / OldValue

Thresholds provide a simple way to perform a simple filtering of the collected statistics during the compilation. But if there is a need for a more complex analysis of collected data (e.g. aggregation by a pipeline stage or by the type of a transformation), it is often better to dump as much data as possible into a file using e.g. -sil-stats-dump-all -sil-stats-modules -sil-stats-functions and then e.g. use the helper scripts to store the collected data into a database and then perform complex queries on it. Many kinds of analysis can be then formulated pretty easily as SQL queries.
2017-09-10 21:47:55 -07:00
Michael Gottesman
49bf82245b [mandatory-inlining] Make fixupReferenceCounts not delete instructions.
The main loop of mandatory inlining is spending a lot of time managing complex
iterator invalidation issues. This is the first in a series of commits that move
the main inlining loop to only delete the callee and to do all cleanups after we
have finished inlining.

This specific optimization (the quick retain/release peephole), I am not going
to do in MandatoryInlining, we already have guaranteed arc opts afterwards that
will be able to hit such a peephole so no perf should be lost.

*NOTE* The reason why I had to touch some of the code motion tests is that the
routine I am using to ensure that strong_retain/release_value is emitted as
appropriate is also used by codemotion. Code motion tests had cargo culted some
code from previous tests that retained Builtin.Int32. I changed the routines
though so that when a retain/release is inserted, if it is trivial, nothing is
inserted. No routine was relying on the actual usage of the inserted
retain/releases, so everything will be safe. This addition to the relevant code
caused me to need to change the tests in code motion to use actual non-trivial
values. The same code paths are being tested in terms of blocking code
motion/etc.

rdar://31521023
2017-09-10 13:23:48 -07:00
Michael Gottesman
9f53380824 [gardening] Add a note to DevirtualizationResult explaining that it can contain an Argument. 2017-09-09 15:54:47 -07:00
Michael Gottesman
430f865f73 [inliner] Extract out checking if we can inline from inlineFunction into canInlineFunction. NFC.
The reason to do this is:

1. The check in SILInliner if we can inline can be done without triggering
side-effects.

2. This enables us to know if inlining will succeed before attempting to inline.
This enables for arguments to be adjusted with new SILInstructions and the like
before inlining occurs. I use this in a forthcoming patch that updates mandatory
inlining for ownership.

rdar://31521023
2017-09-08 18:25:57 -07:00
Jordan Rose
f8b7db4e76 Excise the terms "blacklist" and "whitelist" from Swift source. (#11687)
The etymology of these terms isn't about race, but "black" = "blocked"
and "white" = "allowed" isn't really a good look these days. In most
cases we weren't using these terms particularly precisely anyway, so
the rephrasing is actually an improvement.
2017-08-30 09:28:00 -07:00
Joe Shajrawi
570a82aea5 Reduce expansion of large types in the optimizer 2017-08-25 13:56:26 -07:00
Roman Levenstein
8503daee0d Implement a more robust way to avoid infinite generic specialization loops
The existing simple mechanism for avoiding infinite generic specialization loops is based on checking the structural depth and width of types passed as generic type parameters. If the depth or the width of a type is above a certain threshold, the type is considered too complex for generic specialization and no specialization is produced. While this approach prevents the possibility of producing an infinite number of generic specializations for ever-growing generic type parameters, it catches the issue too late in some cases, leading to excessive CPU and memory usage.

Therefore, the new method tries to solve the problem at its root. An infinite generic specialization loop can be triggered by specializing a given generic call-site if and only if:
-  Doing so would result in a loop inside the specialization graph represented by the `GenericSpecializationInformations`, i.e. it would produce direct or indirect recursion involving a generic call
-  The substitutions used by the current generic call-site are structurally more complex than the substitutions used by the same call-site in the previous iteration inside specialization graph. More complex in this context means that the new generic type parameter structurally contains the generic type parameter from a previous iteration inside the specialization graph and has greater structural depth, e.g. `Array<Int>` is more complex than `Int`.

The generic specializer now records all the required information about specializations it produces and uses it later to detect and prevent any generic specializations which would result in an infinite specialization loop. It detects them as early as possible and thus reduces compile times, memory consumption and potentially also reduces the code-size by not generating useless specializations.
2017-08-06 12:51:49 -07: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
Erik Eckstein
3b54966ff2 SILOptimizer: Add a utility to find dead-end blocks. 2017-07-21 10:37:54 -07:00
Devin Coughlin
06b9ed7501 [Exclusivity] Switch static checking to use IndexTrie instead of ProjectionPath
IndexTrie is a more light-weight representation and it works well in this case.
This requires recovering the represented sequence from an IndexTrieNode, so
also add a getParent() method.
2017-06-15 18:37:23 -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
Roman Levenstein
dd93027a0e Always inline pure functions with constant arguments
A function is pure if it has no side-effects.
If there is a call of a pure function with constant arguments, it always makes sense to inline it, because we know that the whole computation will be constant folded.
2017-05-15 11:52:36 -07:00
Roman Levenstein
d66924b01e [sil-inliner] Move some functionality from PerformanceInliner into PerformanceInlinerUtils. NFC.
It does not change any functionality. The only purpose it to make some functions reusable by other passes.
2017-05-15 09:03:53 -07:00
Roman Levenstein
8fb8cc4367 [generic-specializer] Cosmetic renaming of some vars and functions to match the new naming scheme 2017-04-20 08:16:24 -07:00
Roman Levenstein
686b83b6cb [generic-specializer] Improve comments 2017-04-20 08:16:24 -07:00
Roman Levenstein
f28e28c0a8 [generic-specializer] Big re-factoring of the partial specialization implementation
- Introduced a new helper class FunctionSignaturePartialSpecializer which provides most of the functionality required for producing a specialized generic signature based on the provided substitutions or requirements. The class consists of many small functions, which should make it easier to understand the code.

- Added a full support for partial specialization of generic parameters with generic substitutions (use flag `-Xllvm -sil-partial-specialization-with-generic-substitutions` to enable it)

- Removed the simpler version of the partial specializer which could partially specialize only generic parameters with non-generic substitutions. It is not needed anymore, because we can handle any substations now when performing the partial specialization.

- The functionality used by the EagerSpecializer to implement the partial specializations required by @_specialize is expressed in terms of FunctionSignaturePartialSpecializer as well. The code implementing it is much smaller now.

Partial specialization of generic parameters with generic substitutions is fully functional, but it is disabled by default, because it needs some tweaks when it comes to compile times and size of produced code. These issues will be addressed in the subsequent commits.
2017-04-20 08:16:24 -07:00
Roman Levenstein
ce8d986999 [generic-specializer] Rename OriginalF into Callee 2017-04-20 08:16:24 -07:00
practicalswift
7eb7d5b109 [gardening] Fix 100 typos. 2017-04-18 17:01:42 +02:00
practicalswift
40cf4d183d [gardening] Use consistent spacing after if, for and while 2017-04-14 17:35:36 +02:00
Andrew Trick
4f52f84939 [SILOpt] Redundant load elimination. Add debug output. 2017-04-05 19:59:15 -07:00
Erik Eckstein
a43a844838 StackNesting: use the right debug locations for inserted deallocation instructions
Fixes a crash because we used a return-location for a deallocation instruction.

rdar://problem/31458587
rdar://problem/31458617
2017-04-05 18:05:39 -07:00
swift-ci
024033cf97 Merge pull request #8533 from adrian-prantl/28311051 2017-04-05 11:52:50 -07:00
Adrian Prantl
5ea2d13f5e Improve the performance of IRGenDebugInfo
This commit changes how inline information is stored in SILDebugScope
from a tree to a linear chain of inlined call sites (similar to what
LLVM is using). This makes creating inlined SILDebugScopes slightly
more expensive, but makes lowering SILDebugScopes into LLVM metadata
much faster because entire inlined-at chains can now be cached. This
means that SIL is no longer preserve the inlining history (i.e., ((a
was inlined into b) was inlined into c) is represented the same as (a
was inlined into (b was inlined into c)), but this information was not
used by anyone.

On my late 2012 i7 iMac, this saves about 4 seconds when compiling the
RelWithDebInfo x86_64 swift standard library — or 40% of IRGen time.

rdar://problem/28311051
2017-04-05 08:33:55 -07:00
Roman Levenstein
4aaa855da1 Merge pull request #8489 from swiftix/wip-func-sig-opt-generic-functions-3
[sil-function-signature-opt] Support FSO for generic functions
2017-04-04 17:47:22 -07:00
Roman Levenstein
64813b7b4f [sil-function-signature-opt] Support FSO for generic functions
In particular, support the following optimizations:
- owned-to-guaranteed
- dead argument elimination

Argument explosion is disabled for generics at the moment as it usually leads to a slower code.
2017-04-04 12:33:17 -07:00
Erik Eckstein
805960b0ac ValueLifetimeAnalysis: fix the lifetime computation in case the value definition is in a single-block loop.
This caused DeadObjectElimination to generate a memory leak in case a dead array is in a single-block loop.
rdar://problem/31420889
2017-04-04 10:43:53 -07:00
swift-ci
7dc7207db9 Merge pull request #8474 from atrick/fix 2017-03-31 17:14:10 -07:00
Andrew Trick
2396e7d3cc [SILOpt][NFC] Print projections readably and efficiently.
Begin to make the RLE pass debuggable.
Overhaul the ProjectionPath printing feature and fixup tests.
2017-03-31 16:51:34 -07:00
Slava Pestov
695a8d2065 Merge pull request #8407 from slavapestov/rename-everything-without-asking-permission
SIL: Terminology change: [fragile] => [serialized]
2017-03-29 20:08:15 -07:00
Slava Pestov
8fe8b89b0f SIL: Terminology change: [fragile] => [serialized]
Also, add a third [serializable] state for functions whose bodies we
*can* serialize, but only do so if they're referenced from another
serialized function.

This will be used for bodies synthesized for imported definitions,
such as init(rawValue:), etc, and various thunks, but for now this
change is NFC.
2017-03-29 16:47:28 -07:00
Erik Eckstein
607318e0c7 Utility for correcting the nesting of stack allocation/deallocation instructions in SIL.
This is useful for optimizations (like AllocBoxToStack) which create (de-)alloc_stack instructions.
They can just insert the new instructions anywhere without worrying about nesting and correct the nesting afterwards.
2017-03-29 15:41:04 -07:00
Roman Levenstein
fae0628a97 Implement partial specialization which supports generic substitutions.
Use -sil-partial-specialization-with-generic-substitutions to enable the partial specialization even in cases of substitutions containing generic replacement types.
2017-03-21 08:46:40 -07:00
Erik Eckstein
d70bfc5de2 rename namespace NewMangling -> Mangle 2017-03-20 10:09:30 -07:00
Erik Eckstein
1625345b90 Remove the old mangler.
NFC
2017-03-17 16:10:36 -07:00
Roman Levenstein
c336dafb04 [sil-generic-specializer] Provide a possibility to disable the indirect-to-direct conversions of parameters and results
This is required by the capture propagation pass. Indirect-to-direct conversions are still performed by default.
2017-03-15 08:27:21 -07:00