With the option -sil-print-debuginfo the printing of debug locations and scopes can be enabled.
I made the default for the option “false”, because in 99% of the time I don’t need the debug info in the printed SIL and I prefer better readability.
I put in a simple fixup pass (MarkUninitializedFixup) for staging purposes. I
don't expect it to be in tree long. I just did not feel comfortable fixing up in
1 commit all of the passes up to DI.
rdar://31521023
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)
We used to give witness thunks public linkage if the
conforming type and the protocol are public.
This is completely unnecessary. If the conformance is
fragile, the thunk should be [shared] [serialized],
allowing the thunk to be serialized into callers after
devirtualization.
Otherwise for private protocols or resilient modules,
witness thunks can just always be private.
This should reduce the size of compiled binaries.
There are two other mildly interesting consequences:
1) In the bridged cast tests, we now inline the witness
thunks from the bridgeable conformances, which removes
one level of indirection.
2) This uncovered a flaw in our accessibility checking
model. Usually, we reject a witness that is less
visible than the protocol; however, we fail to
reject it in the case that it comes from an
extension.
This is because members of an extension can be
declared 'public' even if the extended type is not
public, and it appears that in this case the 'public'
keyword has no effect.
I would prefer it if a) 'public' generated a warning
here, and b) the conformance also generated a warning.
In Swift 4 mode, we could then make this kind of
sillyness into an error. But for now, live with the
broken behavior, and add a test to exercise it to ensure
we don't crash.
There are other places where this "allow public but
ignore it, kinda, except respect it in some places"
behavior causes problems. I don't know if it was intentional
or just emergent behavior from general messiness in Sema.
3) In the TBD code, there is one less 'failure' because now
that witness thunks are no longer public, TBDGen does not
need to reason about them (except for the case #2 above,
which will probably require a similar workaround in TBDGen
as what I put into SILGen).
This generalizes a hack where re-abstraction thunks become fragile on contact
with fragile functions.
The old policy was:
- [fragile] functions always serialized
- [reabstraction_thunk] transitively referenced from fragile always serialized
The new policy is:
- [serialized] functions always serialized
- [serializable] functions transitively referenced from serialized functions
are always serialized
- Most kinds of thunks can now be [serializable], allowing them to be shared
between serialized and non-serialized code without any issues, as long as the
body of the thunk is sufficiently "simple" (doesn't reference private
symbols or performs direct access to resilient types)
This changes the order in which declarations are emitted.
It also means we no longer emit a vtable entry for the
materializeForSet of dynamic storage. Neither of these are
intended to have any functional effect.
This is in preparation for removing the +0 self hack.
This commit in more detail does the following:
1. It adds Formal Evaluation Scopes to certain places where the scopes were
missing. Specifically:
a. The SILGenLValue cases are places where we are invoking accessors. In each
one of these cases, we had a formal evaluation scope in the accessor
itself, but we did not have a scope that closed over the base access and
the accessor access. The base access is a formal evaluation in the sense
that just like with inout bases, we must create a new reference to the
base and re-destroy the base in a chain of accesses. This is to ensure
that we do not extend the lifetime of the base inappropriately.
b. The SILGenPoly case is a place where we have never properly placed a
Formal Evaluation Scope and have completely been relying on the +0 self
hack to make sure that archetype callees are properly destroyed
immediately after a +0 call.
2. It changes all of the places in SILGen that emit self to using formal access
cleanups instead of normal cleanups.
rdar://29791263
Everything here should be NFC after the ownership model eliminator except for 1
change where translation of unowned parameters is made more
correct. Specifically:
1. In manageParam, we make it so that if we allow PlusZero, we begin an actual
begin_borrow, end_borrow sequence. We can do this unconditionally since if the
passed in SILValue is already borrowed, we just return early.
2. In TranslateArguments::translateSingle(), we used to handle owned, unowned,
and guaranteed parameters all the same way. This is of course incorrect. Now we
do the following:
a. If our final translated value is guaranteed, but we want an unowned or
owned parameter, then we perform a copyUnmanaged().
b. If our final translated value is unowned and our argument must be a
guaranteed value, then we first transition the unowned value to an owned value
using SILGen::emitManagedRetain() and then transition from owned to guaranteed
using a emitBeginBorrow().
c. If our final translated value is owned and our argument must be a
guaranteed value, then we perform an emitBeginBorrow().
3. In forwardFunctionArguments(), if our argument requires a guaranteed
argument, we begin a begin borrow sequence.
rdar://29791263
Textual SIL was sometimes ambiguous when SILDeclRefs were used, because the textual representation of SILDeclRefs was the same for functions that have the same name, but different signatures.
Textual SIL was sometimes ambiguous when SILDeclRefs were used, because the textual representation of SILDeclRefs was the same for functions that have the same name, but different signatures.
Officially kick SILBoxType over to be "nominal" in its layout, with generic layouts structurally parameterized only by formal types. Change SIL to lower a capture to a nongeneric box when possible, or a box capturing the enclosing generic context when necessary.
Use a syntax that declares the layout's generic parameters and fields,
followed by the generic arguments to apply to the layout:
{ var Int, let String } // A concrete box layout with a mutable Int
// and immutable String field
<T, U> { var T, let U } <Int, String> // A generic box layout,
// applied to Int and String
// arguments
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
Recently I changed the ArchetypeBuilder is minimize requirements
in generic signatures. However substitution lists still contained
all recursively-expanded nested types.
With recursive conformances, this list becomes potentially
infinite, so we can't expand it out anymore. Also, it is just
a waste of time to have them there.
This ensures that ownership is properly propagated forward through the use-def
graph.
This was the work that was stymied by issues relating to SILBuilder performing
local ARC dataflow. I ripped out that local dataflow in 6f4e2ab and added a
cheap ARC guaranteed dataflow pass that performs the same optimization.
Also in the process of doing this work, I found that there were many SILGen
tests that were either pattern matching in the wrong functions or had wrong
CHECK lines (for instance CHECK_NEXT). I fixed all of these issues and also
expanded many of the tests so that they verify ownership. The only work I left
for a future PR is that there are certain places in tests where we are using the
projection from an original value, instead of a copy. I marked those with a
message SEMANTIC ARC TODO so that they are easy to find.
rdar://28685236
This ensures that we can write FileCheck patterns that match the end of sil
functions. Just using a FileCheck pattern against a brace is not sufficient in
the context of checking the SIL emitted by SILGen. This is because we could match a
different function's body and match the closing brace against the other
function's end brace.
With this change, one can be specific by checking:
// CHECK: } {{.*}} end sil function '<mangled name>'
The inspiration for this change is rdar://28685236. While updating SILGen tests
for that I have found many instances of SILGen tests pattern matching against
the wrong function bodies. This change will allow me to eliminate these problems
robustly.
rdar://29077869
Previously IRGen was using a heuristic to assign the argument number
to the $error variable that was not generally correct for optimizaed
code. This patch inserts a debug_value instruction in SILGen and thus
assigns the ArgNo together with all the other function arguments. This
is more robust and faster than than the old heuristic.
<rdar://problem/28748323>
radar rdar://problem/28434323
SILGen has no reason to insert shadow copies for inout parameters any more. They cannot be captured. We still emit these copies. Sometimes deshadowing removes them, but sometimes it does not.
In this PR we just avoid emitting the copies and remove the deshadowing pass.
This PR chery-picked some of @dduan work and built on top of it.
Now that the previous patches have shaken out implicit assumptions
about the order of generic requirements and substitutions, we can
make a more radical change, dropping redundant protocol requirements
when building the original generic signature.
This means that the canonical ordering and minimization that we
used to only perform when building the mangling signature is done
all of the time, and hence getCanonicalManglingSignature() can go
away.
Usages now either call getCanonicalSignature(), or operate on the
original signature directly.
When synthesizing the witness for Error._code, synthesize it as
final. This isn't meant to be user-visible (and, therefore, isn't
meant to be user-overridable), so it's a minor efficiency
win. Moreover, we weren't making sure this member got synthesized in
in cross-module situations, leading to runtime crashes. Fixes
rdar://problem/27335637.
Strict aliasing only applies to memory operations that use strict
addresses. The optimizer needs to be aware of this flag. Uses of raw
addresses should not have their address substituted with a strict
address.
Also add Builtin.LoadRaw which will be used by raw pointer loads.
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.
This ireapplies commit 255c52de9f.
Original commit message:
Serialize debug scope and location info in the SIL assembler language.
At the moment it is only possible to test the effects that SIL
optimization passes have on debug information by observing the
effects of a full .swift -> LLVM IR compilation. This change enable us
to write targeted testcases for single SIL optimization passes.
The new syntax is as follows:
sil-scope-ref ::= 'scope' [0-9]+
sil-scope ::= 'sil_scope' [0-9]+ '{'
sil-loc
'parent' scope-parent
('inlined_at' sil-scope-ref )?
'}'
scope-parent ::= sil-function-name ':' sil-type
scope-parent ::= sil-scope-ref
sil-loc ::= 'loc' string-literal ':' [0-9]+ ':' [0-9]+
Each instruction may have a debug location and a SIL scope reference
at the end. Debug locations consist of a filename, a line number, and
a column number. If the debug location is omitted, it defaults to the
location in the SIL source file. SIL scopes describe the position
inside the lexical scope structure that the Swift expression a SIL
instruction was generated from had originally. SIL scopes also hold
inlining information.
<rdar://problem/22706994>
At the moment it is only possible to test the effects that SIL
optimization passes have on debug information by observing the
effects of a full .swift -> LLVM IR compilation. This change enable us
to write targeted testcases for single SIL optimization passes.
The new syntax is as follows:
sil-scope-ref ::= 'scope' [0-9]+
sil-scope ::= 'sil_scope' [0-9]+ '{'
sil-loc
'parent' scope-parent
('inlined_at' sil-scope-ref )?
'}'
scope-parent ::= sil-function-name ':' sil-type
scope-parent ::= sil-scope-ref
sil-loc ::= 'loc' string-literal ':' [0-9]+ ':' [0-9]+
Each instruction may have a debug location and a SIL scope reference
at the end. Debug locations consist of a filename, a line number, and
a column number. If the debug location is omitted, it defaults to the
location in the SIL source file. SIL scopes describe the position
inside the lexical scope structure that the Swift expression a SIL
instruction was generated from had originally. SIL scopes also hold
inlining information.
<rdar://problem/22706994>