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
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.
The commit was reverted because of a regression in the
Prototypes/CollectionTransformers test. I believe the root
cause was an escape analysis bug, which is fixed in my
previous commit.
If the thunk's type otherwise did not involve type parameters, we
would still pass around the generic parameters from the caller's
context, which is wasteful.
This flips the switch to have @noescape be the default semantics for
function types in argument positions, for everything except property
setters. Property setters are naturally escaping, so they keep their
escaping-by-default behavior.
Adds contentual printing, and updates the test cases.
There is some further (non-source-breaking) work to be done for
SE-0103:
- We need the withoutActuallyEscaping function
- Improve diagnostics and QoI to at least @noescape's standards
- Deprecate / drop @noescape, right now we allow it
- Update internal code completion printing to be contextual
- Add more tests to explore tricky corner cases
- Small regressions in fixits in attr/attr_availability.swift
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.
And use project_box to get to the address value.
SILGen now generates a project_box for each alloc_box.
And IRGen re-uses the address value from the alloc_box if the operand of project_box is an alloc_box.
This lets the generated code be the same as before.
Other than that most changes of this (quite large) commit are straightforward.
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).
All refutable patterns and function parameters marked with 'var'
is now an error.
- Using explicit 'let' keyword on function parameters causes a warning.
- Don't suggest making function parameters mutable
- Remove uses in the standard library
- Update tests
rdar://problem/23378003
And include some supplementary mangling changes:
- Give the first generic param (depth=0, index=0) a single character mangling. Even after removing the self type from method declaration types, 'Self' still shows up very frequently in protocol requirement signatures.
- Fix the mangling of generic parameter counts to elide the count when there's only one parameter at the starting depth of the mangling.
Together these carve another 154KB out of a debug standard library. There's some awkwardness in demangled strings that I'll clean up in subsequent commits; since decl types now only mangle the number of generic params at their own depth, it's context-dependent what depths those represent, which we get wrong now. Currying markers are also wrong, but since free function currying is going away, we can mangle the partial application thunks in different ways.
Swift SVN r32896
Make the following illegal:
switch thing {
case .A(var x):
modify(x0
}
And provide a replacement 'var' -> 'let' fix-it.
rdar://problem/23172698
Swift SVN r32883
Canonical dependent member types are always based from a generic parameter, so we can use a more optimal mangling that assumes this. We can also introduce substitutions for AssociatedTypeDecls, and when a generic parameter in a signature is constrained by a single protocol, we can leave that protocol qualification out of the unsubstituted associated type mangling. These optimizations together shrink the standard library by 117KB, and bring the length of the longest Swift symbol in the stdlib down from 578 to 334 characters, shorter than the longest C++ symbol in the stdlib.
Swift SVN r32786
The CaptureInfo computed by Sema now records if the body of the
function uses any generic parameters from the outer context.
SIL type lowering only adds a generic signature if this is the
case, instead of unconditionally.
This might yield a marginal performance improvement in some cases,
but more interestingly will allow @convention(c) conversions from
generic context.
Swift SVN r32161
peephole reabstraction components by applying them to
the r-value instead of materializing to a temporary
and then assigning to that.
Removes a completely unnecessary use of the getter
from simple assignments to properties or subscripts
at a different abstraction level.
Swift SVN r31197
This is a bit unfortunate since the natural result of 'get' was probably already at the right abstraction level and already got abstracted in the wrong direction, but we don't have the infrastructure to peephole away the redundancy yet. Fixes rdar://problem/20341012.
Swift SVN r30483
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
Now the SILLinkage for functions and global variables is according to the swift visibility (private, internal or public).
In addition, the fact whether a function or global variable is considered as fragile, is kept in a separate flag at SIL level.
Previously the linkage was used for this (e.g. no inlining of less visible functions to more visible functions). But it had no effect,
because everything was public anyway.
For now this isFragile-flag is set for public transparent functions and for everything if a module is compiled with -sil-serialize-all,
i.e. for the stdlib.
For details see <rdar://problem/18201785> Set SILLinkage correctly and better handling of fragile functions.
The benefits of this change are:
*) Enable to eliminate unused private and internal functions
*) It should be possible now to use private in the stdlib
*) The symbol linkage is as one would expect (previously almost all symbols were public).
More details:
Specializations from fragile functions (e.g. from the stdlib) now get linkonce_odr,default
linkage instead of linkonce_odr,hidden, i.e. they have public visibility.
The reason is: if such a function is called from another fragile function (in the same module),
then it has to be visible from a third module, in case the fragile caller is inlined but not
the specialized function.
I had to update lots of test files, because many CHECK-LABEL lines include the linkage, which has changed.
The -sil-serialize-all option is now handled at SILGen and not at the Serializer.
This means that test files in sil format which are compiled with -sil-serialize-all
must have the [fragile] attribute set for all functions and globals.
The -disable-access-control option doesn't help anymore if the accessed module is not compiled
with -sil-serialize-all, because the linker will complain about unresolved symbols.
A final note: I tried to consider all the implications of this change, but it's not a low-risk change.
If you have any comments, please let me know.
Swift SVN r22215
When we produce a physical LValue with an abstraction difference, cap off the LValue with a logical "OrigToSubstComponent", which enacts the abstraction change on load or store, and introduces a writeback for the property when used in an @inout context.
Swift SVN r11498