The goal here is to make the short demangling as short and readable as possible, also at the cost of omitting some information.
The assumption is that whenever the short demangling is displayed, there is a way for the user to also get the full demangled name if needed.
*) omit <where ...> because it does not give useful information anyway
Deserializer.deserialize<A where ...> () throws -> [A]
--> Deserializer.deserialize<A> () throws -> [A]
*) for multiple specialized functions only emit a single “specialized”
specialized specialized Constructible.create(A.Element) -> Constructible<A>
--> specialized Constructible.create(A.Element) -> Constructible<A>
*) Don’t print function argument types:
foo(Int, Double, named: Int)
--> foo(_:_:named:)
This is a trade-off, because it can lead to ambiguity if there are overloads with different types.
*) make contexts of closures, local functions, etc. more readable by using “<a> in <b>” syntax
This is also done for the full and not only for the simplified demangling.
Renderer.(renderInlines([Inline]) -> String).(closure #1)
--> closure #1 in Renderer.renderInlines
*) change spacing, so that it matches our coding style:
foo <A> (x : A)
--> foo<A>(x: A)
The reason why this needs to be done is that we represent class pointers as
guaranteed, but we need to pass them as inout, violating the guaranteed
assumption. The truth is, we should be passing them in guaranteed but due to the
large required AST changes needed, we do not today.
Since we model this as an inout today, SILGen rightfully tries to use a store
[init] which is consuming. This commit works around that issue by using a
store_guaranteed.
rdar://29791263
Instead of appending a character for each substitution, we now prefix the substitution with the repeat count, e.g.
AbbbbB -> A5B
The same is done for known-type substitutions, e.g.
SiSiSi -> S3i
This significantly shrinks mangled names which contain large lists of the same type, like
func foo(_ x: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int))
rdar://problem/30707433
First, use the correct generic environment to compute the substituted
storage type. Substitutions derived from 'self' are not enough,
because we also want the archetypes of the generic subscript's
innermost generic parameters.
Also, use the method and witness_method calling conventions for the
materializeForSet callback, depending on if we have a protocol
witness or concrete implementation.
Since the materializeForSet callback is called with a more
abstract type at the call site than the actual function type
of the callback, we used to rely on these two SIL types being
ABI compatible:
@convention(thin) <Self : P, T, U) (..., Self.Type) -> ()
@convention(thin) <T, U> (..., Foo<T, U>.Type) -> ()
The IRGen lowering is roughly the following -- the call site
passes two unused parameters, but that's fine:
(..., Self.Type*, Self.Type*, Self.P*)
(..., Foo<T, U>.Type*)
However if the callback has its own generic parameters because
the subscript is generic, we might have SIL types like so,
@convention(thin) <Self : P, T, U, V) (..., Self.Type) -> ()
@convention(thin) <T, U, V> (..., Foo<T, U>.Type) -> ()
And the IRGen lowering is the following:
(..., Self.Type*, Self.Type*, Self.P*, V.Type*)
(..., Foo<T, U>.Type*, V.Type*)
The parameters no longer line up, because the caller still passes
the two discarded arguments, and type metadata for V cannot be
derived from the Self metadata so must be passed separately.
The witness_method calling convention is designed to solve this
problem; it puts the Self metadata and protocol conformance last,
so if you have these SIL types:
@convention(witness_method) <Self : P, T, U, V) (..., swiftself Self.Type) -> ()
@convention(witness_method) <T, U, V> (..., swiftself Foo<T, U>.Type) -> ()
The IRGen lowering is the following:
(..., Self.Type*, V.Type*, Self.Type*, Self.P*)
(..., Foo<T, U>.Type*, V.Type*, Self.Type*, unused i8*)
However, the problem is now that witness_method and thin functions
are not ABI compatible, because thin functions don't have a
distinguished 'self', which is passed differently in LLVM's swiftcc
calling convention:
@convention(witness_method) <Self : P, T, U, V) (..., Self.Type) -> ()
@convention(thin) <T, U, V> (..., Foo<T, U>.Type) -> ()
So instead of using 'thin' representation for the concrete callback
case, use 'method', which is essentially the same as 'thin' except if
the last parameter is pointer-size, it is passed as the 'self' value.
This makes everything work out.
new API called ManagedValue::unmanagedBorrow() for places where we were really trying to model
an exclusive borrow.
ManagedValue::unmanagedBorrow() is just the old implementation.
rdar://29791263
Keep in mind that these are approximations that will not impact correctness
since in all cases I ensured that the SIL will be the same after the
OwnershipModelEliminator has run. The cases that I was unsure of I commented
with SEMANTIC ARC TODO. Once we have the verifier any confusion that may have
occurred here will be dealt with.
rdar://28685236
Implements SE-0055: https://github.com/apple/swift-evolution/blob/master/proposals/0055-optional-unsafe-pointers.md
- Add NULL as an extra inhabitant of Builtin.RawPointer (currently
hardcoded to 0 rather than being target-dependent).
- Import non-object pointers as Optional/IUO when nullable/null_unspecified
(like everything else).
- Change the type checker's *-to-pointer conversions to handle a layer of
optional.
- Use 'AutoreleasingUnsafeMutablePointer<NSError?>?' as the type of error
parameters exported to Objective-C.
- Drop NilLiteralConvertible conformance for all pointer types.
- Update the standard library and then all the tests.
I've decided to leave this commit only updating existing tests; any new
tests will come in the following commits. (That may mean some additional
implementation work to follow.)
The other major piece that's missing here is migration. I'm hoping we get
a lot of that with Swift 1.1's work for optional object references, but
I still need to investigate.
The function pointer is a thin function and possibly polymorphic,
so it does not really have an AST type. Instead of pretending it has
an AST type, just return a RawPointer and remove some casts in the
process.
We don't want to perform substitutions when we call the materializeForSet
accessor itself, since the return value is a polymorphic thin function,
and its calling convention is not compatible with a concretely-typed
function value in the case where 'Self' is an abstract type parameter.
With this change, the materializeForSet declaration still has an AST type
for the callback in its return value, but since this AST type makes no
sense in reality it would be better to just return a RawPointer instead,
removing some unnecessary code from CodeSynthesis.cpp. This will be
cleaned up in a subsequent patch.
We don't want to perform substitutions when we call the materializeForSet
accessor itself, since the return value is a polymorphic thin function,
and its calling convention is not compatible with a concretely-typed
function value in the case where 'Self' is an abstract type parameter.
With this change, the materializeForSet declaration still has an AST type
for the callback in its return value, but since this AST type makes no
sense in reality it would be better to just return a RawPointer instead,
removing some unnecessary code from CodeSynthesis.cpp. This will be
cleaned up in a subsequent patch.
Similarly to how we've always handled parameter types, we
now recursively expand tuples in result types and separately
determine a result convention for each result.
The most important code-generation change here is that
indirect results are now returned separately from each
other and from any direct results. It is generally far
better, when receiving an indirect result, to receive it
as an independent result; the caller is much more likely
to be able to directly receive the result in the address
they want to initialize, rather than having to receive it
in temporary memory and then copy parts of it into the
target.
The most important conceptual change here that clients and
producers of SIL must be aware of is the new distinction
between a SILFunctionType's *parameters* and its *argument
list*. The former is just the formal parameters, derived
purely from the parameter types of the original function;
indirect results are no longer in this list. The latter
includes the indirect result arguments; as always, all
the indirect results strictly precede the parameters.
Apply instructions and entry block arguments follow the
argument list, not the parameter list.
A relatively minor change is that there can now be multiple
direct results, each with its own result convention.
This is a minor change because I've chosen to leave
return instructions as taking a single operand and
apply instructions as producing a single result; when
the type describes multiple results, they are implicitly
bound up in a tuple. It might make sense to split these
up and allow e.g. return instructions to take a list
of operands; however, it's not clear what to do on the
caller side, and this would be a major change that can
be separated out from this already over-large patch.
Unsurprisingly, the most invasive changes here are in
SILGen; this requires substantial reworking of both call
emission and reabstraction. It also proved important
to switch several SILGen operations over to work with
RValue instead of ManagedValue, since otherwise they
would be forced to spuriously "implode" buffers.
For long names this is easier to read and in most cases the omitted information can be seen in the actual SIL code.
With the option -Xllvm -sil-full-demangle the old behavior can be restored.
Having a separate address and container value returned from alloc_stack is not really needed in SIL.
Even if they differ we have both addresses available during IRGen, because a dealloc_stack is always dominated by the corresponding alloc_stack in the same function.
Although this commit quite large, most changes are trivial. The largest non-trivial change is in IRGenSIL.
This commit is a NFC regarding the generated code. Even the generated SIL is the same (except removed #0, #1 and @local_storage).
As part of this, I've made the demangler base the colon-vs.-not
decision on the entity kind instead of assuming that anything
with a function type must be a function. It also looks through
new-style generics when it didn't before.
Swift SVN r28814
The only caveat is that:
1. We do not properly recognize when we have a let binding and we
perform a guaranteed dynamic call. In such a case, we add an extra
retain, release pair around the call. In order to get that case I will
need to refactor some code in Callee. I want to make this change, but
not at the expense of getting the rest of this work in.
2. Some of the protocol witness thunks generated have unnecessary
retains or releases in a similar manner.
But this is a good first step.
I am going to send a large follow up email with all of the relevant results, so
I can let the bots chew on this a little bit.
rdar://19933044
Swift SVN r27241
Most tests were using %swift or similar substitutions, which did not
include the target triple and SDK. The driver was defaulting to the
host OS. Thus, we could not run the tests when the standard library was
not built for OS X.
Swift SVN r24504
use a thin function type.
We still need thin-function-to-RawPointer conversions
for generic code, but that's fixable with some sort of
partial_apply_thin_recoverable instruction.
Swift SVN r24364
optional callback; retrofit existing implementations.
There's a lot of unpleasant traffic in raw pointers here
which I'm going to try to clean up.
Swift SVN r24123
teach SILGenLValue that let values guarantee the lifetime of their value for at least
the duration of whatever expression references the let value. This allows us to eliminate
retains/release pairs in a lot of cases, and provides more value for people to use let
instead of var. This combines particularly well with +0 self arguments (currently just
protocol/archetype dispatches, but perhaps someday soon all method dispatches).
Thanks to John for suggesting this.
Swift SVN r24004
or pointer depends on another for validity in a
non-obvious way.
Also, document some basic value-propagation rules
based roughly on the optimization rules for ARC.
Swift SVN r23695
conservatively copying them.
Also, fix a number of issues with mutating getters that
I noticed while examining and changing this code. In
particular, stop relying on suppressing writeback scopes
during loads.
Fixes rdar://19002913, a bug where an unnecessary copy of
an array for a getter call left the array in a non-unique
state when a subsequent mutation occurred.
Swift SVN r23642