The two methods on FunctionSignatureTransform in question:
createOptimizedSILFunctionName()
createOptimizedSILFunctionType()
are pure computation on the transform descriptor on the
FunctionSignatureTransform. So there really isn't a reason not to make it a
getter method on FunctionSignatureTransformDescriptor. This helps me to thin out
FunctionSignatureTransform even further in prepration for splitting it.
This is something that has been talked about for some time. By splitting up
function signature optimization into several smaller "transforms" that can be
composed, we are able to test each transform individually as well as make it
easier to add more optimizations. Hopefully, other function signature
optimizations we currently perform with separate passes can be combined into
this framework.
NFC.
We never push_back additional such items onto the descriptor lists once the
transform is constructed. We do on the other hand, potentially modify those
items in the vector. That suggests that this property is better represented by
the "simpler" MutableArrayRef.
Check that an ``withoutActuallyEscaping(noescape_closure) { // scope}`` closure
has not escaped in the scope using the ``is_escaping_closure %closure``
instruction.
rdar://35525730
Will be used to verify that withoutActuallyEscaping's block does not
escape the closure.
``%escaping = is_escaping_closure %closure`` tests the reference count. If the
closure is not uniquely referenced it prints out and error message and
returns true. Otherwise, it returns false. The returned result can be
used with a ``cond_fail %escaping`` instruction to abort the program.
rdar://35525730
A couple of lines of boilerplate simplies life. It's always nice when the
Transform class matches the formal pass definition. This way, the back trace
doesn't point you to the wrong transform.
There's no good reason to share Transform classes that I know of.
This patch both makes debug variable information it optional on
alloc_stack and alloc_box instructions, and forced variable
information on debug_value and debug_value_addr instructions. The
change of the interface uncovered a plethora of bugs in SILGen,
SILTransform, and IRGen's LoadableByAddress pass.
Most importantly this fixes the previously commented part of the
DebugInfo/local-vars.swift.gyb testcase.
rdar://problem/37720555
If the pass does not register a new function, that new function will never be
passed through the current function pipeline. We were getting lucky that enough
of the mandatory passes were module passes that it didn't seem to matter in
practice (until I convert them to function passes).
(after pass reorganization, a one line fix that doesn't rely on
outrageous changes to the pass' function signatures.)
In preparation for fixing a bug.
- Separate general SIL utilities, liveness, escape analysis,
and promotion.
- Give promotion routines access to the current pass.
Ideally, the current pass would be accessible via TLS. In the meantime,
pass routines should always have access to a state object that
encapsulates the pass information corresponding to a single invocation
of the pass.
Access to the pass' state should be consistent and idiomatic; it should
not depend on the where we are in the call stack. This makes the code much easier to understand and refactor, and it enables exploratory changes.
Now we will consistently expand destroy_addr/copy_addr into either
{retain,release}_value or into ARC operations on its most derived descendents.
This will improve code-size (by not expanding when we didn't intend to), but
more importantly preserve invariants that the ARC optimizer depends upon.
rdar://36509461
This enum controls how certain routines in TypeLowering potentially expand types
when performing copy_value/destroy_value operations. Its previous form was
problematic because:
1. The name LoweringStyle does't suggest anything related to expansion really.
The new has the word expansion in it explicitly.
2. The cases of LoweringStyle used to be Shallow, Deep. This caused confusion
since Shallow (the base case) was not a no-op. It just caused us to expand into
children. Now TypeExpansionKind has 3 cases to make this clear: None,
DirectChildren, and MostDerivedDescendents.
Confusion around this API caused us to canonicalize ARC operations differently
for different operations (e.g. copy_value/destroy_value vs
copy_addr/destroy_addr). This caused us to misout on some code-size wins (since
we were splitting some operations onto DirectChildren of aggregates), but more
importantly also caused the optimizer to break an invariant that the ARC
optimizer relied upon: local semantic pairings being at the same level of
abstraction. In a subsequent commit, I am going to fix that bug.
rdar://36509461
It's the correct thing to do, as we immediately switch the current
debug scope. In this case, it's NFC as the code was already doing
the right thing, but this is more concise/harder to get wrong.
Also: add an additional DeadObjectElimination pass in the low level pipeline because
redundant load elimination (which runs before) can turn an object into a dead object.
* allow small class methods to be inlined with -Osize
* inline pure calls: references to objects, which are initialized with constants, are considered as constant arguments
We run GlobalOpt multiple times in the pass pipeline but in some cases object outlining shouldn't be done too early.
Having it done in a separate pass enables to run it independently from GlobalOpt.
This enables to optimize chains of constant-foldable terminal instructions, for which we would have needed multiple ConstantPropagaion-SimplifyCFG pass pairs in the pipeline otherwise.
See the test file for an example.