This isn't as straightforward as it should be, since EnumElementDecls aren't AbstractFunctionDecls, but luckily there's only one trivial curry level with a thin metatype parameter.
Swift SVN r28991
When emitting try_apply, don't start a new scope between adding
a cleanup and forwarding the value. This would leave behind a
dead cleanup, which would fire an assertion in emitSharedCaseBlocks().
Fixes <rdar://problem/20923654>.
Swift SVN r28572
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
When a derived class specializes its base class, e.g. 'class Derived: Base<Int>', the natural abstraction levels of its methods may differ from the original base class's more abstract methods. Handle this by using the reabstraction machinery to thunk values when necessary. Merge the existing optionality thunking support into the reabstraction code, where witness thunking and similar convention adjustments may also be able to use it, if we desire. Fixes rdar://problem/19760292.
Swift SVN r28505
in memory when it is address-only. This leads to better -O0 performance and
easier to read silgen output. This is ongoing progress towards rdar://20642198.
Swift SVN r28318
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
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
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
For the most part, this just involves spot fixes to make sure protocol inits follow the same paths as value type initializers would, with the extra wrinkle that we have to ensure we forward the correct metatype from the delegating initializer to the delegatee, in case the initializer is invoked with a different dynamic type from the static Self type. This should handle non-@objc delegations; @objc will need some additional work.
Swift SVN r27900
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
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
SGF::emitLocalVariable: inline it into its only remaining client (which is
indirectly part of 'var' pattern binding emission) and simplify the code a bit.
NFC.
Swift SVN r27531
emission instead of hand coded magic. Eliminating special cases allows simplifying
other parts of the compiler, and this probably helps the error handling initiative
as well.
This uses the (horrible) new null_class instruction to properly model rebinding of
self. The code that SILGen was producing before was wildly incorrect and we only
got lucky that it seemed to work in most cases before.
NFC except that SILGen tests see the new null_class instructions, and we get better
location info for 'return nil' for obscure reasons that don't really matter.
Swift SVN r27530
already set up, allowing clients to generate code before the top-level
cleanup stack is emitted.
Use this to switch value constructors onto emitEpilog() and, more importantly,
to start managing the self box as a normal local variable tracked with cleanups
instead of being tracked with ad-hoc code spread through SILGen.
Among other things, once classes are switched over to the same model, we can
remove SGF.FailSelfDecl and the code to support it. NFC.
Swift SVN r27472
to make it take a ManagedValue instead of an Expr*.
NFC, except that the temporaries are emitted a bit later in some cases,
accounting for the diffs in the testcases.
Swift SVN r27458
Consistently open all references into existentials into
opened-existential archetypes within the constraint solver. Then,
during constraint application, use OpenExistentialExprs to record in
the AST where an existential is opened into an archetype, then use
that archetype throughout the subexpression. This simplifies the
overall representation, since we don't end up with a mix of operations
on existentials and operations on archetypes; it's all archetypes,
which tend to have better support down the line in SILGen already.
Start simplifying the code in SILGen by taking away the existential
paths that are no longer needed. I suspect there are more
simplifications to be had here.
The rules for placing OpenExistentialExprs are still a bit ad hoc;
this will get cleaned up later so that we can centralize that
information. Indeed, the one regression in the compiler-crasher suite
is because we're not closing out an open existential along an error
path.
Swift SVN r27230
Try to emit the existential as a guaranteed value, and if we succeed, only +1 the bound opaque value if it's needed as a consumed value. This lets us avoid retaining or copying the existential if the existential can be produced and its contained value consumed at +0.
Swift SVN r27200
These aren't really orthogonal concerns--you'll never have a @thick @cc(objc_method), or an @objc_block @cc(witness_method)--and we have gross decision trees all over the codebase that try to hopscotch between the subset of combinations that make sense. Stop the madness by eliminating AbstractCC and folding its states into SILFunctionTypeRepresentation. This cleans up a ton of code across the compiler.
I couldn't quite eliminate AbstractCC's information from AST function types, since SIL type lowering transiently created AnyFunctionTypes with AbstractCCs set, even though these never occur at the source level. To accommodate type lowering, allow AnyFunctionType::ExtInfo to carry a SILFunctionTypeRepresentation, and arrange for the overlapping representations to share raw values.
In order to avoid disturbing test output, AST and SILFunctionTypes are still printed and parsed using the existing @thin/@thick/@objc_block and @cc() attributes, which is kind of gross, but lets me stage in the real source-breaking change separately.
Swift SVN r27095
This is necessary for correctly dealing with non-standard
ownership conventions in secondary positions, and it should
also help with non-injective type imports (like BOOL/_Bool).
But right now we aren't doing much with it.
Swift SVN r26954
This change permits SILGen to make smarter decisions about
block placement by keeping related blocks together instead
of always inserting to the end to the function. The
flipside is that SILGen needs to be somewhat careful to
create blocks in the right order. Counter-intuitively,
that order is the reverse of the order in which the blocks
should be laid out, since blocks created later will be
inserted before blocks created earlier. Note, however,
that this produces the right results for recursive
emission.
To that end, adjust a couple of places in SILGen to
create blocks in properly nested order.
All of the block-order differences in the tests seem
to be desirable; several of them even had confused
comments wondering how on earth a block got injected
where it did.
Also, fix the implementation of SILBuilder::moveBlockTo,
and fix a latent bug in epilogue emission where epilogBB
was erased from its parent (deleting it) and then
queried multiple times (!).
Swift SVN r26428
This patch also introduces some SILGen infrastructure for
dividing the function into "ordinary" and "postmatter"
sections, with error-handling-like stuff going into the
final section. Currently, this is largely undermined by
SILBuilder, but I'm going to fix that in a follow-up.
Swift SVN r26422
Leave a cleanup to deinit the container after the uniquely-referenced opaque value is taken out of it. While we're here, stub out support for boxed existentials (though we can't test it since _ErrorType doesn't have any Self-returning methods, and we currently only produce OpenExistentialExprs in the AST for method calls involving covariant Self or metatypes).
Swift SVN r26284
in terms of the pattern binding/emission facilities that are currently
used for switches. They are more general (handling all patterns,
not hacked up just for optionals).
This leads to us producing better code for if/let bindings, because we
don't alloc_stack a temporary and deal with memory for non-address-only
types (e.g. the common case of an optional pointer). Instead, the code
emits a select_enum{_addr} on the value.
While this changes the generated code in the compiler, there is no exposed
behavioral change to the developer.
Swift SVN r26142