Commit Graph

166 Commits

Author SHA1 Message Date
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
Erik Eckstein
020a283bbb SIL: Let the OpenedArchetypesTracker be constructed with a null SILFunction.
NFC
2017-08-23 09:15:00 -07:00
Roman Levenstein
95223728c2 [sil-inliner] It is always OK to inline a simple call
A simple call is an invocation of a function without any side-effects, where all passed parameters are constants.
2017-08-22 15:16:19 -07:00
Arnold Schwaighofer
1b7a308016 Osize: Only skip inlining for class methods
This addresses most of the regressions from the compat suite and some size
saving gains.
2017-08-18 14:28:32 -07:00
Arnold Schwaighofer
d85b35b588 Tune down inlining at Osize
This is obviously just a start. Don't inline into thunks and don't inline
methods.

Start off with half the benefit for removing a call.
2017-08-17 14:57:22 -07:00
Roman Levenstein
980a590708 [sil-inliner] Transparent functions should be inlined by the performance inliner as if they are always inline functions 2017-05-19 15:08:25 -07:00
Roman Levenstein
341b5c506d [sil-inliner] Respect the @inline(__always) and @_transparent even if inlining of generics is disabled
If some functions are explicitly annotated by developers as @inline(__always) or @_transparent, they should always be a subject for the inlining of generics, even if this kind of inlining is not enabled currently for all functions.
2017-05-19 15:08:18 -07:00
Roman Levenstein
5b4691d901 Revert "[sil-inliner] Respect the @inline(__always) and @_transparent even if inlining of generics is disabled" 2017-05-19 08:20:55 -07:00
Roman Levenstein
116581f2c5 [sil-inliner] Transparent functions should be inlined by the performance inliner as if they are always inline functions 2017-05-18 21:54:45 -07:00
Roman Levenstein
3fcd6f40c8 [sil-inliner] Respect the @inline(__always) and @_transparent even if inlining of generics is disabled
If some functions are explicitly annotated by developers as @inline(__always) or @_transparent, they should always be a subject for the inlining of generics, even if this kind of inlining is not enabled currently for all functions.
2017-05-18 21:54:45 -07:00
Erik Eckstein
74fa0bcc87 Disable generic inlining and partial specialization, except in libswiftCore
This avoids code size regressions in programs while still getting the performance improvements in generic code in the stdlib.

rdar://problem/32277313
2017-05-18 15:38:54 -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
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
Slava Pestov
0290c2d5d8 AST: Make GenericSignature and GenericEnvironment SubstitutionMaps interchangable
SubstitutionMap::lookupConformance() would map archetypes out
of context to compute a conformance path. Do the same thing
in SubstitutionMap::lookupSubstitution().

The DenseMap of replacement types in a SubstitutionMap now
always has GenericTypeParamTypes as keys.

This simplifies some code and brings us one step closer to
a more efficient representation of SubstitutionMaps.
2017-04-24 14:12:36 -07:00
practicalswift
7eb7d5b109 [gardening] Fix 100 typos. 2017-04-18 17:01:42 +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
Erik Eckstein
dc426bd885 SIL optimizer: add some clean-up passes before the inliner.
This is important in case the inline restarts the pass pipeline.
In a sub-sequent invocation of the inlined it should receive a cleaned-up function so that it can make better estimations for further inlining.

As a compensation, reduce the caller-block limit of the inliner.
And add an overall block limit which is also taken into account for always-inline functions.
2017-03-31 15:31:57 -07:00
Erik Eckstein
2cb998f09c PerformanceInliner: add a debug message for an always-inline decision. 2017-03-31 15:31:57 -07:00
Erik Eckstein
9ce3df106e Add two new array semantics functions.
array.append_element(newElement: Element)
array.append_contentsOf(contentsOf newElements: S)

And allow early inlining of them.
Those functions will be needed to optimize Array.append(contentsOf)
2017-03-31 15:31:57 -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
Slava Pestov
de2f5f78ac AST: Remove Substitution::subst()
I want to get rid of Substitution entirely, and now we have
the right abstractions to do everything with SubstitutionMap.
2017-03-07 16:04:54 -08:00
Slava Pestov
c040c71ea9 AST: Remove some unnecessary SubstitutionList copies
ASTContext::getSpecializedConformance() already copies the
substitutions, so remove some AllocateCopy() calls.

Also, add a new overload taking a SubstitutionMap instead.
This allows removing some gatherAllSubstitutions() calls,
which have an allocation inside them.

Finally, remove the now-unused ModuleDecl parameter from
ProtocolConformance::subst() and make it public.
2017-03-07 15:59:05 -08:00
Roman Levenstein
a9db867e8d Implement partial specialization behind a flag.
Partial specialization is disabled by default. Use -sil-partial-specialization to enable it.

