Print the SIL function body on an assert. Recovering the SIL code is the
critical path for pretty much any SIL development. The only alternative is
rebuilding the library with string matching or building a debug compiler and
hoping lldb works. The standard library takes a very long time to build with a
debug compiler.
Storing this separately is unnecessary since we already
serialize the enum element's interface type. Also, this
eliminates one of the few remaining cases where we serialize
archetypes during AST serialization.
Formal types are defined by the language's type system. SIL types are
lowered. They are no longer part of that type system.
The important distinction here is between the SIL storage type and the SIL value
type. To make this distinction clear, I refer to the SILFunctionTypes "formal"
conventions. These conventions dictate the SIL storage type but *not* the SIL
value type. I call them "formal" conventions because they are an immutable
characteristic of the function's type and made explicit via qualifiers on the
function type's parameters and results. This is in contrast to to SIL
conventions which depend on the SIL stage, and in the short term whether the
opaque values flag is enabled.
Pass correct argument indices to the mangler for function specialization. This
has probably always been broken. The demangler doesn't support these manglings
anyway. It doesn't seem to have mattered in practice yet (aside from the
confusion of devs) like me. It will matter once we begin exposing public
specializations.
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.
Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.
Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
Names matter. When using an unsigned int to index arguments, always make it
clear what the index refers to. It is a particularly confusing in this code because:
- mangling should not care about argument indices at all, only the function type should matter.
- argument indices for a given function type may be different depending on the SIL stage.
- these indices are actually a contract between the client code and the mangler.
- the specialized function's argument indices are different than the original indices!
This issue was hiding bugs in the mangler. The bug fixes will be in a separate PR.
Remove unused function as identified during a normal compilation:
swift/lib/SILOptimizer/Transforms/StackPromotion.cpp:303:15: warning: unused function 'operator!=' [-Wunused-function]
@_specialize is not fully enabled right now, and there is code which
has been preprocessed away. There were some declarations that were left
behind. This removes them to avoid the unused warning/unused
function/unused private member warnings. NFC.
The reason why I am introducing special instructions is so I can maintain the
qualified ownership API wedge in between qualified SIL and the rest of the ARC
instructions that are pervasively used in the compiler.
These instructions in the future /could/ be extended to just take @sil_unmanaged
operands directly, but I want to maintain flexibility to take regular
non-trivial operands in the short term.
rdar://29791263
A witness table is dead if it is not used outside the module (private/internal) and it’s not used by any instruction or other witness table in the module.
Also the meta-type of the conforming type must not escape, because it’s possible to test any opaque type if it conforms to a protocol.
rdar://problem/23026019
Separate collecting the applies and devirtualizing them into two loops.
We run into an issue on a huge test case where we end up devirtualizing a call-site over and over again.
I have not been able to reduce a test case.
rdar://29785529
Most of this involved sprinkling ValueOwnershipKind::Owned in many places. In
some of these places, I am sure I was too cavalier and I expect some of them to
be trivial. The verifier will help me to track those down.
On the other hand, I do expect there to be some places where we are willing to
accept guaranteed+trivial or owned+trivial. In those cases, I am going to
provide an aggregate ValueOwnershipKind that will then tell SILArgument that it
should disambiguate using the type. This will eliminate the ackwardness from
such code.
I am going to use a verifier to fix such cases.
This commit also begins the serialization of ValueOwnershipKind of arguments,
but does not implement parsing of value ownership kinds. That and undef are the
last places that we still use ValueOwnershipKind::Any.
rdar://29791263
This in the case of insertFunctionArgument requires a ValueOwnershipKind to be
specified since we use that for transformations of function argument lists that
are only correct after the transformation is complete. This only occurs in
FunctionSignatureOptimizations.
On the other hand, createFunctionArgument is only used to construct completely
new argument lists, so we can instead just rely on the function we are in rather
than require the user to pass it in.
rdar://29791263
This is dead code and can be re-added if it is needed. Right now though there
really isnt a ValueOwnershipKind that corresponds to deallocating and I do not
want to add a new ValueOwnershipKind for dead code.
Handling address_to_pointer as a plain inout missed some mutations and lead to miscompiles.
We now treat address_to_pointer as escaping address.
Fixes SR-3554
If a generic parameter was substituted for Self, we have to be careful
to not erase Self.Type down to a concrete metatype.
Also, teach the devirtualizer that a metatype of Self type does not
have an exact static type.
This shows up in an assert in RLE, but is very hard to reproduce.
The problem was that the reference to the Values map element is potentially invalidated when assigning to the Values map in this line:
Values[Base] = FirstVal.stripLastLevelProjection();
hopefully fixes rdar://problem/29922800
The ASI->eraseFromParent() call after removeSingleBlockAllocation(ASI)
will assert if there are any remaining uses of the allocation ASI. This can
happen if there are any dead instructions for struct or tuple address
projections, since removeSingleBlockAllocation only removes the instructions
that are actually used by loads and stores. The existing stdlib/subString.swift
test exposes this issue when running check-swift-optimize.
rdar://problem/28671838