Commit Graph

1232 Commits

Author SHA1 Message Date
John McCall
2df6880617 Introduce ProtocolConformanceRef. NFC.
The main idea here is that we really, really want to be
able to recover the protocol requirement of a conformance
reference even if it's abstract due to the conforming type
being abstract (e.g. an archetype).  I've made the conversion
from ProtocolConformance* explicit to discourage casual
contamination of the Ref with a null value.

As part of this change, always make conformance arrays in
Substitutions fully parallel to the requirements, as opposed
to occasionally being empty when the conformances are abstract.

As another part of this, I've tried to proactively fix
prospective bugs with partially-concrete conformances, which I
believe can happen with concretely-bound archetypes.

In addition to just giving us stronger invariants, this is
progress towards the removal of the archetype from Substitution.
2016-01-08 00:19:59 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Joe Groff
5e206f35a1 SILGen: Generate closure contexts as guaranteed.
When enabled, generate closure functions with guaranteed conventions as their context parameters, and pass context arguments to them as guaranteed when possible. (When forming a closure by partial_apply, the partial apply still needs to take ownership of the parameters, regardless of their convention.)
2015-12-31 15:10:27 -08:00
Joe Groff
b76c0abc37 SIL: Lower closure capture params out-of-band from the formal type.
Instead of bodging a representation of the SIL capture parameters for a closure into the formal type of closure SILDeclRefs, introduce those parameters in a separate lowering step. This lets us clean up some TypeLowering code that was tolerating things like SILBoxTypes and naked LValueTypes in formal types for nefarious ends (though requires some hacks in SILGen to keep the representation of curry levels consistent, which is something I hope to clean up next). This also decouples the handling of captures from the handling of other parameters, which should enable us to make them +0. For now, there should be NFC.
2015-12-30 10:32:36 -08:00
practicalswift
fa0b339a21 Fix typos. 2015-12-26 17:51:59 +01:00
practicalswift
36d7072013 Remove immediately adjacent repeated words ("the the", "for for", "an an", etc.). 2015-12-21 22:16:04 +01:00
practicalswift
8ab8847684 Fix typos. 2015-12-16 22:09:32 +01:00
Davide Italiano
2e78fdf58f Fix a bunch of pessimizing moves which prevent copy elision. 2015-12-11 19:09:13 +00:00
Slava Pestov
832a637c04 SIL: Start cleaning up getMethodDispatch() / requiresObjCDispatch()
Move these to SILDeclRef, maybe not the best place but a good home for now.
Factor out a new requiresForeignToNativeThunk() function, which cleans up
some code duplication introduced by the following patch:

478e1c7513

This is a small step towards consolidating duplicated logic for figuring out
method dispatch semantics and emitting curry thunks.
2015-12-11 08:58:52 -08:00
David Farler
e6d1d9748b SILGen: Use the base SILDeclRef for super_method override constant info
getOverriddenVTableEntry only goes one level up in the class hierarchy,
but getConstantOverrideInfo requires that the next level up not itself be an
override.

A little bit of refactoring:

SILDeclRef::getOverriddenVTableEntry()
  -> SILDeclRef::getNextOverriddenVTableEntry()

static findOverriddenFunction()
  -> SILDeclRef::getBaseOverriddenVTableEntry()

rdar://problem/22749732
2015-12-10 15:47:50 -08:00
David Farler
09c6210afa SILGen: Use vtable thunk abstraction for super_method instructions
The constant provided to the callee for super methods reference the
backing implementation, but the vtable entry may point to a thunk with
different abstraction when using mixed concrete and generic classes in
the hierarchy. The SIL devirtualizer expects super method references to
match what's in the vtable.

Also update the verifier for SuperMethodInst types - before it required
that the types be the same, but they may not be for the same reasons noted
above. Instead, do a similar check as for ClassMethodInst.

https://bugs.swift.org/browse/SR-134
2015-12-10 13:53:09 -08:00
David Farler
a04a557404 SILGen: Substitute generics for partial super_method instructions
These need to be provided to partial_apply instructions.
2015-12-10 12:12:00 -08:00
John McCall
23ea72b21e Teach IRGen to apply the ARC autorelease optimization implicitly
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.
2015-12-09 00:49:42 -08:00
Joe Groff
b1667ec705 SIL: Introduce a new @inout_aliasable parameter convention.
Modeling nonescaping captures as @inout parameters is wrong, because captures are allowed to share state, unlike 'inout' parameters, which are allowed to assume to some degree that there are no aliases during the parameter's scope. To model this, introduce a new @inout_aliasable parameter convention to indicate an indirect parameter that can be written to, not only by the current function, but by well-typed, well-synchronized aliasing accesses too. (This is unrelated to our discussions of adding a "type-unsafe-aliasable" annotation to pointer_to_address to allow for safe pointer punning.)
2015-12-08 14:35:47 -08:00
David Farler
6825b27316 Use calculated uncurry level to determine how to emit partial super_method
There was a mis-refactoring when removing the LatePartialSuperEmitter,
using the wrong uncurryLevel check when using the inlined emitter.
This fixes a crash with partially applied super methods.