Use -sil-partial-specialization-with-generic-substitutions to enable the partial specialization even in cases of substitutions containing generic replacement types.
2017-03-02 23:29:55 -08:00
Roman Levenstein
a71202fbae [sil-performance-inliner] Do not inline generics into thunks
This allows for about 4% code size reduction on stdlib. And the performance hit is not very significant. Only 5-6 benchmarks get somewhat slower.
2017-02-24 14:59:44 -08:00
practicalswift
d352652a72 Merge pull request #7727 from practicalswift/typos-20170223
[gardening] Fix typos
2017-02-24 09:15:12 +01:00
practicalswift
33a5601ad1 [gardening] Fix typos 2017-02-23 22:46:40 +01:00
practicalswift
59221c63c8 [gardening] Remove unused logic in SILPerformanceInliner::isProfitableToInline(...) 2017-02-23 22:18:08 +01:00
Roman Levenstein
7bcb3227fc Enable inlining of generics 2017-02-20 17:57:42 -08:00
Roman Levenstein
ef088e818d [sil-performance-inliner] Fix recent performance regressions
Do not perform any inlining of generics if it is not enabled. Don't do it even for always inline functions.
2017-02-20 16:16:18 -08:00
Roman Levenstein
de6328122d [sil-performance-inliner] Do not inline generic functions if they contain a partial_apply with an opened existential in its substitution list
IRGen cannot handle partial_applies containing opened_extistentials in their substitutions lists.
2017-02-17 09:07:18 -08:00
Roman Levenstein
4388593943 [sil-performance-inliner] Tweak the inlining profitability heuristic for inlining of generics
Consider the possibility of performing a specialization or devirtualization after inlining of a generic function.
2017-02-17 09:07:18 -08:00
Jordan Rose
1c60910198 Revert "Merge pull request #6092 from swiftix/wip-generics-inlining-flag-4"
This reverts commit 1b3d29a163, reversing
changes made to b32424953e.

We're seeing a handful of issues from turning on inlining of generics,
so I'm reverting to unblock the bots.
2017-02-13 10:52:17 -08:00
Roman Levenstein
260eeb27e3 Adjust to recent Generics.h changes. 2017-02-10 07:41:55 -08:00
Roman Levenstein
54bd9c3863 Adjust PerformanceInliner to the recent SubstitutionMap changes 2017-02-10 07:41:54 -08:00
Roman Levenstein
55de499c99 [sil-performance-inliner] Enable inlining of generics 2017-02-10 07:41:54 -08:00
Roman Levenstein
263d3a64fb [sil-performance-inliner] Prefer specialization of generics to inlining 2017-02-10 07:41:54 -08:00
Roman Levenstein
2c3f3b461b [sil-performance-inliner] Add profitability heuristic tweaks for generic functions.
This should limit uncontrolled code size growth.

Transparent and always inline generic functions are now always inlined.
2017-02-10 07:41:54 -08:00
Slava Pestov
844765b2fc SILOptimizer: Clean up hasDynamicSelfTypes() and hasUnboundGenericTypes() 2017-01-08 21:01:13 -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
practicalswift
38be6125e5 [gardening] C++ gardening: Terminate namespaces, fix argument names, ...
Changes:
* Terminate all namespaces with the correct closing comment.
* Make sure argument names in comments match the corresponding parameter name.
* Remove redundant get() calls on smart pointers.
* Prefer using "override" or "final" instead of "virtual". Remove "virtual" where appropriate.
2016-12-17 00:32:42 +01: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
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
Andrew Trick
a296ced6df Generic inline (#5467)
* [sil-performance-inliner] Re-factor the isProfitableToInline logic. NFC.

* [sil-performance-inliner] Introduce a pre-filter to decide of a generic function should be inlined

This logic is unconditional and is does not require any complex cost models.
The outcome of the check is one of:
- yes, inline this generic function
- no, do not inline this generic function
- None, don't know if it should be inline. Further more complex checks are required.

* [sil-performance-inliner] Handle inlining of generic functions into cold blocks

Generic functions should be inlined into cold blocks only if they should be unconditionally inlined (e.g. when they are always_inline or transparent).

* Allow generic inlining under -sil-inline-generics.
2016-10-25 17:27:02 -07:00
Doug Gregor
dc2777e283 Revert "[sil-performance-inliner] Re-introduce inlining of generics as a staging feature behind a flag" 2016-10-19 15:15:59 -07:00
Roman Levenstein
91f5b9dac1 [sil-performance-inliner] Re-introduce inlining of generics as a staging feature behind a flag
Use the following options to enable this flag: -Xllvm -sil-inline-generics

Generic inlining is now handled by a dedicated logic in isProfitableToInlineGeneric. This makes it easier to find this logic. And it will make it easier to extend and improve it in the future.

The initial policy for generic inlining is:
- unconditionally inline generic functions if the -sil-inline-generics flag is used.
- If the flag is not used, only perform generic inlining of always_inline and transparent functions.

There are slight standard library's code-size regressions with this policy. They will be addressed by the future work on the generic inlining.
2016-10-18 16:52:50 -07:00
Roman Levenstein
0cc7043599 [sil-performance-inliner] Re-factoring: Split the performance inliner into a main driver and a set of utility files. NFC.
- Move the common performance inliner functionality into PerformanceInlinerUtils.cpp.
- Move the functionality specific to non-generic inlining into NonGenericPerformanceInliner.cpp
- Temporarily disable the inlining of generics. It will be enabled in the subsequent commit.
2016-10-12 16:48:06 -07:00
Roman Levenstein
7cc11a56ec [sil-inliner] Introduce a staging flag to enable the inlining of generics.
Use the following options to enable this flag: -Xllvm -sil-inline-generics
2016-10-11 10:10:52 -07:00
Slava Pestov
185921f6ab AST: Remove slow version of Substitution::subst()
When applying substitutions to substitution lists in SIL, we would
unpack the ArrayRef<Substitution> into a SubstitutionMap on each
iteration over the original ArrayRef<Substitution>. Discourage
this sort of thing by removing the API in question and refactoring
surrounding code.
2016-09-13 22:58:58 -07:00