Commit Graph

1223 Commits

Author SHA1 Message Date
Michael Gottesman
ffe698ddaa Remove trailing whitespace. NFC.
Swift SVN r27506
2015-04-20 23:35:37 +00:00
John McCall
a67452c72c SILGen for throwing foreign errors out of @objc thunks.
Also, create a new file specifically for the foreign-error
code.

Swift SVN r27347
2015-04-16 05:16:54 +00:00
John McCall
156a4c7ed0 SILGen for calls under foreign error conventions. WIP.
Swift SVN r27270
2015-04-14 02:35:54 +00:00
Doug Gregor
997136962e Always open existential types in the type checker.
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
2015-04-11 03:20:22 +00:00
John McCall
79cc258f65 Lower 'throws' to an error result.
Swift SVN r27108
2015-04-08 00:09:29 +00:00
Joe Groff
ad0d20c07a Fold "AbstractCC" into SILFunctionType::Representation.
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
2015-04-07 21:59:39 +00:00
Joe Groff
4821f594bb SIL: Separate SILFunctionType::Representation and ExtInfo from AST FunctionTypes.
The set of attributes that make sense at the AST level is increasingly divergent from those at the SIL level, so it doesn't really make sense for these to be the same. It'll also help prevent us from accidental unwanted propagation of attributes from the AST to SIL, which has caused bugs in the past. For staging purposes, start off with SILFunctionType's versions exactly the same as the FunctionType versions, which necessitates some ugly glue code but minimizes the potential disruption.

Swift SVN r27022
2015-04-05 17:04:55 +00:00
John McCall
dc4b8ff2c2 Incorporate an optional Clang type into AbstractionPattern.
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
2015-04-03 21:39:31 +00:00
Chris Lattner
79ed57f9f2 standardize naming of tuples and tuple patterns on "elements".
Previously some parts of the compiler referred to them as "fields",
and most referred to them as "elements".  Use the more generic 'elements'
nomenclature because that's what we refer to other things in the compiler
(e.g. the elements of a bracestmt).

At the same time, make the API better by providing "getElement" consistently
and using it, instead of getElements()[i].

NFC.



Swift SVN r26894
2015-04-02 20:23:49 +00:00
Joe Pamer
eee40fc53f Add basic parsing, sema and mangling support for throwing function types. Next up, metadata and serialization support, as well as more tests.
Swift SVN r26767
2015-03-31 18:55:19 +00:00
Joe Groff
751724c3fa SILGen: Special-case NSError to ErrorType erasure.
We want this to be a "toll-free" adoption of the class reference without requiring a second box allocation.

Swift SVN r26711
2015-03-30 04:52:41 +00:00
Doug Gregor
3d77855b31 Start allowing extensions of protocol types.
Remove the semantic restrictions that prohibited extensions of
protocol types, and start making some systematic changes so that
protocol extensions start to make sense:
  - Replace a lot of occurrences of isa<ProtocolDecl> and
    dyn_cast<ProtocolDecl> on DeclContexts to use the new
    DeclContext::isProtocolOrProtocolExtensionContext(), where we want
    that behavior to apply equally to protocols and protocol extensions.
  - Eliminate ProtocolDecl::getSelf() in favor of
    DeclContext::getProtocolSelf(), which produces the appropriate
    generic type parameter for the 'Self' of a protocol or protocol
    extension. Update all of the callers of ProtocolDecl::getSelf()
    appropriately.
  - Update extension validation to appropriately form generic
    parameter lists for protocol extensions.
  - Methods in protocol extensions always use the witnesscc calling
  convention.

At this point, we can type check and SILGen very basic definitions of
protocol extensions with methods that can call protocol requirements,
generic free functions, and other methods within the same protocol
extension.

Regresses four compiler crashers but improves three compiler
crashers... we'll call that "progress"; the four regressions all hit
the same assertion in the constraint system that will likely be
addressed as protocol extensions starts working.

Swift SVN r26579
2015-03-26 04:50:51 +00:00
John McCall
35b7db3ae1 Parsing support for error results from SILFunctionType.
Swift SVN r26566
2015-03-26 00:01:32 +00:00
Mark Lacey
1f23ff27bb Remove the transparent bit from apply instructions.
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
2015-03-25 08:36:34 +00:00
John McCall
08d3460a19 Implement throw expressions. Untested.
Tests tomorrow for this and 'catch', I promise. :)

