Commit Graph

159 Commits

Author SHA1 Message Date
Andrew Trick
d369aa4070 Support @noescape SIL function types. (#12420)
Support for @noescape SILFunctionTypes.

These are the underlying SIL changes necessary to implement the new
closure capture ABI.

Note: This includes a change to function name mangling that
primarily affects reabstraction thunks.

The new ABI will allow stack allocation of non-escaping closures as a
simple optimization.

The new ABI, and the stack allocation optimization, also require
closure context to be @guaranteed. That will be implemented as the
next step.

Many SIL passes pattern match partial_apply sequences. These all
needed to be fixed to handle the convert_function that SILGen now
emits. The conversion is now needed whenever a function declaration,
which has an escaping type, is passed into a @NoEscape argument.

In addition to supporting new SIL patterns, some optimizations like
inlining and SIL combine are now stronger which could perturb some
benchmark results.

These underlying SIL changes should be merged now to avoid conflicting
with other work. Minor benchmark discrepancies can be investigated as part of
the stack-allocation work.

* Add a noescape attribute to SILFunctionType.

And set this attribute correctly when lowering formal function types to SILFunctionTypes based on @escaping.

This will allow stack allocation of closures, and unblock a related ABI change.

* Flip the polarity on @noescape on SILFunctionType and clarify that
we don't default it.

* Emit withoutActuallyEscaping using a convert_function instruction.

It might be better to use a specialized instruction here, but I'll leave that up to Andy.

Andy: And I'll leave that to Arnold who is implementing SIL support for guaranteed ownership of thick function types.

* Fix SILGen and SIL Parsing.

* Fix the LoadableByAddress pass.

* Fix ClosureSpecializer.

* Fix performance inliner constant propagation.

* Fix the PartialApplyCombiner.

* Adjust SILFunctionType for thunks.

* Add mangling for @noescape/@escaping.

* Fix test cases for @noescape attribute, mangling, convert_function, etc.

* Fix exclusivity test cases.

* Fix AccessEnforcement.

* Fix SILCombine of convert_function -> apply.

* Fix ObjC bridging thunks.

* Various MandatoryInlining fixes.

* Fix SILCombine optimizeApplyOfConvertFunction.

* Fix more test cases after merging (again).

* Fix ClosureSpecializer. Hande convert_function cloning.

Be conservative when combining convert_function. Most of our code doesn't know
how to deal with function type mismatches yet.

* Fix MandatoryInlining.

Be conservative with function conversion. The inliner does not yet know how to
cast arguments or convert between throwing forms.

* Fix PartialApplyCombiner.
2017-10-17 13:07:25 -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
6b12d7d6cf [mandatory-inline] Move fixupReferenceCounts to /before/ inlining.
Once this lands, I can land my commit that turns on ownership for mandatory
inlining.

rdar://31521023
2017-09-13 13:39:32 -07:00
Michael Gottesman
7262673789 [mandatory-inline] Use prev_or_default to simplify code. NFC. 2017-09-12 14:29:43 -07: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
Michael Gottesman
29378a849c [mandatory-inline] Roll some more acceptable callee checks from runOnFunctionRecursively into getCalleeFunction. NFC.
I also did a little bit of cleaning up by converting a couple of

  Type *F = dyn_cast<Type>(X).

To:

  auto *F = dyn_cast<Type>(X).

rdar://31521023
2017-09-11 16:16:07 -07:00
Michael Gottesman
54dbdbc677 [mandatory-inline] Add a note about the weird behavior where II later in Mandatory inlining may no longer be the original apply.
This is one reason for the weird iteration maintainance code in
MandatoryInlining. This comment at least makes it clear what is going on (more
for historical purposes, since I am hoping to fix this soon).

rdar://31521023
2017-09-11 14:07:29 -07:00
Michael Gottesman
5981cc30f5 [mandatory-inline] Refactor out cleanupLoadedCalleeValue from cleanupCalleeValue.
I am refactoring this for two reasons:

1. This code was 60-70% of cleanupCalleeValue, yet cleanupCalleeValue also
performs other tasks. This is a classic situation where one should extract a
subroutine to make cleanupCalleeValue more readable.

2. I am going to be extracting out the cleanup of the callee to be outside the
main inlining loop. Without this refactoring, I would have to use goto to
perform a continue from the inside of an inner for loop of an outer for loop.
Instead by refactoring it this way, I can separate continuing in the inner loop
from continuing in the outer loop.

rdar://31521023
2017-09-10 13:35:07 -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
2722b98003 [mandatory-inlining] Improve readability by using standard loop variable names for instructions, basic blocks.
F{I,E} is generally used for function iterators over a module's functions.
B{I,E} are generally standard for block iterator, block end. I make the II
change just to make it clearer that the given value is an instruction iterator
like in other parts of the SIL Optimizer.

rdar://31521023
2017-09-09 21:17:36 -07:00
swift-ci
cf27ab9d93 Merge pull request #11839 from gottesmm/pr-8aae8140c859cc0621e37aa723e638253cf585b7 2017-09-09 20:04:17 -07:00
Michael Gottesman
600edc32d2 [mandatory-inline] Extract out tryDevirtualizeCode into its own helper function. NFC.
Just trying to slim down/refactor this huge loop.

rdar://31521023
2017-09-09 19:39:29 -07:00
Michael Gottesman
a26ab976c6 [gardening] Convert two typedefs to using. 2017-09-09 16:23:50 -07:00
Michael Gottesman
fc1a639a9e [mandatory-inline] Move the creation of the inliner and bailing upon knowing that inlining will fail, before any side-effect having work occurs.
rdar://31521023
2017-09-08 22:18:07 -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
Erik Eckstein
020a283bbb SIL: Let the OpenedArchetypesTracker be constructed with a null SILFunction.
NFC
2017-08-23 09:15:00 -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
Michael Gottesman
c55c0f8bfd [gardening] Eliminate two else returns. 2017-05-02 10:22:03 -07:00
Michael Gottesman
503774e5a7 [gardening] Standardize usage of auto in if-dyncast pattern in cleanupCalleeValue.
The if-dyncast pattern is this construct:

(1) if (auto *x = dyn_cast<SILInstruction>(f)).

In this function, we were sometimes using 'auto *' and othertimes we were
writing out the full type. This commit standardizes on 'auto *'.
2017-05-02 10:21:58 -07: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
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
a0079ba5be SIL optimizations: Implement the new API for analysis invalidation.
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
2017-03-14 13:00:54 -07:00
Michael Gottesman
81dcdba0a9 Revert "Make sure we always de-serialize transparent functions."
This reverts commit 821b365054.

It caused a bunch of execution time regressions.
2017-02-18 13:36:34 -08:00
Erik Eckstein
821b365054 Make sure we always de-serialize transparent functions.
We didn’t do that if an optimization looked up a witness table.

Fixes rdar://problem/30544344

I couldn’t come up with an isolated test case, but this should be covered with our existing tests.
(The problem shows up when inlining of generics are enabled)
2017-02-16 17:04:58 -08:00
practicalswift
f6b8bc2a5d [gardening] we’d → we'd 2017-01-07 21:07:14 +01:00
practicalswift
a2928fca2d [gardening] can’t → can't 2017-01-07 21:06:15 +01:00
Joe Shajrawi
e2bb8c177d Merge pull request #6635 from shajrawi/thick_func_fix_ref_counts
Mandatory Inlining: Fix a bug wherein we added thick function’s reference count fix-up code at the wrong location
2017-01-06 23:27:54 -08:00
Joe Shajrawi
4ea522bef6 Mandatory Inlining: Fix a bug wherein we added thick function’s reference count fix-up code at the wrong location 2017-01-06 18:41:01 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Slava Pestov
7b82cf8018 SILOptimizer: Fix Mandatory Inlining problem with opened existentials
It looks like an apply of a partial_apply with an opened existential
in the substitutions triggered an assert because the opened
existential was not propagated into the body of the inlined
function.
2016-12-29 13:07:38 -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
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
Michael Gottesman
a8c4cc60e8 [gardening] Rename ValueBase::getParentBB() => getParentBlock(). 2016-11-14 00:39:47 -08:00
Michael Gottesman
362a556af4 [semantic-arc] SILBuilder::emit{Retain,Release}ValueOperation => SILBuilder::emit{Copy,Destroy}ValueOperation.
rdar://28851920
2016-10-25 13:12:52 -07:00
Joe Groff
aac85cb93f SIL: Introduce a 'closure' convention for unapplied invocation functions.
We don't want the machine calling conventions for closure invocation functions to necessarily be tied to the convention for normal thin functions or methods. NFC yet; for now, 'closure' follows the same behavior as the 'method' convention, but as part of partial_apply simplification it will be a requirement that partial_apply takes a @convention(closure) function and a box and produces a @convention(thick) function from them.
2016-10-17 15:55:04 -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
Slava Pestov
a993e36c06 AST: Add a new SubstitutionMap data structure
This replaces the TypeSubstitutionMap / ConformanceMap pair that
has been appearing more and more lately.
2016-09-08 21:59:11 -07:00
Slava Pestov
ca0b548584 SIL: Replace SILFunction::ContextGenericParams with a GenericEnvironment
This patch is rather large, since it was hard to make this change
incrementally, but most of the changes are mechanical.

Now that we have a lighter-weight data structure in the AST for mapping
interface types to archetypes and vice versa, use that in SIL instead of
a GenericParamList.

This means that when serializing a SILFunction body, we no longer need to
serialize references to archetypes from other modules.

Several methods used for forming substitutions can now be moved from
GenericParamList to GenericEnvironment.

Also, GenericParamList::cloneWithOuterParameters() and
GenericParamList::getEmpty() can now go away, since they were only used
when SILGen-ing witness thunks.

Finally, when printing generic parameters with identical names, the
SIL printer used to number them from highest depth to lowest, by
walking generic parameter lists starting with the innermost one.
Now, ambiguous generic parameters are numbered from lowest depth
to highest, by walking the generic signature, which means test
output in one of the SILGen tests has changed.
2016-08-28 13:51:37 -07:00
Roman Levenstein
62e5b77cac [sil-mandatory-inliner] Decrease the compile time
The inlining algorithm was rescanning the whole basic block after inlining a call, which resulted in O(N^2) time complexity. In some pathological cases like e.g. huge basic blocks with many thousands of calls this would lead to very long compile times which could takes hours to finish.

This change improves compile times by avoiding the rescanning of basic blocks containing the call which was inlined.

rdar://27818830
2016-08-23 23:15:29 -07:00
Slava Pestov
b8ae9c1391 AST: Refactor GenericParamList::getSubstitutionMap() to take a GenericSignature, NFC
This function takes a substitution array and produces a
contextual type substitution map, so it is the contextual
type equivalent of GenericSignature::getSubstitutionMap(),
which produces an interface type substitution map.

The new version takes a GenericSignature, just like the new
getForwardingSubstitutions(), so that it can walk the
requirements of the signature rather than walking the
AllArchetypes list.

Also, this new version now produces a mapping from
archetypes to conformances in addition to the type mapping,
which will allow it to be used in a few places that had
hand-coded logic.
2016-08-22 10:45:51 -07:00
Saleem Abdulrasool
365c7b38be SIL: update for SVN r277399
SVN r277399 introduced a new typedef requirement for the traits type.
2016-08-13 09:26:13 -07:00
Roman Levenstein
794d72e923 Track dependencies of SIL instructions on opened archetypes which they use
Till now there was no way in SIL to explicitly express a dependency of an instruction on any opened archetypes used by it. This was a cause of many errors and correctness issues. In many cases the code was moved around without taking into account these dependencies, which resulted in breaking the invariant that any uses of an opened archetype should be dominated by the definition of this archetype.

This patch does the following:
- Map opened archetypes to the instructions defining them, i.e. to open_existential instructions.
- Introduce a helper class SILOpenedArchetypesTracker for creating and maintaining such mappings.
- Introduce a helper class SILOpenedArchetypesState for providing a read-only API for looking up available opened archetypes.
- Each SIL instruction which uses an opened archetype as a type gets an additional opened archetype operand representing a dependency of the instruction on this archetype. These opened archetypes operands are an in-memory representation. They are not serialized. Instead, they are re-constructed when reading binary or textual SIL files.
- SILVerifier was extended to conduct more thorough checks related to the usage of opened archetypes.
2016-06-28 08:43:01 -07:00
swiftix
be27850aa2 Revert "Track dependencies of SIL instructions on opened archetypes which they use" 2016-06-24 21:25:08 -07:00
Roman Levenstein
9d4fc913d9 Track dependencies of SIL instructions on opened archetypes which they use
Till now there was no way in SIL to explicitly express a dependency of an instruction on any opened archetypes used by it. This was a cause of many errors and correctness issues. In many cases the code was moved around without taking into account these dependencies, which resulted in breaking the invariant that any uses of an opened archetype should be dominated by the definition of this archetype.

This patch does the following:
- Map opened archetypes to the instructions defining them, i.e. to open_existential instructions.
- Introduce a helper class SILOpenedArchetypesTracker for creating and maintaining such mappings.
- Introduce a helper class SILOpenedArchetypesState for providing a read-only API for looking up available opened archetypes.
- Each SIL instruction which uses an opened archetype as a type gets an additional opened archetype operand representing a dependency of the instruction on this archetype. These opened archetypes operands are an in-memory representation. They are not serialized. Instead, they are re-constructed when reading binary or textual SIL files.
- SILVerifier was extended to conduct more thorough checks related to the usage of opened archetypes.
2016-06-24 10:36:52 -07:00
Xin Tong
4526e88bef Revert "Track dependencies of SIL instructions on opened archetypes which they use"
This reverts commit 8ef8bb4eb1.

Broke swift_tools-RA_stdlib-RD_test-no_device and soem others
2016-06-22 18:17:25 -07:00
swiftix
d10aa3f7ff Merge pull request #2928 from swiftix/wip-opened-archetypes-v3
Track dependencies of SIL instructions on opened archetypes which they use.
2016-06-22 14:34:26 -07:00
Roman Levenstein
8ef8bb4eb1 Track dependencies of SIL instructions on opened archetypes which they use
Till now there was no way in SIL to explicitly express a dependency of an instruction on any opened archetypes used by it. This was a cause of many errors and correctness issues. In many cases the code was moved around without taking into account these dependencies, which resulted in breaking the invariant that any uses of an opened archetype should be dominated by the definition of this archetype.

This patch does the following:
- Map opened archetypes to the instructions defining them, i.e. to open_existential instructions.
- Introduce a helper class SILOpenedArchetypesTracker for creating and maintaining such mappings.
- Introduce a helper class SILOpenedArchetypesState for providing a read-only API for looking up available opened archetypes.
- Each SIL instruction which uses an opened archetype as a type gets an additional opened archetype operand representing a dependency of the instruction on this archetype. These opened archetypes operands are an in-memory representation. They are not serialized. Instead, they are re-constructed when reading binary or textual SIL files.
- SILVerifier was extended to conduct more thorough checks related to the usage of opened archetypes.
2016-06-22 14:28:39 -07:00
Erik Eckstein
d23551a25b Don't generate code for transparent functions.
They are mandatory inlined anyway. Therefore the binary code of transparent functions is not used in most cases.
In case the address of a transparent function is taken, the main program (which deserialized the transparent function) generates code for it and treats it as shared function.

This reduces the stdlib code size by 2.8%.
2016-06-16 15:59:00 +02:00
Slava Pestov
8f038cead4 SIL: Stricter asserts for non-fragile references from fragile functions
Building off of the previous patches, add stricter assertions to
inlining passes and SIL serialization.
2016-04-08 02:16:30 -07:00
Erik Eckstein
74d44b74e7 SIL: remove SILValue::getDef and add a cast operator to ValueBase * as a repelacement. NFC. 2016-01-25 15:00:49 -08:00