When extending a protocol where the 'Self' type is a subclass of some
known class type, initializers within the protocol extension can
delegate to required initializers of that superclass bound. Correctly
adjust the 'self' we produce in SILGen to the superclass type.
Fixes rdar://problem/21370992.
Swift SVN r30584
Requiring a variadic parameter to come at the end of the parameter
list is an old restriction that makes no sense nowadays, and which we
had all thought we had already lifted. It made variadic parameters
unusable with trailing closures or defaulted arguments, and made our
new print() design unimplementable.
Remove this restriction, replacing it with a less onerous and slightly
less silly restriction that we not have more than one variadic
parameter in a given parameter clause. Fixes rdar://problem/20127197.
Swift SVN r30542
SILGen was not imploding tuple initializers for global variables and always generated an element-by-element initialization.
This made it difficult for GlobalOpt to propagate the value of the global into its uses. Therefore, SILGen now generates tuple instructions to initialize global variables of trivial tuple types.
Swift SVN r30237
Unless we can prove that the input and output are layout identical we must use either trivial_bit_cast or bitwise_cast.
This changes the lowering to be more conservative for:
- Builtin.reinterpretCast
- address_to_pointer -> pointer_to_address
This also makes LoadStoreOpts more conservative in:
- forwardAddrToUncheckedCastToLd
In order to commit this without massive performance regressions, I added SILType::canBitCastAsSingleRef. When this is true for both sides
of a bitwise case, we can convert it to a RefBitCast, which has RC identity.
Swift SVN r30172
We were creating counters for IfExpr coverage, but weren't actually
mapping these when emitting coverage. Handle this.
rdar://problem/21720161
Swift SVN r29971
This allows the value to be cast to an UnsafePointer type and correctly loaded out in all cases. In particular, this lets you pass a Swift closure by pointer as the context parameter to a C function pointer, allowing callback-based C APIs to be more conveniently wrapped. Fixes rdar://problem/21505805.
Swift SVN r29904
- If delegating to an initializing constructor for a value type,
the ApplyInst takes an @out parameter for Self, instead of
returning Self like with references. Fix the def-use traversal
to handle that instead of crashing.
- When calling an allocating constructor, the formal type is
the instance type because Sema constructs the constructor call
as if it were an initializing constructor. This causes us to
fail to re-abstract a @thin metatype to @thick. Fix this to
use the correct metatype type for allocating constructors.
Fixes <rdar://problem/20945954>.
Swift SVN r29555
The other part of rdar://problem/21444126. This is a little trickier since SIL doesn't track uses of witness tables in a principled way. Track uses in SILGen by putting a "SILGenBuilder" wrapper in front of SILBuilder, which marks conformances from apply, existential erasure, and metatype lookup instructions as used, so we can avoid emitting shared Clang importer witnesses when they aren't needed.
Swift SVN r29544
This new method eliminates repeated code sequences that all create an
unchecked_trivial_bit_cast if the result type is trivial or
unchecked_ref_bit_cast otherwise.
NFC.
Swift SVN r29486
Special-casing these as MemberRefExprs created an asymmetry
where unbound archetype instance methods (<T : P> T.f) could
not be represented. Treating class and protocol methods
uniformly also eliminates a handful of special cases around
MemberRefExpr.
SILGen's RValue and call emission peepholes now have to know
about DeclRefExprs that point to protocol methods.
Finally, generalize the diagnostic for partially applied
mutating methods to any partially applied function with an
inout parameter, since this is not supported.
Fixes <rdar://problem/20564672>.
Swift SVN r29298
in a trivial struct, the 'self' argument in an initializer won't have
a cleanup, so don't disable or reenable it when rebinding self due to delegation.
Swift SVN r28674
instead of being an expression.
To the user, this has a couple of behavior changes, stemming from its non-expression-likeness.
- #available cannot be parenthesized anymore
- #available is in its own clause, not used in a 'where' clause of if/let.
Also, the implementation in the compiler is simpler and fits the model better. This
fixes:
<rdar://problem/20904820> Following a "let" condition with #available is incorrectly rejected
Swift SVN r28521
And take advantage of the guaranteed peephole when available to emit the base expression at +0 in general existential-to-existential erasures. Fixes rdar://problem/20890504.
Swift SVN r28447
This reapplies commit r27632 with additional fixes, tests.
I turned off the guaranteed struct optimization since we really don't have the
infrastructure to do it right and more importantly I don't have the time to do
so (and was not asked to do so).
We still have the class optimization though!
This means that there is one retain in ClassIntTreeMethod.find.
class ClassIntTreeNode {
let value : Int
let left, right : ClassIntTreeNode
init() {}
func find(v : Int) -> ClassIntTreeNode {
if v == value { return self }
if v < value { return left.find(v) }
return right.find(v)
}
}
Swift SVN r28264
Two pieces to this:
- Peephole OptionalEvaluationExpr(InjectOptionalExpr(BindOptionalExpr(X))) to bitcast x to the result type.
- Enhance OptionalEvaluationExpr to delete the failure block if not needed.
This is the same as r28150, but it includes a fix for the case when a non-address-only type
is initializing a contextally-provided-and-addressible buffer, tested by the new
testContextualInitOfNonAddrOnlyType testcase.
Swift SVN r28153
Two pieces to this:
- Peephole OptionalEvaluationExpr(InjectOptionalExpr(BindOptionalExpr(X))) to
bitcast x to the result type.
- Enhance OptionalEvaluationExpr to delete the failure block if not needed.
This is the same as r28111, except that we finalize the initialization in the
address-only case. A reduced testcase for the specific issue is added to
optional-casts.swift.
Swift SVN r28150
and r28105: "implement <rdar://problem/17013042> T! <-> T? conversions should not produce a diamond"
r28111 broke the stdlib build. I also reverted r28105, because r28111 fixes regressions introduced in r2805.
Swift SVN r28114
Instead of immediately creating closures for local function declarations and treating them directly as capturable values, break function captures down and transitively capture the storage necessary to invoke the captured functions. Change the way SILGen emits calls to closures and local functions so that it treats the capture list as the first curry level of an invocation, so that full applications of closure literals or nested functions don't require a partial apply at all. This allows references among local functions with captures to work within the existing confines of partial_apply, and also has the nice benefit that circular references would work without creating reference cycles (though Sema unfortunately rejects them; something we arguably ought to fix.)
This fixes rdar://problem/11266246 and improves codegen of local functions. Full applications of functions, or immediate applications of closure literals like { }(), now never need to allocate a closure.
Swift SVN r28112
on inject_into_optional/bind_optional_expr isn't safe because we don't know what
optional_evaluation_expr is actually being bound, or if it is bound to the result of the
injection.
Instead, make this more careful to look for the evaluation_expr as well, matching
the specific pattern:
(optional_evaluation_expr type='T?'
(inject_into_optional type='T?'
(bind_optional_expr type='T'
(whatever type='T?' ...)
This fixes the two interpreter testcases that regressed in r28105.
Swift SVN r28111
Two pieces to this:
- Peephole InjectOptionalExpr(BindOptionalExpr(X)) to bitcast x to the result type.
- Enhance OptionalEvaluationExpr to delete the failure block if not needed.
Swift SVN r28105
nil path. This avoids emitting a "release" operation on an optional temporary that is
always guaranteed to be dynamically nil. This cleans up the generated code for x?.foo().
Swift SVN r28103
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
emit{StrongRelease,ReleaseValue} => emit{StrongRelease,ReleaseValue}AndFold.
Then introduce a new method emit{StrongRelease,ReleaseValue} that returns a
PointerUnion containing the increment to be deleted if it exists. This obviates
the need for the callback.
Swift SVN r27804
When emitting default arguments for a parameter, emitApplyOfDefaultArgGenerator
was trying to reconstruct the original type by looking at the decl that it came
from. However, it doesn't know the number of curry levels already applied, so it
was wrong in the case of default arguments on methods and initializers (which already
have self applied).
Fix this by having the caller pass this information in, since it knows the original
type.
While we're at it, remove the code for handling default arguments from the general
SILGenExpr logic. Default arguments in tuples are no longer a general thing, they
are only valid in argument lists.
Swift SVN r27800
Specifically this patch makes the following changes:
1. We properly propagate down the SGFContext of a tuple to its elements
when extracting from a tuple. There was a typo that caused us to use
data from the newly created default initialized copy instead of from the
actual SGFContext of the parent tuple.
2. If we are accessing a member ref of self in a guaranteed context:
a. If self is a struct, regardless of whether or not the field is a
var or a let we no longer emit a retain. This is b/c self in a
guaranteed context is immutable. This implies even a var in the
struct can not be reassigned to.
b. If self is a class, if the field is a let, we no longer emit an
extra retain.
This makes it so that the only rr traffic in IntTreeNode::find is in the
block of code where we return self.
class IntTreeNode {
let value : Int
let left, right : IntTreeNode
init() {} // not needed for -emit-silgen
func find(v : Int) -> IntTreeNode {
if v == value { return self }
if v < value { return left.find(v) }
return right.find(v)
}
}
One gets the same effect using a struct for IntTreeNode and a generic
box class, i.e.:
class Box<T> {
let value: T
init(newValue: T) { value = newValue }
}
class Kraken {}
struct IntTreeNode {
let k : Kraken // Just to make IntTreeNode non-trivial for rr purposes.
let left, right : Box<IntTreeNode>
init() {} // not needed for -emit-silgen
func find(v : Int) -> IntTreeNode {
if v == value { return self }
if v < value { return left.value.find(v) }
return right.value.find(v)
}
}
There is more work that can be done here by applying similar logic to
enums, i.e. switching on self in an enum should not generate any rr
traffic over the switch. Also it seems that there are some places in SILGen
where isGuaranteedValid is not being propagated to SILGenFunction::emitLoad. But
that is for another day.
I am going to gather data over night and send an email to the list.
rdar://15729033
Swift SVN r27632