Swift SVN r26432
2015-03-23 08:10:15 +00:00
John McCall
ee4aa14703 Stop reordering blocks in SILBuilder::emitBlock.
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
2015-03-23 06:38:20 +00:00
Michael Gottesman
41747b6ce2 [+0 self] Enforce the retain/copy, call, release/destroy pattern for @guaranteed and @in_guaranteed parameters.
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
2015-03-20 07:34:51 +00:00
Joe Groff
970958c43c SILGen: Support method and property lookup on boxed existentials.
Swift SVN r26290
2015-03-19 02:10:14 +00:00
Joe Groff
f5676400f5 SILGen: Don't leak when opening an existential 'self' argument to an application.
Swift SVN r26289
2015-03-19 00:54:02 +00:00
Michael Gottesman
3c2216b115 [+0 self] Add the deallocating parameter convention.
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
2015-03-16 07:51:11 +00:00
Joe Groff
962a87f444 SIL: Rename address-only existential instructions to '{init,deinit,open}_existential_addr'.
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
2015-03-09 23:55:31 +00:00
Joe Groff
5629d5cdd0 SILGen: Handle scalar-to-tuple shuffles in function arguments.
Deferring to emitRValue doesn't work for inout parameters. Factor out the code for shuffling arguments in TupleShuffleExprs so we can reuse for ScalarToTuple transformations. Building what amounts to a fake TupleShuffle out of a ScalarToTuple isn't the most elegant solution, but I think it's the lowest-risk approach for the short term. Fixes rdar://problem/19814841.

Swift SVN r25290
2015-02-14 01:02:13 +00:00
Joe Groff
7d811bf1da SILGen: Load when an lvalue base is passed to a nonmutating accessor.
This shouldn't happen, but this is a low-risk workaround to fix rdar://problem/19782170.

Swift SVN r25241
2015-02-12 17:01:56 +00:00
Joe Groff
b0fabcef7b Sema: Force dynamic materializeForSet accessors to be statically dispatched.
The materializeForSet accessor for a `dynamic` property needs to dynamically invoke the getter and setter of the property in order to allow for runtime modification, so it doesn't need to be dynamically dispatched itself. If the property came from an imported ObjC class, then we can't dynamically dispatch it without polluting the selector namespace. Introduce a new 'ForcedStaticDispatch' bit and set it in order to force `dynamic` materializeForSet accessors to be statically dispatched. (They can't be `final` because it's legal to override a dynamic property.) If the property came from ObjC, register materializeForSet as an external declaration so it gets generated by SIL. Fixes rdar://problem/18706056.

Swift SVN r24930
2015-02-04 00:46:24 +00:00
Nadav Rotem
3d8e7bcf92 Fix a few warnings of unused variables in the -no-assertions build.
Swift SVN r24921
2015-02-03 19:41:10 +00:00
John McCall
bf75beeb7a Begin formal accesses on l-value arguments immediately before
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
2015-01-24 13:05:46 +00:00
John McCall
cae0f6e3db Add the ability for a owning addressor to return
a non-native owner.  This is required by Slice, which
will use an ObjC immutable array object as the owner
as long as all the elements are contiguous.

As part of this, I decided it was best to encode the
native requirement in the accessor names.  This makes
some of these accessors really long; we can revisit this
if we productize this feature.

Note that pinning addressors still require a native
owner, since pinning as a feature is specific to swift
refcounting.

Swift SVN r24420
2015-01-14 19:14:20 +00:00
John McCall
6a46350546 Bugfixes for the new addressor kinds.
Permit non-Ordinary accesses on references to functions,
with the semantics of devirtualizing the call if the
function is a class member.  This is important for
constructing direct call to addressors from synthesized
materializeForSet accessors: for one, it's more
performant, and for another, addressors do not currently
appear in v-tables.

Synthesize trivial accessors for addressed class members.
We weren't doing this at all before, and I'm still not
sure we're doing it right in all cases.  This is a mess.

Assorted other fixes.  The new addressor kinds seem
to work now.

Swift SVN r24393
2015-01-13 10:37:22 +00:00
John McCall
dc4431ebff Split addressors into unsafe, owning, and pinning variants.
Change all the existing addressors to the unsafe variant.

Update the addressor mangling to include the variant.

The addressor and mutable-addressor may be any of the
variants, independent of the choice for the other.

SILGen and code synthesis for the new variants is still
untested.

