Commit Graph

57 Commits

Author SHA1 Message Date
John McCall
e249fd680e Destructure result types in SIL function types.
Similarly to how we've always handled parameter types, we
now recursively expand tuples in result types and separately
determine a result convention for each result.

The most important code-generation change here is that
indirect results are now returned separately from each
other and from any direct results.  It is generally far
better, when receiving an indirect result, to receive it
as an independent result; the caller is much more likely
to be able to directly receive the result in the address
they want to initialize, rather than having to receive it
in temporary memory and then copy parts of it into the
target.

The most important conceptual change here that clients and
producers of SIL must be aware of is the new distinction
between a SILFunctionType's *parameters* and its *argument
list*.  The former is just the formal parameters, derived
purely from the parameter types of the original function;
indirect results are no longer in this list.  The latter
includes the indirect result arguments; as always, all
the indirect results strictly precede the parameters.
Apply instructions and entry block arguments follow the
argument list, not the parameter list.

A relatively minor change is that there can now be multiple
direct results, each with its own result convention.
This is a minor change because I've chosen to leave
return instructions as taking a single operand and
apply instructions as producing a single result; when
the type describes multiple results, they are implicitly
bound up in a tuple.  It might make sense to split these
up and allow e.g. return instructions to take a list
of operands; however, it's not clear what to do on the
caller side, and this would be a major change that can
be separated out from this already over-large patch.

Unsurprisingly, the most invasive changes here are in
SILGen; this requires substantial reworking of both call
emission and reabstraction.  It also proved important
to switch several SILGen operations over to work with
RValue instead of ManagedValue, since otherwise they
would be forced to spuriously "implode" buffers.
2016-02-18 01:26:28 -08:00
Erik Eckstein
506ab9809f SIL: remove getTyp() from SILValue 2016-01-25 15:00:49 -08:00
practicalswift
8efa5f587e [gardening] Remove "-*- C++ -*-" tag from .cpp files
Emacs assumes .h files are C files by default which is why the
tag "-*- C++ -*-" is needed.

.cpp files do not have this problem.
2016-01-23 12:09:32 +01:00
Slava Pestov
1dff04ebe7 SILGen: Add a new RValue(AbstractionPattern, CanType) constructor 2016-01-11 18:41:29 -08:00
Slava Pestov
941e57c0d9 SILGen: Revert accidental edit from alloc_global patch
Today is a really bad day as far as me not breaking the build goes.
Sorry folks!
2016-01-07 14:32:46 -08:00
Slava Pestov
046606a8f4 SIL: Add a new alloc_global instruction
If a global variable in a module we are compiling has a type containing
a resilient value type from a different module, we don't know the size
at compile time, so we cannot allocate storage for the global statically.

Instead, we will use a buffer, just like alloc_stack does for archetypes
and resilient value types.

This adds a new SIL instruction but does not yet make use of it.
2016-01-07 13:40:48 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
practicalswift
36d7072013 Remove immediately adjacent repeated words ("the the", "for for", "an an", etc.). 2015-12-21 22:16:04 +01: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
Roman Levenstein
42304ee4e4 Minor fix to the copy&paste error in one of my previous patches. NFC.
Swift SVN r30241
2015-07-15 23:40:12 +00:00
Roman Levenstein
e6969a03c7 [silgen] Emit tuple initializers for global variables of trivial tuple types using tuple instructions.
SILGen was not imploding tuple initializers for global variables and always generated an element-by-element initialization.
This made it difficult for GlobalOpt to propagate the value of the global into its uses. Therefore, SILGen now generates tuple instructions to initialize global variables of trivial tuple types.

Swift SVN r30237
2015-07-15 23:40:09 +00:00
Chris Lattner
18cd2d6f1a slightly simplify code.
Swift SVN r27035
2015-04-06 07:04:33 +00:00
Chris Lattner
0c35b2e8d4 refactor a bunch of stuff around Initialization to simplify the code and
make it easier to extend, NFC.

 3 files changed, 196 insertions(+), 238 deletions(-)



Swift SVN r27029
2015-04-06 06:00:30 +00:00
Chris Lattner
f88133cb92 Fix <rdar://problem/18851497> Swiftc fails to compile nested destructuring tuple binding
When imploding a tuple element, not all of the active values may be used (because there
may be subsequent tuple elements), so remove a bogus assert. Fix tuple implosion to remove
the elements from the 'values' list of things in the rvalue because this may be in a nested
tuple context.

It turns out not to be related to the stuff I'm working on afterall, but good to fix.