The test was updated for this case.
2015-12-08 13:20:37 -08:00
David Farler
b53ff3b580 SILGen: Refactor LatePartialSuperEmitter
We proabably aren't going to continue using this pattern, so just
inline the code at its single point of use. NFC.
2015-12-07 21:57:37 -08:00
David Farler
a53a31cb6e SILGen: Use super_method for native non-final methods in classes
Use the `super_method` instruction for non-final `func` and `class func`
declarations in native Swift classes. Previously, we would always emit
a static `function_ref` for these, which prevents resilient dynamic
dispatch.

This is hidden behind a -use-native-super-dispatch flag while I
survey the effects on devirtualization and stack promotion. When
that's figured out, I'll add more tests and update test cases that
still assume static dispatch.

rdar://problem/22749732
2015-12-05 13:06:31 -08:00
Slava Pestov
d0d038bdab SILGen: Fix early return from enum payload initialization
This is a regression from the following commit, caught by
validation-tests/stdlib/String:

7496730f69

I'll add SILGen tests for this case later, for now just fix
the broken build.
2015-12-05 03:40:03 -08:00
Slava Pestov
a7a9e16298 SILGen: Open code calls of enum case constructors
Sema models enum case constructors as ApplyExprs. Formerly SILGen
would emit a case constructor function for each enum case,
constructing the enum value in the constructor body. ApplyExprs
of case constructors were lowered like any other call.

This is nice and straightforward but has several downsides:

1) Case constructor functions are very repetitive and trivial,
   in particular for no-payload cases. They were declared
   @_transparent and so were inlined at call sites, but for
   public enums they still had to be emitted into the final
   object file.

2) If the enum is generic, the substituted type may be loadable
   even if the unsubstituted type is not, but since the case
   constructor is polymorphic we had to allocate stack buffers
   anyway, to pass the payload and result at the right abstration
   level. This meant that for example Optional.Some(foo)
   generated less-efficient SIL than the equivalent implicit
   conversion.

3) We were missing out on peephole optimization opportunities when
   the payload of an indirect case or address-only enum could be
   emitted directly into the destination buffer, avoiding a copy.
   One example would be when an enum payload is the result of
   calling a function that returns an address-only value indirectly.
   It appears we had unnecessary copies and takes even with -O.
   Again, optional implicit conversions special-cased this.

This patch implements a new approach where a fully-formed call to
a element constructor is handled via a special code path where
the 'enum' or 'init_enum_data_addr' / 'inject_enum_addr'
instructions are emitted directly. These always work on the
substituted type, avoiding stack allocations unless needed.
An additional optimization is that the ArgumentSource abstraction
is used to delay evaluation of the payload argument until the
indirect box or address-only payload was set up.

If a element constructor is partially applied, we still emit a
reference to the constant as before.

It may seem like case constructor functions are at least useful
for resilience, but case constructors are transparent, so making
them resilient would require a new "transparent but only in this
module, and don't serialize the SIL body" declaration.
@inline(always) is almost what we need here, but this affect
mandatory inlining, only the optimizer, so it would be a
regression for non-resilient enums, or usages of resilient enums
in the current module.

A better approach is to construct resilient enums with a new
destructiveInjectEnumTag value witness function, which is
coming soon, and the general improvement from that approach
is what prompted this patch.
2015-12-05 01:44:44 -08:00
Slava Pestov
7496730f69 SILGen: Add a new SILGenFunction::emitInjectEnum() function, NFC
This factors out code duplication between InjectIntoOptionalExpr and
enum case constructors, and will eventually be used in other places
too.
2015-12-05 01:44:44 -08:00
Slava Pestov
2fa0bf82a2 SILGen: Simplify instance variables of Callee class, NFC 2015-12-05 01:44:44 -08:00
Slava Pestov
9025cf881d SILGen: Add comments describing call decomposition in more detail, NFC 2015-12-05 01:37:55 -08:00
David Farler
6d831bd00e Add specialized emitter for partially applied super_method
This creates the heavy lifting in SILGen of emission of super methods
with the implicit self partially applied, which is still possible even
after removing curried function declaration syntax.

