This fixes a crash when referencing partially-applied methods
from @_inlineable functions.
Also, curry thunks for private methods do not need shared
linkage; private is sufficient.
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
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
* Migrate from `UnsafePointer<Void>` to `UnsafeRawPointer`.
As proposed in SE-0107: UnsafeRawPointer.
`void*` imports as `UnsafeMutableRawPointer`.
`const void*` imports as `UnsafeRawPointer`.
Occurrences of `UnsafePointer<Void>` are replaced with UnsafeRawPointer.
* Migrate overlays from UnsafePointer<Void> to UnsafeRawPointer.
This requires explicit memory binding in several places,
particularly in NSData and CoreAudio.
* Fix a bunch of test cases for Void->Raw migration.
* qsort takes IUO values
* Bridge `Unsafe[Mutable]RawPointer as `void [const] *`.
* Parse #dsohandle as UnsafeMutableRawPointer
* Update a bunch of test cases for Void->Raw migration.
* Trivial fix for the SceneKit test case.
* Add an UnsafeRawPointer self initializer.
This is unfortunately necessary for assignment between types imported from C.
* Tiny simplification of the initializer.
* Migrate from `UnsafePointer<Void>` to `UnsafeRawPointer`.
As proposed in SE-0107: UnsafeRawPointer.
`void*` imports as `UnsafeMutableRawPointer`.
`const void*` imports as `UnsafeRawPointer`.
Occurrences of `UnsafePointer<Void>` are replaced with UnsafeRawPointer.
* Migrate overlays from UnsafePointer<Void> to UnsafeRawPointer.
This requires explicit memory binding in several places,
particularly in NSData and CoreAudio.
* Fix a bunch of test cases for Void->Raw migration.
* qsort takes IUO values
* Bridge `Unsafe[Mutable]RawPointer as `void [const] *`.
* Parse #dsohandle as UnsafeMutableRawPointer
* Update a bunch of test cases for Void->Raw migration.
* Trivial fix for the SceneKit test case.
* Add an UnsafeRawPointer self initializer.
This is unfortunately necessary for assignment between types imported from C.
* Tiny simplification of the initializer.
Swift has supported this for a long time using manual casts and going
from Swift to Objective-C; just enable it now for the importer.
rdar://problem/15101588
Being generic, the '_unwrapped' intrinsics force trafficking through memory, and while they're transparent so always get inlined, we don't do memory promotion in -Onone. Emitting the branch inline lets loadable optionals stay values leading to better -Onone codegen. (It also lets us throw away a surprising amount of support code for these optional intrinsics.)
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).
when working with autoreleased result conventions, and stop
emitting autorelease_return and strong_retain_autoreleased in
SILGen.
The previous representation, in which strong_retain_autoreleased
was divorced from the call site, allowed it to "wander off" and
be cloned. This would at best would break the optimization, but
it could also lead to broken IR due to some heroic but perhaps
misguided efforts in IRGen to produce the exact required code
pattern despite the representational flaws.
The SIL pattern for an autoreleased result now looks exactly
like the pattern for an owned result in both the caller and
the callee. This should be fine as long as interprocedural
optimizations are conservative about convention mismatches.
Optimizations that don't wish to be conservative here should
treat a convention mismatch as an autorelease (if the callee
has an autoreleased result) or a retain (if the formal type
of the call has an autoreleased result).
Fixes rdar://23810212, which is an IRGen miscompile after the
optimizer cloned a strong_retain_autoreleased. There's no
point in adding this test case because the new SIL pattern
inherently prevents this transformation by construction.
The 'autorelease_return' and 'strong_retain_autoreleased'
instructions are now dead, and I will remove them in a
follow-up commit.
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
SILPrinter was printing uses for all SIL values, except for SIL basic blocks arguments. Fill the gap and print uses for BB arguments as well. This makes reading and analyzing SIL easier.
Basic blocks may have multiple arguments, therefore print uses of each BB argument on separate lines - one line per BB argument.
The comment containing information about uses of a BB argument is printed on the line just above the basic block name, following the approach used for function_ref and other kinds of instructions, which have additional information printed on the line above the actual instruction.
The output now looks like:
// %0 // user: %3
// %1 // user: %9
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<UnsafeMutablePointer<Int8>>):
rdar://23336589
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
'Ss' appears in manglings tens of thousands of times in the standard library and is also incredibly frequent in other modules. This alone is enough to shrink the standard library by 59KB.
Swift SVN r32409
to not drop optionals in memory all the time. We now generate a lot better code
for them in many cases. This makes generated SIL more readable and should help
-O0 perf.
This is progress towards <rdar://problem/20642198> SILGen shouldn't be dropping optionals into memory all the time
Swift SVN r28102
The main thing that this patch does is work around a shortcoming of
SILGenApply namely that we in certain cases emit self before we know
what the callee is. We work around this by emitting self at +0 assuming
that the callee does pass self at +0 and set a flag. After we know what
the callee is, if the flag is set, we emit an extra retain for self.
rdar://15729033
Swift SVN r27553
registers instead of eagerly dumping them in memory and operating on
them by-address. This avoids a lot of temporaries and traffic to
manipulate them.
As part of this, add some new SGF::getOptionalNoneValue/getOptionalSomeValue
helper methods for forming loading optional values.
Many thanks to JoeG for helping with the abstraction difference change in
getOptionalSomeValue.
Swift SVN r27537
We no longer need or use it since we can always refer to the same bit on
the applied function when deciding whether to inline during mandatory
inlining.
Resolves rdar://problem/19478366.
Swift SVN r26534
the call instead of during the formal evaluation of the argument.
This is the last major chunk of the semantic changes proposed
in the accessors document. It has two purposes, both related
to the fact that it shortens the duration of the formal access.
First, the change isolates later evaluations (as long as they
precede the call) from the formal access, preventing them from
spuriously seeing unspecified behavior. For example::
foo(&array[0], bar(array))
Here the value passed to bar is a proper copy of 'array',
and if bar() decides to stash it aside, any modifications
to 'array[0]' made by foo() will not spontaneously appear
in the copy. (In contrast, if something caused a copy of
'array' during foo()'s execution, that copy would violate
our formal access rules and would therefore be allowed to
have an arbitrary value at index 0.)
Second, when a mutating access uses a pinning addressor, the
change limits the amount of arbitrary code that falls between
the pin and unpin. For example::
array[0] += countNodes(subtree)
Previously, we would begin the access to array[0] before the
call to countNodes(). To eliminate the pin and unpin, the
optimizer would have needed to prove that countNodes didn't
access the same array. With this change, the call is evaluated
first, and the access instead begins immediately before the call
to +=. Since that operator is easily inlined, it becomes
straightforward to eliminate the pin/unpin.
A number of other changes got bundled up with this in ways that
are hard to tease apart. In particular:
- RValueSource is now ArgumentSource and can now store LValues.
- It is now illegal to use emitRValue to emit an l-value.
- Call argument emission is now smart enough to emit tuple
shuffles itself, applying abstraction patterns in reverse
through the shuffle. It also evaluates varargs elements
directly into the array.
- AllowPlusZero has been split in two. AllowImmediatePlusZero
is useful when you are going to immediately consume the value;
this is good enough to avoid copies/retains when reading a 'var'.
AllowGuaranteedPlusZero is useful when you need a stronger
guarantee, e.g. when arbitrary code might intervene between
evaluation and use; it's still good enough to avoid copies
from a 'let'. The upshot is that we're now a lot smarter
about generally avoiding retains on lets, but we've also
gotten properly paranoid about calling non-mutating methods
on vars.
(Note that you can't necessarily avoid a copy when passing
something in a var to an @in_guaranteed parameter! You
first have to prove that nothing can assign to the var during
the call. That should be easy as long as the var hasn't
escaped, but that does need to be proven first, so we can't
do it in SILGen.)
Swift SVN r24709
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
Have the ArgumentInitVisitor directly bind argument variables to BB arguments, instead of trying to reuse the InitializationForPattern logic used for general variable bindings. That was a nice idea, but it leads to some ugly edge cases because of the many little ways arguments are different from local variable bindings. By getting rid of the abstraction layers, it's easy for argument binding to bind +0 guaranteed or +1 arguments in place when appropriate, avoiding an r/r pair for "let" bindings. It will also let us eliminate some ugly code from variable binding initialization. Should be NFC aside from some harmless reordering of prolog/epilog variable setup.
Swift SVN r24412
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