Commit Graph

566 Commits

Author SHA1 Message Date
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
Slava Pestov
e7a3877a42 SILGen: Fix re-abstraction of single-element tuples to opaque pattern
This triggered on the PerfTestSuite but there weren't any tests for it.
Add a simple test, but probably its still wrong, eg opaque-to-opaque
tuple conversions.

A better fix would be to have transforms support conversions where
only one side is a tuple in transformTuple().
2015-11-06 15:36:43 -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
dd5feb616f SILGen: More general re-abstraction thunks
Kill the two Transform subclasses, OrigToSubst and SubstToOrig. Instead,
Transform::transform() and other functions take an abstraction pattern
for both the input and the output value.

This simplifies the code in preparation for resilience expansion thunks.
2015-11-06 11:08:55 -08:00
Slava Pestov
91cf4c11da SIL: Move description of abstraction patterns to AbstractionPattern.h and write new comment in SILGenPoly describing function thunks, NFC
Probably SILGenPoly.cpp should be named SILGenThunk.cpp, but I'm saving
that for if I ever extract the duplication between bridging thunks and
re-abstraction thunks.
2015-11-05 21:49:23 -08:00
Slava Pestov
b3251796ec SILGen: Combine Transform::transformMetatype() implementations, NFC
They're basically doing the same thing, bringing us closer to eliminating
the OrigToSubst and SubstToOrig subclasses of Transform.
2015-11-05 21:46:42 -08:00
Slava Pestov
cbdab7dfca SILGen: Big re-abstraction thunk renaming, NFC
I'm making some big changes here to support resilience and splitting off
the renaming will make code easier to review.
2015-11-05 21:46:41 -08:00
Andrew Trick
57a450b28f Generate unchecked_ref_cast, not unchecked_ref_bit_cast.
This improves support for promoting to and generating
unchecked_ref_cast so we no longer need unchecked_ref_bit_cast, which
will just go away in the next commit.

Swift SVN r32597
2015-10-10 05:42:53 +00:00
Slava Pestov
6d8e600a10 SILGen: Add remaining type conversions to thunk emission
I doubt these are useful at all, but they're easy enough to add
after all the refactoring was done.

Swift SVN r31545
2015-08-27 21:53:58 +00:00
Slava Pestov
0af82e6345 SILGen: Move optional and existential conversions to SILGenConvert.cpp, NFC
This is a better place for code shared between expression emission
and thunks.

Swift SVN r31544
2015-08-27 21:53:49 +00:00
Slava Pestov
4a09d72420 SILGen: Refactor existentials a bit more for use in thunks, NFC
Swift SVN r31526
2015-08-27 08:35:25 +00:00
Slava Pestov
c58899a212 SILGen: Combine emitOrigToSubstMetatype() and emitSubstToOrigMetatype(), NFC
Swift SVN r31525
2015-08-27 08:35:23 +00:00
Slava Pestov
a49198c791 SILGen: FunctionConversionExpr now uses thunking logic, NFC
Swift SVN r31487
2015-08-26 09:15:31 +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
6c944a694e SIL: Move checkForABIDifferences() from SILFunctionType to TypeConverter, NFC
Also make it more accurate by lowering optional payload types, but
nothing depends on this right now.

Apologies for the recent stream of unrelated-looking NFCs -- the goal
here is to make a big upcoming patch easier to review.

Swift SVN r31480
2015-08-26 04:24:27 +00:00
Slava Pestov
689be69345 SILGen: Split off cleanup of transforms code from bigger patch
- Generalize::transformFunction() had a couple of little optimizations
  for emitting convert_function or thin_to_thick_function instead of
  a thunk, if possible -- move this into code shared by all
  transforms

- Nuke Generalize since it doesn't do anything special anymore

Swift SVN r31423
2015-08-24 00:23:57 +00:00
Slava Pestov
074a5577ca SIL: Extract SILFunctionType::checkForABIDifferences(), NFC
There are three implementations of this in SIL so far:
- in emitGeneralizedFunctionValue()
- in emitVTableMethod()
- in the SILVerifier

I haven't touched the latter yet, though.

Swift SVN r31422
2015-08-23 23:10:54 +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
John McCall
807f7f5434 Reimplement materializeForSet emission in SILGen instead of
the type-checker.  The strategy for now is to just use this
for protocol witness thunk emission, where it is required
when generating a materializeForSet for storage that is
either implemented in a protocol extension or requires
reabstraction to the requirement's pattern.

Eventually, this should be generalized to the point that
we can use it for all materializeForSet emission, which
I don't think will take much.  However, that's not really
the sort of instability we want to embrace for the current
release.

WIP towards rdar://21836671; currently disabled, so NFC.

Swift SVN r31072
2015-08-07 09:22:27 +00:00
John McCall
ed0681004c Remove the almost-pointless Materialize type from SILGen,
and stop forcing optionals to memory in a bunch of places
where the callee is perfectly capable of handling a
non-address value.