NFC for current IRGen - SILGen doesn't lead to here yet.

rdar://problem/22749732
2015-12-05 01:29:27 -08:00
Slava Pestov
c73a04d865 SILGen: ApplyOptions::Transparent and related support logic is dead, NFC 2015-11-30 20:33:22 -08:00
Slava Pestov
1b55becf76 SILGen: Fix issues with one-element tuples in thunks
Take apart exploded one-element tuples and be more careful with
passing around tuple abstraction patterns.

Also, now we can  remove the inputSubstType parameter from
emitOrigToSubstValue() and emitSubstToOrigValue(), making the
signatures of these functions nice and simple once again.

Fixes <rdar://problem/19506347> and <rdar://problem/22502450>.
2015-11-06 13:51:15 -08:00
Slava Pestov
736beddf1b SILGen: Cleanup, NFC 2015-11-05 21:46:04 -08:00
Slava Pestov
533f42dd2f Closures and local functions only capture generic parameters if necessary
The CaptureInfo computed by Sema now records if the body of the
function uses any generic parameters from the outer context.
SIL type lowering only adds a generic signature if this is the
case, instead of unconditionally.

This might yield a marginal performance improvement in some cases,
but more interestingly will allow @convention(c) conversions from
generic context.

Swift SVN r32161
2015-09-22 21:08:28 +00:00
Slava Pestov
e1f0f02480 SILGen: Three-parameter re-abstraction thunks
Right now, re-abstraction thunks are set up to convert values
as follows, where L is type lowering:

- OrigToSubst: L(origType, substType) -> L(substType)
- SubstToOrig: L(substType) -> L(origType, substType)

This assumes there's no AST-level type conversion, because
when we visit a type in contravariant position, we flip the
direction of the transform but we're still converting *to*
substType -- which will now equal to the type of the input,
not the type of the expected result!

This caused several problems:

- VTable thunk generation had a bunch of special logic to
  compute a substOverrideType, and wrap the thunk result
  in an optional, duplicating work done in the transform

- Witness thunk generation similarly had to handle the case
  of upcasting to a base class to call the witness, and
  casting the result of materializeForSet back to the right
  type for properties defined on the base.

  Now the materializeForSet cast sequence is a bit longer,
  we unpack the returned tuple and do a convert_function
  on the function, then pack it again -- before we would
  unchecked_ref_cast the tuple, which is technically
  incorrect since the tuple is not a ref, but IRGen didn't
  seem to care...

To handle the conversions correctly, we add a third AST type
parameter to a transform, named inputType. Now, transforms
perform these conversions:

- OrigToSubst: L(origType, inputType) -> L(substType)
- SubstToOrig: L(inputType) -> L(origType, substType)

When we flip the direction of the transform while visiting
types in contravariant position, we also swap substType with
inputType.

Note that this is similar to how bridging thunks work, for
the same reason -- bridging thunks convert between AST types.

This is mostly just a nice cleanup that fixes some obscure
corner cases for now, but this functionality will be used
in a subsequent patch.

Swift SVN r31486
2015-08-26 09:15:29 +00:00
Slava Pestov
7a2018ef52 SILGen: fix conversions from @convention(c) to @convention({thick,block})
Also clean up some code and add some tests for FunctionConversionExpr,
which will be very important in subsequent patches.

Swift SVN r31400
2015-08-22 03:17:02 +00:00
Slava Pestov
e416bfbc4e SILGen: Refactor code for existentials
We need to be able to introduce and eliminate existentials inside
reabstraction thunks, so make this logic independent of RValue
and Expr emission.

NFC for now.

Swift SVN r31375
2015-08-21 02:26:57 +00:00
Slava Pestov
9b74a4b0d6 SILGen: Fix memory leak when sub-expression of ErasureExpr throws
If we didn't initialize the existential, we have to emit a cleanup
because we may have allocated a buffer on the heap to store the value.

Factor out the TakeExistentialCleanup that appears in a few places,
rename it to DeinitExistentialCleanup and add support for deallocating
boxed existentials.

Then, use a special Initialization subclass to keep track of the
state of the memory in emit{AddressOnly,Boxed}Erasure().

Swift SVN r31259
2015-08-16 16:45:44 +00:00
John McCall
0c39ec02fa Don't use materializeForSet when accessing properties or
subscripts defined in protocol extensions.

The right condition for this is really direct uses of the
default implementation; right now, that just means all
direct uses of something from a protocol extension.