Swift SVN r24387
2015-01-13 03:09:16 +00:00
John McCall
f3dc58667d Improve the typing of materializeForSet callbacks to
use a thin function type.

We still need thin-function-to-RawPointer conversions
for generic code, but that's fixable with some sort of
partial_apply_thin_recoverable instruction.

Swift SVN r24364
2015-01-11 21:13:35 +00:00
John McCall
44eec49842 Change the signature of materializeForSet to return an
optional callback; retrofit existing implementations.

There's a lot of unpleasant traffic in raw pointers here
which I'm going to try to clean up.

Swift SVN r24123
2014-12-23 22:14:38 +00:00
John McCall
a86ebcfb17 Require that the argument to an early emitter still be
in expression form.

Swift SVN r23963
2014-12-16 21:11:54 +00:00
John McCall
43f28f4aa9 Split SIL emission for builtin functions into its own file.
NFC for now, but I've also added the infrastructure to allow
"early emission", i.e. emission directly from the original
RValueSource, which can be useful either as an optimization
(e.g. for Builtin.initialize) or a requirement for particularly
hacky SIL intrinsics should we need them (and I'm thinking of
needing one).

Swift SVN r23953
2014-12-16 02:02:54 +00:00
Chris Lattner
9662c65938 tidy up some code weirdisms that John pointed out, NFC.
Swift SVN r23867
2014-12-11 21:14:36 +00:00
Chris Lattner
5d8613c7c9 Introduce a new "Indirect_In_Guaranteed" SIL parameter convention. This
isn't used yet, but will be for modeling the self argument passed to an 
address-only witness implementation.   NFC since all this code is dead :-)



Swift SVN r23857
2014-12-11 01:41:29 +00:00
John McCall
3b4e0d307e Intrinsic support for pinning.
Using the intrinsics is obnoxious because I needed them
to return Builtin.NativeObject?, but there's no reasonable
way to safely generate optional types from Builtins.cpp.
Ugh.

Dave and I also decided that there's no need for
swift_tryPin to allow a null object.

Swift SVN r23824
2014-12-10 00:52:48 +00:00
John McCall
b376264442 Bind mark_dependence as Builtin.markDependence.
Swift SVN r23707
2014-12-05 00:38:03 +00:00
John McCall
b0adca8115 Base prepareAccessorBaseArg's behavior in a more principled
way on whether the accessor consumes its self argument, rather
than a simple type analysis.

Swift SVN r23601
2014-12-01 23:50:00 +00:00
Joe Groff
f8dfcaa84e SIL: Consider the original Clang type of a decl before bridging Bool back to ObjCBool.
It's not always correct to map a Swift Bool back to ObjCBool in C land, since Bool could have originally been a proper _Bool. Pass the clang::Decl down to type lowering so we can recognize this. We still don't have a great solution for block types, because there's no decl to refer to, and Swift's user-level type system erases the distinction between void(^)(_Bool) and void(^)(BOOL). However, this is enough to let us start using C APIs that traffic in _Bool.

Swift SVN r23546
2014-11-22 05:21:55 +00:00
Michael Gottesman
1afc987739 Refactor the SILArgument API on SILBasicBlock so we can insert bb arguments anywhere in the argument list. Also clean up the API names so that they all match.
Swift SVN r23543
2014-11-22 00:24:40 +00:00
John McCall
5672a42e46 Ensure that LValues are uniquely used.
Swift SVN r23492
2014-11-20 23:01:15 +00:00
Arnold Schwaighofer
c322b3592d Add a data dependence between opened existential values and method_inst that 'use' them.
Before this patch there was no dependence visible to the optimizer between a
open_existential and the witness_method allowing the optimizer to reorder the
two instruction. The dependence was implicit in the opened archetype but this
is not a concept model by the SIL optimizer.

  %2 = open_existential %0 : $*FooProto to $*@opened("...") FooProto
  %3 = witness_method $@opened("...") FooProto,
                      #FooProto.bar!1 : $@cc(...)
  %4 = apply %3<...>(%2)

This patch changes the SIL representation such that witness_methods on opened
archetypes take the open_existential (or the producer of the opened existential)
as an operand preventing the optimizer from reordering them.

  %2 = open_existential %0 : $*FooProto to $*@opened("...") FooProto
  %3 = witness_method $@opened("...") FooProto,
                      #FooProto.bar!1,
                      %2 : $*@opened("...") FooProto : $@cc(...)
  %4 = apply %3<...>(%2)