Swift SVN r30107
2015-07-11 02:58:49 +00:00
Slava Pestov
ee2aacceb9 SILGen: Fix vtable thunk generation for overrides changing Optional to IUO
Actually invoking such an override on an instance of the derived type
still doesn't work, unless you cast to the base type first. Fixing this
requires emitting a new vtable entry for the new signature and is
tracked in <rdar://problem/21435542>.

Fixes <rdar://problem/21364764>.

Swift SVN r29935
2015-07-07 04:41:52 +00:00
Slava Pestov
5c76bb35a6 SILGen: Simpler fix for crash when protocol witness is unary method with default argument
This patch attempts to fix rdar://problem/21452981, which Joe worked on
in r29572, but reverted because that patch had other changes that broke
stuff.

Swift SVN r29934
2015-07-07 04:41:51 +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
Joe Groff
2be344aa33 Revert "SILGen: Make witness parameter translation handle single-element tuples."
This reverts commit r29572, which is breaking some external projects.

Swift SVN r29605
2015-06-24 13:59:33 +00:00
Joe Groff
7a4b80ce4d SILGen: Make witness parameter translation handle single-element tuples.
These still show up if you have a witness with a default argument, which the AST still represents as a single-element tuple, matched against a non-tuple orig type in the witness signature. Handle this by allowing getTupleElementType(0) on non-tuple AbstractionPatterns to work, and tweaking the parallel translation code to drill through single-element tuples and line up the contained scalars properly. Fixes rdar://problem/21452981. (Still left broken is the obnoxious single-element-tuple-of-tuple case, rdar://problem/21496105.)

Now with less Xcode autosave breakage.

Swift SVN r29572
2015-06-23 17:25:47 +00:00
Dave Abrahams
4d7feb72e0 Revert "SILGen: Make witness parameter translation handle single-element tuples."
This reverts commit r29561; JoeG says it was a mistake.

Swift SVN r29562
2015-06-23 00:57:08 +00:00
Joe Groff
87ba8f5123 SILGen: Make witness parameter translation handle single-element tuples.
These still show up if you have a witness with a default argument, which the AST still represents as a single-element tuple, matched against a non-tuple orig type in the witness signature. Handle this by allowing getTupleElementType(0) on non-tuple AbstractionPatterns to work, and tweaking the parallel translation code to drill through single-element tuples and line up the contained scalars properly. Fixes rdar://problem/21452981. (Still left broken is the obnoxious single-element-tuple-of-tuple case, rdar://problem/21496105.)

Swift SVN r29561
2015-06-23 00:27:43 +00:00
Joe Groff
6ef872d471 SILGen: Handle optional variance in overrides before abstracting lowering their signatures.
Fixes rdar://problem/21154055.

Swift SVN r29406
2015-06-16 23:01:01 +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
Joe Groff
66e1f37e62 SILGen: Reabstraction for vtable entries.
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
2015-05-13 03:25:05 +00:00
Slava Pestov
fd256e70e3 EmitGuaranteedSelf is always on now
NFC except for removal of flag

Swift SVN r28427
2015-05-11 18:21:37 +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
Joe Groff
21890883ac SILGen: Remove obsolete 'stripInputTupleLabels' hack from witness generation.
Keyword labels are now required to match between a protocol requirement and witness, so this hack is dead code.

Swift SVN r27536
2015-04-21 20:12:49 +00:00
Chris Lattner
d874bc8592 fix comment. NFC.
Swift SVN r27456
2015-04-18 22:13:33 +00:00
Michael Gottesman
38b1818b1b Convert code to use a covered switch. NFC.
Swift SVN r27310
2015-04-15 04:05:41 +00:00
Michael Gottesman
0bef564982 Loosen an assert.
The translation code already handles translating in_guaranteed arguments
correctly. The assert was just too conservative.

<rdar://problem/20522878>

Swift SVN r27307
2015-04-15 02:40:37 +00:00
Michael Gottesman
75ea31dba9 Turn on +0 self by default.
The only caveat is that:

1. We do not properly recognize when we have a let binding and we
perform a guaranteed dynamic call. In such a case, we add an extra
retain, release pair around the call. In order to get that case I will
need to refactor some code in Callee. I want to make this change, but
not at the expense of getting the rest of this work in.

2. Some of the protocol witness thunks generated have unnecessary
retains or releases in a similar manner.

But this is a good first step.

I am going to send a large follow up email with all of the relevant results, so
I can let the bots chew on this a little bit.

rdar://19933044

Swift SVN r27241
2015-04-12 22:23:37 +00:00
Michael Gottesman
a79b97f0a1 Fix typo. NFC.
Swift SVN r27153
2015-04-09 01:38:12 +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
Chris Lattner
95b7b4d5e4 rename CleanupLocation::getCleanupLocation -> CleanupLocation::get, NFC.
Swift SVN r26994
2015-04-04 22:56:01 +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
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
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
5fa20867e9 SILGen: Implement thunking for C function pointer conversions.
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
2015-03-01 06:18:58 +00:00
Adrian Prantl
45544727ac Mark reabstraction thunk helpers as auto-generated.
Fixes <rdar://problem/18670152> Stack trace is a lie.

Swift SVN r25362
2015-02-18 00:46:25 +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
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