Fixes rdar://22109071.

Swift SVN r31228
2015-08-13 21:49:14 +00:00
John McCall
7e81f7e129 Fix a number of bugs with the new materializeForSet SILGen,
including one which triggered only for non-subscripts and
a number which triggered with different cases of classes.

Swift SVN r31198
2015-08-13 01:52:17 +00:00
Slava Pestov
48fe3e1c9b SILGen: Fix static computed properties in protocol extensions
We need to keep the AST formal type of the base around when building up
lvalues.

When the getter or setter involves an accessor call, we would use the
lowered type of the self argument to form the call. However, it might be
at the wrong level of abstraction, causing a @thin -vs- @thick metatype
mismatch. Using the formal type instead allows SILGenApply logic to emit
a thin to thick metatype conversion if necessary.

Fixes <rdar://problem/21358641>.

Swift SVN r30913
2015-08-01 07:21:25 +00:00
Doug Gregor
07135ac4e9 Handle initializer delegation in a protocol extension with a class-bound Self.
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
2015-07-24 18:22:43 +00:00
Doug Gregor
f00e5bc6ab Allow a variadic parameter anywhere in the parameter list.
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
2015-07-23 18:45:29 +00:00
Slava Pestov
35e55940ca SILGen: Fix miscompile if witness is a property defined in base class
Fixes <rdar://problem/21375219>.

Swift SVN r29901
2015-07-02 21:31:07 +00:00
Slava Pestov
7b2aa2c0a2 SILGen: Fix lvalue reabstraction
We didn't have any tests exercising SubstToOrigComponent and in
fact it was broken. Fix emitInOut() to remove a level of inout
from the origParam abstraction pattern and add some tests.

Fixes <rdar://problem/20985062>.

Swift SVN r29644
2015-06-24 22:27:54 +00:00
Slava Pestov
a64d505a98 SILGen: Fix some problems when generating delegating init calls
- 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
2015-06-22 22:26:17 +00:00
Slava Pestov
7319a97ab4 Sema: Rewrite witness method calls as ApplyExpr + DeclRefExpr
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
2015-06-04 15:57:58 +00:00
Joe Groff
96638e3028 SILGen: Properly type reabstracted overrides in calls and witness thunks.
Fixes most of rdar://problem/20874966, though curry thunks are still broken (filed as rdar://problem/21167978).

Swift SVN r29160
2015-05-30 00:41:55 +00:00
John McCall
af25b38029 Teach SILFunctionType substitution to handle foreign error conventions.
Normally, ObjC methods are never generic, but this comes up
with protocol methods.

rdar://21051021

Swift SVN r28900
2015-05-22 01:23:04 +00:00
John McCall
26a9a4d1e5 SILGen for 'rethrows'. WIP; committed to get broader testing
of an assertion.

Swift SVN r28733
2015-05-19 00:54:32 +00:00
John McCall
f0f8787b0f Generalize the 'transparent' flag passed around to
various emitApply routines.  NFC.

Swift SVN r28720
2015-05-18 20:30:12 +00:00
Slava Pestov
2098c60131 SIL: Generate emitRawApply()'s @guaranteed cleanups with CleanupLocation
These used a RegularLocation because the mechanism is different from
the usual Cleanup stuff, which is tied to a specific scope.

Using a CleanupLocation prevents unreachable code diagnostics from
complaining if we call a @noreturn with guaranteed.

If we diagnose while emitting one of the cleanups, the diagnostic will
point to the end of the apply expression rather than the start, but I
don't think that matters.

Swift SVN r28690
2015-05-18 00:26:19 +00:00
John McCall
312a9c1f6e Clean up correctly if a variadic argument throws.
rdar://20942603

Swift SVN r28622
2015-05-15 08:20:36 +00:00
Joe Groff
a32b14e0a8 SILGen: Don't try to witness-dispatch extension inits that delegate to other extension inits.
Fixes rdar://problem/20841699.

Swift SVN r28263
2015-05-07 14:38:34 +00:00
John McCall
36c605f7dc Remove ScalarToTupleExpr in favor of a flag on TupleShuffleExpr.
Also, implement in-place initialization through tuple shuffles.

Swift SVN r28227
2015-05-06 23:44:26 +00:00
Joe Groff
e2962ed213 SILGen: Implement recursive local function references.
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
2015-05-04 05:33:55 +00:00
John McCall
58b5e1dc0f Implement error handling in protocol witness and
reabstraction thunks.

rdar://20782111

Swift SVN r28075
2015-05-02 04:37:30 +00:00