- 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.
I put in a simple fixup pass (MarkUninitializedFixup) for staging purposes. I
don't expect it to be in tree long. I just did not feel comfortable fixing up in
1 commit all of the passes up to DI.
rdar://31521023
Add a diagnostic pass that emits errors when a violation of the "Law of
Exclusivity" is detected at compile time. The Law of Exclusivity requires
that the access duration of any access to an address not overlap
with an access to the same address unless both accesses are reads.
This pass relies on 'begin_access' and 'end_access' SIL instruction
markers inserted by SILGen to determine when an access to an address begins and
ends. It models the in-progress accesses with a map from storage locations to
the counts of read and write-like accesses in progress for that location.
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.
I improved all of the pass names so they are minimal but fully descriptive.
The PASS macros contained wordy, unhelpful descriptions, which served
no functional purpose. Those descriptions are permanently preseved in
git history. If anyone thinks they contain useful information, then
they should be added to the *definition* of the pass (where passes are
actually described).
Long-winded pass comments have no place in Passes.def. The purpose of
those macros is to associate a unique type name, enum value,
command-line-option name, and pretty name with each pass for tooling
purposes. Any one of those entities needs to be sufficient for looking
up the others. That's not where anyone should look read a description
of the pass.
I am going to run it very early and use it to ensure that extra copies due to my
refactoring of SILGenPattern do not cause COW copies to be introduced.
For now, it does a very simple optimization, namely, it eliminates a copy_value,
with only a destroy_value user on a guaranteed parameter.
It is now disabled behind a flag.
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
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.
if the argument is an array literal.
For example:
arr += [1, 2, 3]
is replaced by:
arr.append(1)
arr.append(2)
arr.append(3)
This gives considerable speedups up to 10x (for our micro-benchmarks which test this).
This is based on the work of @ben-ng, who implemented the first version of this optimization (thanks!).
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)
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.
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.
Use -sil-partial-specialization-with-generic-substitutions to enable the partial specialization even in cases of substitutions containing generic replacement types.
There are now separate functions for function addition and deletion instead of InvalidationKind::Function.
Also, there is a new function for witness/vtable invalidations.
rdar://problem/29311657
Previously it was part of swiftBasic.
The demangler library does not depend on llvm (except some header-only utilities like StringRef). Putting it into its own library makes sure that no llvm stuff will be linked into clients which use the demangler library.
This change also contains other refactoring, like moving demangler code into different files. This makes it easier to remove the old demangler from the runtime library when we switch to the new symbol mangling.
Also in this commit: remove some unused API functions from the demangler Context.
fixes rdar://problem/30503344
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.