Previously we were:
1. Doing a linear scan, performing certain optimizations, and setting up a
worklist for future processing.
2. Draining the worklist of changed instructions until we reached a fix point.
The key thing here is that for (1) to be safe, we would need to not perform any
optimizations on block arguments since there was an ssumption that we would only
perform SSA-like optimizations.
I am going to be adding such optimizations soon, so it makes sense to just
convert the initial traversal to non-destructively seed the worklist and
eliminate that initial optimization pass.
This should be NFC.
Create a Predecessor abstraction for readability. Eliminates frequent
occurence of inscrutable getInt() and getPointer() calls.
Create an escapesInsideFunction() API that only uses mapped
values. This prevents bugs where a content node's value would be
mistakenly used to check for escapes.
This is a first version of cross module optimization (CMO).
The basic idea for CMO is to use the existing library evolution compiler features, but in an automated way. A new SIL module pass "annotates" functions and types with @inlinable and @usableFromInline. This results in functions being serialized into the swiftmodule file and thus available for optimizations in client modules.
The annotation is done with a worklist-algorithm, starting from public functions and continuing with entities which are used from already selected functions. A heuristic performs a preselection on which functions to consider - currently just generic functions are selected.
The serializer then writes annotated functions (including function bodies) into the swiftmodule file of the compiled module. Client modules are able to de-serialize such functions from their imported modules and use them for optimiations, like generic specialization.
The optimization is gated by a new compiler option -cross-module-optimization (also available in the swift driver).
By default this option is off. Without turning the option on, this change is (almost) a NFC.
rdar://problem/22591518
This is needed for cross-module-optimization: CMO marks functions as inlinable. If a private or internal method is referenced from such an inlinable function, it must not be eliminated by dead function elimination after serialization (a method is basically an AbstractFunctionDecl).
For SILFunctions we can do this by simply setting the linkage, but for methods we need another mechanism.
All the context dependencies in SIL type lowering have been eradicated, but IRGen's
type info lowering is still context-dependent and doesn't systemically pass generic
contexts around. Sink GenericContextScope bookkeeping entirely into IRGen for now.
Lowering a SIL type should be a pure function of the formal type of a value and the
abstraction pattern it's being lowered against, but we historically did not carry
enough information in abstraction patterns to lower generic parameter types, so we
relied on a generic context signature that would be pushed and popped before lowering
interface types. This patch largely eliminates the necessity for that, by making it
so that `TypeClassifierBase` and its subclasses now take an `AbstractionPattern`
all the way down, and fixing up the visitor logic so that it derives appropriate
abstraction patterns for tuple elements, function arguments, and aggregate fields too.
This makes it so that type lowering is independent of the current generic context.
(Unfortunately, there are still places scattered across the code where we use the
current generic context in order to build abstraction patterns that we then feed
into type lowering, so we can't yet completely eliminate the concept.)
This then enables us to integrate substituted function type construction into type
lowering as well, since we can now lower a generic parameter type against an
abstraction pattern without that generic parameter having to be tied to the same
generic signature (or any generic signature at all, which in the case of a
substituted function type hasn't necessarily even been finalized yet.)
Now the condition matches exactly what's checked in asserts in SILBuilder.
fixes an assert in the PerformanceInliner
https://bugs.swift.org/browse/SR-11817
rdar://problem/57369847
These are separate, mostly unrelated passes. Putting them in their own
files makes it easier to read the code, understand how to control the
passes, and makes it possible to independently trace, and debug them.
The hook is intended to be used by debuggers to catch the point a `throw` happened in user source. It's unnecessary and undesirable to hook in places where an already-thrown error is just being implicitly propagated.
The cast optimizer was too eager to fold casts where the source and
target lowered types were the same, even though the formal types
might be different. Move the classifyFeasibility() check to deal
with this case.
Also in dead code elimination we have to mark all operands of a
cast branch instruction as live, not just the first operand,
otherwise we miss the special 'type dependent' self metadata
operand and replace it with 'undef'.
The ExistentialSpecializer incorrectly assumed that an existential's conformances match an opened archetype. They don't. Opened archetypes strip inherited conformances per the ABI for generic argument passing. Existential values retain those inherited conformances (for some inexplicable reason).
- Rename ASTContext::getExistentialSignature() to
getOpenedArchetypeSiganture() because it was doing exactly the wrong
thing for existentials.
- Fix ConcreteExistentialInfo to produce the correct SubstitutionMap.
- Fix ExistentialSpecializer to generate the correct conformances for
init_existential by adding a collectExistentialConformances() helper.
Fixes <rdar://problem/57025861> "Assertion failed: (conformances.size() == numConformanceRequirements)" in ExistentialSpecializer on inlined code