Swift SVN r26909
2015-04-02 22:44:40 +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
Joe Groff
07a47a02d0 SILGen: Remove InOutInitialization and its related "AddressBinding" initialization kind.
We don't need these now that we don't set up argument bindings via initializations.

Swift SVN r24413
2015-01-14 05:51:01 +00:00
Michael Gottesman
5bfdc670ad [silgen] Move EmitBBArguments into SILGenDecl.cpp since that is the only place it is used and remove the resulting dead methods.
This was done at John's request.

Swift SVN r23623
2014-12-02 23:58:42 +00:00
Michael Gottesman
61f4f28fca Remove trailing whitespace. NFC.
Swift SVN r23622
2014-12-02 23:46:41 +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
Greg Parker
eef633d732 Replace assert(0) with llvm_unreachable() or llvm::report_fatal_error().
Swift SVN r23340
2014-11-15 00:24:32 +00:00
Joe Groff
3c2f1657de SILGen: Copy block arguments, even if they're optional.
Avoids creating a dangling stack block reference when working with imported APIs that take blocks as IUOs, fixing rdar://problem/18132853.

Swift SVN r21662
2014-09-02 23:56:27 +00:00
Joe Groff
9cbb367a00 SILGen: Imploding unmanaged RValues is OK.
Fixes <rdar://problem/16020428>.

Swift SVN r16564
2014-04-19 05:04:40 +00:00
Joe Groff
d149851607 SILGen: Copy blocks received as function arguments.
We want to generally treat blocks as heap objects until proven stack-able by escape analysis, like we do generally with other heap entities. The only place we should be exposed to stack blocks is when they're passed as arguments, so handle this by copy_block'ing any block arguments we get in the function prolog. Optimization can eliminate them when analysis shows the block doesn't escape or is already on the heap.

Swift SVN r16096
2014-04-09 04:35:17 +00:00
Chris Lattner
1344319677 Rename the internal compiler lexicon from val -> let.
Swift SVN r14408
2014-02-26 21:21:18 +00:00
Chris Lattner
e00b354d4b add some SGFContext arguments to a couple of RValueSource methods,
mostly for consistency with the underlying RValue logic they replicate.



Swift SVN r14264
2014-02-22 19:20:07 +00:00
Chris Lattner
28903887e7 Rename the internal compiler lexicon from let -> val.
Swift SVN r13992
2014-02-17 16:48:21 +00:00
Joe Groff
fc4ecc92c7 SILGen: Don't box 'let' bindings inside 'switch' patterns.
If all of the bindings in a pattern column are 'let' bindings, don't box the binding. If there is any 'var' in the column, conservatively fall back to binding a box. Factor out the logic for producing an initialization for a variable into an new emitInitializationForVarDecl method that SILGenPattern can use. Add a 'copyInto' method to RValue that can bind a copy of an rvalue to an Initialization.

This doesn't use Chris's new +0 ManagedValue optimization yet, so we end up with an extra copy_value when the value is bound that might still be avoidable.

Swift SVN r12903
2014-01-24 05:33:14 +00:00
Chris Lattner
246c301bf5 enhance emission of tupleelementexprs to know about +0 values to
avoid temporaries.  This exposed a bug in the RValue tuple scalarization
logic handling +0 values.  This has no impact on the stdlib.


Swift SVN r12874
2014-01-23 20:17:32 +00:00
Chris Lattner
84f9919016 introduce a SGF::emitRValueAsSingleValue helper function to wrap a common
and repetitive pattern.


Swift SVN r12808
2014-01-22 22:51:55 +00:00
Chris Lattner
b782bd4c56 'ignored' SGFContext's are also dead, remove them too.
Swift SVN r12799
2014-01-22 22:27:48 +00:00
Chris Lattner
7cd0f1739a A big part of handling address-only types is making sure that various
emission routines use the SGFContext passed in.  To help with this and
to help the handshake, add a new "isInContext()" representation to 
ManagedValue.  This makes the code producing and consuming these more
explicit.  NFC.


Swift SVN r12783
2014-01-22 21:31:44 +00:00
Chris Lattner
90e1b572f0 split the ManagedValue class out to its own .h/.cpp files.
Swift SVN r12702
2014-01-22 05:42:34 +00:00
John McCall
817e80bde5 Implicit conversions for UncheckedOptional.
rdar://15189000
rdar://15189009

Swift SVN r12260
2014-01-13 23:15:03 +00:00
Chris Lattner
5c5c7829da Rework SILGen of address-only let declarations. Previously, we would just drop them
into heap boxes like var decls.  Now we drop them into stack temporaries like rvalues.

No semantic change goes with this.