rdar://18984526

Swift SVN r23438
2014-11-19 17:22:22 +00:00
Joe Groff
055e8671a0 SILGen: Fix memory leak when casting from address-only to loadable trivial type.
The result does not carry a meaningful cleanup when trivial. Fixes rdar://problem/18936388.

Swift SVN r23284
2014-11-12 21:03:15 +00:00
Joe Groff
b73b22a179 Remove meaningless code.
Swift SVN r23278
2014-11-12 18:13:40 +00:00
Joe Groff
aa3f35c28d Don't consider DynamicTypeExpr or MetatypeConversionExpr to produce a statically derived metatype.
Though the value may be statically known in some cases, that isn't good enough to do what we try to do with this information. In particular, if we invoke a class method on a MetatypeConversion, we want to dispatch to the method of the original metatype, not statically call the method of the converted type, which is what is evident in the AST. Fixes rdar://problem/18877135.

Swift SVN r23277
2014-11-12 18:10:31 +00:00
Joe Groff
976d1db2f8 SILGen: Don't leak BridgeObjects when we cast their bit patterns.
Fixes rdar://problem/18925836.

Swift SVN r23240
2014-11-11 19:16:14 +00:00
Joe Groff
db4ff15380 SILGen: Implement partial application of generic methods.
Most of the parts were already here. We mishandled a few edge cases in RValueEmitter because of MemberRefExpr/ApplyExpr confusion at the Sema level, and we artifically asserted that we didn't support this. Removing the assertion and wiring up the existing thunking infrastructure made this just fall out. Fixes rdar://problem/18763738.

Swift SVN r22944
2014-10-26 02:34:26 +00:00
Joe Groff
5a2f48e3be Add a Builtin.BridgeObject type.
This is a type that has ownership of a reference while allowing access to the
spare bits inside the pointer, but which can also safely hold an ObjC tagged pointer
reference (with no spare bits of course). It additionally blesses one
Foundation-coordinated bit with the meaning of "has swift refcounting" in order
to get a faster short-circuit to native refcounting. It supports the following
builtin operations:

- Builtin.castToBridgeObject<T>(ref: T, bits: Builtin.Word) ->
  Builtin.BridgeObject

  Creates a BridgeObject that contains the bitwise-OR of the bit patterns of
  "ref" and "bits". It is the user's responsibility to ensure "bits" doesn't
  interfere with the reference identity of the resulting value. In other words,
  it is undefined behavior unless:

    castReferenceFromBridgeObject(castToBridgeObject(ref, bits)) === ref

  This means "bits" must be zero if "ref" is a tagged pointer. If "ref" is a real
  object pointer, "bits" must not have any non-spare bits set (unless they're
  already set in the pointer value). The native discriminator bit may only be set
  if the object is Swift-refcounted.

- Builtin.castReferenceFromBridgeObject<T>(bo: Builtin.BridgeObject) -> T

  Extracts the reference from a BridgeObject.

- Builtin.castBitPatternFromBridgeObject(bo: Builtin.BridgeObject) -> Builtin.Word

  Presents the bit pattern of a BridgeObject as a Word.

BridgeObject's bits are set up as follows on the various platforms:

i386, armv7:

  No ObjC tagged pointers
  Swift native refcounting flag bit: 0x0000_0001
  Other available spare bits:        0x0000_0002

x86_64:

  Reserved for ObjC tagged pointers: 0x8000_0000_0000_0001
  Swift native refcounting flag bit: 0x0000_0000_0000_0002
  Other available spare bits:        0x7F00_0000_0000_0004

arm64:

  Reserved for ObjC tagged pointers: 0x8000_0000_0000_0000
  Swift native refcounting flag bit: 0x4000_0000_0000_0000
  Other available spare bits:        0x3F00_0000_0000_0007

TODO: BridgeObject doesn't present any extra inhabitants. It ought to at least provide null as an extra inhabitant for Optional.

Swift SVN r22880
2014-10-23 00:09:23 +00:00
Joe Groff
e3f9a2035c SIL: Move SILGen and passes over to use "builtin" instead of "apply (builtin_function_ref)".
Swift SVN r22785
2014-10-15 23:37:22 +00:00
Chris Lattner
558439b507 simplify the implementation of emitMetatypeOfValue a bit, NFC.
Swift SVN r22733
2014-10-14 21:06:15 +00:00