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
Getting the protocols of an arbitrary type doesn't make sense, so start phasing this out by introducing specialized entry points that do make sense:
- get the inherited protocols of a ProtocolDecl
- get the conforming protocols for an associated type or generic
type parameter
- (already present) ask for the protocols to which a nominal type conforms
Swift SVN r26411
This means:
1. In_Guaranteed when preparing accessor base args is like @in not
@inout. This is because @in_guaranteed parameters are immutable. We
were not miscompiling since we were not inserting cleanups for these
parameters. Now with 2, we perform the copy so we have the immutable
property and then destroy_addr the result after the call.
2. If we have a guaranteed parameter, we put the destroy value right
after the call instead of at the end of expression.
The reason 2 is necessary is that if we destroy the value at the end of
scope situations like the following cause COW to fail:
struct Foo {
let object: AnyObject
var rawObject: Builtin.RawPointer {
return Builtin.bridgeToRawPointer(object) // Psuedoname of builtin.
}
mutating func isUnique() -> Bool {
return isUnique(rawObject)
}
}
What happens is that because Foo.isUnique is mutating, Foo is passed in
@inout. Since @inout is a guarantee related to memory, SILGen has to
increment the refcount of self to guarantee self's lifetime. Before this
patch we would have (in pseudo-sil).
%self = load %ptr_self
retain_value %self
%0 = getRawObject() // guaranteed call.
%result = isUnique(%0)
release_value %self
This causes the COW check to always fail. There is no reason to extend
the lifetime of %self so far, guaranteed only means that the object's
lifetime is guaranteed over the call in question. So now instead, we
release after the call.
<rdar://problem/20094305>
<rdar://problem/20234910>
Swift SVN r26351
Replace the loop over all known protocols with a query into the
actual conformance lookup table, which more properly deals with
out-of-order conformance queries, inheritance of protocol
conformances, and conformance queries in multi-file situtations.
The SILGen test change is because we're no longer emitting redundant
conformances, while the slight diagnostic regression in
circular-inheritance cases is because we handle circular inheritance
very poorly throughout the compiler.
While not the end, this is a major step toward finishing
rdar://problem/18448811.
Swift SVN r26299
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
Previously, a multi-pattern var/let decl like:
var x = 4, y = 17
would produce two pattern binding decls (one for x=4 one for y=17). This is convenient
in some ways, but is bad for source reproducibility from the ASTs (see, e.g. the improvements
in test/IDE/structure.swift and test/decl/inherit/initializer.swift).
The hardest part of this change was to get parseDeclVar to set up the AST in a way
compatible with our existing assumptions. I ended up with an approach that forms PBDs in
more erroneous cases than before. One downside of this is that we now produce a spurious
"type annotation missing in pattern"
diagnostic in some cases. I'll take care of that in a follow-on patch.
Swift SVN r26224
The deallocating parameter convention is a new convention put on a
non-trivial parameter if the caller function guarantees to the callee
that the parameter has the deallocating bit set in its object header.
This means that retains and releases do not need to be emitted on these
parameters even though they are non-trivial. This helps to solve a bug
in +0 self and makes it trivial for the optimizer to perform
optimizations based on this property.
It is not emitted yet by SILGen and will only be put on the self
argument of Deallocator functions.
Swift SVN r26179
- Rename getParentPattern() -> getParentPatternBinding(), since
it returns the pattern binding, not the pattern.
- Introduce new getParentPattern()/getParentInitializer() methods,
covering the most common uses of getParentPatternBinding().
NFC.
Swift SVN r26175
This changes 'if let' conditions to take general refutable patterns, instead of
taking a irrefutable pattern and implicitly matching against an optional.
Where before you might have written:
if let x = foo() {
you now need to write:
if let x? = foo() {
The upshot of this is that you can write anything in an 'if let' that you can
write in a 'case let' in a switch statement, which is pretty general.
To aid with migration, this special cases certain really common patterns like
the above (and any other irrefutable cases, like "if let (a,b) = foo()", and
tells you where to insert the ?. It also special cases type annotations like
"if let x : AnyObject = " since they are no longer allowed.
For transitional purposes, I have intentionally downgraded the most common
diagnostic into a warning instead of an error. This means that you'll get:
t.swift:26:10: warning: condition requires a refutable pattern match; did you mean to match an optional?
if let a = f() {
^
?
I think this is important to stage in, because this is a pretty significant
source breaking change and not everyone internally may want to deal with it
at the same time. I filed 20166013 to remember to upgrade this to an error.
In addition to being a nice user feature, this is a nice cleanup of the guts
of the compiler, since it eliminates the "isConditional()" bit from
PatternBindingDecl, along with the special case logic in the compiler to handle
it (which variously added and removed Optional around these things).
Swift SVN r26150
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
John points out that we would still need to evaluate default arguments in an ignored context, and these cases aren't important to fixing the bug.
Swift SVN r26108
For now, we assume that 'while' after the braces starts
a do/while rather than being an independent statement.
We should disambiguate this, or better, remove do/while.
Tests later.
Swift SVN r26079
"similar", avoiding false positive "not exhaustive" diagnostics on switches
like:
switch ... {
case let x?: break
case .None: break
}
Also, start using x? patterns in the stdlib more (review appreciated!), which
is what shook this issue out.
Swift SVN r26004
This introduces a new pattern, spelled "x?" which is sugar for
matching ".Some(x)". It also changes the parser slightly so that
_ (the discard expr) is parsed as a unary expr instead of as an
expr. This allows it to have postfix ? after it, which is important
in pattern contexts to support "case _?:".
Swift SVN r25907
For better consistency with other address-only instruction variants, and to open the door to new exciting existential representations (such as a refcounted boxed representation for ErrorType).
Swift SVN r25902
Turns out llvm::DataLayoutPass is used in other places, so the bots are still unhappy.
Re-applying the original change so we can fix the problem holistically.
Swift SVN r25761
This is breaking the testing bot because DataLayoutPass was just removed from LLVM trunk.
Chris is the best one to fix this change, but we need to get the bots green.
Swift SVN r25760
- Have Sema, not SILGen decide if a vardecl can be captured by address
instead of by-box. This is a non-local property that is best computed
during capture set formation. Sema captures this as a bit on the new
CapturedValue entry.
- Rework some diagnostic emission to centralize a class of noescape
diagnostics in capture set calculation. Previously, funcdecl closures
produced their diagnostics there, but ClosureExprs produced them in
MiscDiagnostics (NFC for this part).
This fixes <rdar://problem/19981118> Swift 1.2 beta 2: Closures nested in @noescape closures copy, rather than reference, captured vars.
Swift SVN r25759
when computing the list. This simplifies getLocalCaptures to *just* filter out
global captures, and paves the way for other enhancements. NFC.
Swift SVN r25739
...rather than just assuming any initializer without a body that makes it
to SILGen is a memberwise initializer.
In the long term we want SILGen to stop handling these initializers, at
which point we can see if it makes sense to remove this body kind.
No intended functionality change.
Swift SVN r25723
If we have a C function pointer conversion, generate a thunk using the same logic we use for ObjC method thunks, and emit a pointer to that thunk as the C function pointer value. (This works for nongeneric, nonmember functions; generics will additionally need to apply generic parameters within the thunks. Static functions would need to gather the metatype as well.)
Swift SVN r25653
This doesn't allow 'continue' out of an if statement for the same reason we don't
allow it on switch: we'd prefer people to write loops more explicitly.
Swift SVN r25565