Swift SVN r11939
2014-01-06 19:42:50 +00:00
Chris Lattner
1ca2722e83 introduce ManagedValue::forLValue(x) as a helper function for
making LValue ManagedValues, and switch SILGenLValue to use
this form of managed value consistently for lvalues, instead of
using unmanaged values in some cases.  NFC. 


Swift SVN r11878
2014-01-04 00:45:05 +00:00
Chris Lattner
be58684653 further detangle @inout and @lvalue types, making the code more specific
and simpler.


Swift SVN r11801
2014-01-01 21:35:31 +00:00
Chris Lattner
2aab668817 Change two places that can only see @inout types, not @lvalue types.
Swift SVN r11733
2013-12-30 06:57:13 +00:00
Chris Lattner
9ae289de46 Drive the semantic wedge harder into lvalues. Now, instead of having one LValueType
with qualifiers on it, we have two distinct types:
 - LValueType(T) aka @lvalue T, which is used for mutable values on the LHS of an
   assignment in the typechecker.
 - InOutType(T) aka @inout T, which is used for @inout arguments, and the implicit
   @inout self argument of mutable methods on value types.  This type is also used
   at the SIL level for address types.

While I detangled a number of cases that were checking for LValueType (without checking
qualifiers) and only meant @inout or @lvalue, there is more to be done here.  Notably,
getRValueType() still strips @inout, which is totally and unbearably wrong.



Swift SVN r11727
2013-12-29 22:23:11 +00:00
Chris Lattner
5faf530cf2 implement restructuring assignment of let decls, repurposing the existing
implosion logic.  This resolves rdar://15716277


Swift SVN r11679
2013-12-27 22:30:28 +00:00
Chris Lattner
90284eca72 reimplement cleanup processing for 'let' VarDecls. Previously, we would
emit the cleanup for the initializing expression when the expression was
complete, instead of at the end of the let decl scope (releasing things 
too early).

This fixes rdar://15689514, thanks to DaveA for the great testcase.


Swift SVN r11516
2013-12-20 18:50:03 +00:00
Chris Lattner
1788421e5d Change SILGen to lower and bind non-address-only 'let' variables
as values, without a box at all.  This generalizes some of the
previous hacks I had for silgen'ing 'self' as a value instead of
a box, and capturing them with CaptureKind::Constant.




Swift SVN r11360
2013-12-16 20:36:16 +00:00
Adrian Prantl
2acb71831e SILArgument: Make Decls mandatory for function arguments.
Swift SVN r11099
2013-12-10 23:30:23 +00:00
John McCall
20e58dcf93 Change the type of function values in SIL to SILFunctionType.
Perform major abstraction remappings in SILGen.  Introduce
thunking functions as necessary to map between abstraction
patterns.

Swift SVN r10562
2013-11-19 22:55:09 +00:00
John McCall
08171453da Make it a bit easier to propogate expressions around instead
of having to lower to an RValue.

This is valuable because we can often emit an expression to a
desired abstraction level more efficiently than just emitting
it to minimal abstraction and then generalizing.

Swift SVN r10455
2013-11-14 05:25:06 +00:00
Adrian Prantl
9ad9548388 Debug info: Update the inout testcase and emit debug information for
unboxed [inout] arguments.

Swift SVN r9187
2013-10-11 01:00:46 +00:00
Joe Groff
3d4c1251f1 Rename 'byref' attribute to 'inout'.
Swift SVN r8661
2013-09-25 20:56:52 +00:00
Joe Groff
7c3e1e1dd1 SILGen: Emit semantic-to-storage conversions in implicit struct ctors.
If a struct has [unowned] fields and an implicit elementwise constructor, then the constructor receives a strong reference argument corresponding to the unowned field, and we have to introduce that conversion as part of the construction.

Swift SVN r8207
2013-09-13 20:39:03 +00:00
Anna Zaks
32e14dc63b [SIL] Add another missing location (for BBArguments).
Swift SVN r8084
2013-09-10 22:52:41 +00:00
Anna Zaks
369a948248 [SIL] Minor auto-generated SILLocation API rename/refactor.
Swift SVN r8018
2013-09-06 23:57:27 +00:00
John McCall
b9dea7f458 Remove the emitSemantic* methods from TypeLowering and
move the corresponding functionality into SILGen.

I've switched around 'assign' so that it's no longer a
semantic assignment --- that is, so that it expects a properly
lowered value as its operand, not an r-value of the semantic
type.  This actually simplifies quite a lot of code and removes
some ugly special-casing from MemoryPromotion.

Swift SVN r7942
2013-09-05 06:44:50 +00:00