Parameters (to methods, initializers, accessors, subscripts, etc) have always been represented
as Pattern's (of a particular sort), stemming from an early design direction that was abandoned.
Being built on top of patterns leads to patterns being overly complicated (e.g. tuple patterns
have to have varargs and default parameters) and make working on parameter lists complicated
and error prone. This might have been ok in 2015, but there is no way we can live like this in
2016.
Instead of using Patterns, carve out a new ParameterList and Parameter type to represent all the
parameter specific stuff. This simplifies many things and allows a lot of simplifications.
Unfortunately, I wasn't able to do this very incrementally, so this is a huge patch. The good
news is that it erases a ton of code, and the technical debt that went with it. Ignoring test
suite changes, we have:
77 files changed, 2359 insertions(+), 3221 deletions(-)
This patch also makes a bunch of wierd things dead, but I'll sweep those out in follow-on
patches.
Fixes <rdar://problem/22846558> No code completions in Foo( when Foo has error type
Fixes <rdar://problem/24026538> Slight regression in generated header, which I filed to go with 3a23d75.
Fixes an overloading bug involving default arguments and curried functions (see the diff to
Constraints/diagnostics.swift, which we now correctly accept).
Fixes cases where problems with parameters would get emitted multiple times, e.g. in the
test/Parse/subscripting.swift testcase.
The source range for ParamDecl now includes its type, which permutes some of the IDE / SourceModel tests
(for the better, I think).
Eliminates the bogus "type annotation missing in pattern" error message when a type isn't
specified for a parameter (see test/decl/func/functions.swift).
This now consistently parenthesizes argument lists in function types, which leads to many diffs in the
SILGen tests among others.
This does break the "sibling indentation" test in SourceKit/CodeFormat/indent-sibling.swift, and
I haven't been able to figure it out. Given that this is experimental functionality anyway,
I'm just XFAILing the test for now. i'll look at it separately from this mongo diff.
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.)
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.
Now that we open-code enum construction, enum constructor entry points are
only needed when they are partially-applied, which is a rare case. So we
treat them like curry thunks and only emit them as needed.
The main consequence of this is that enum case constructors are no longer
part of our ABI.
To avoid a regression in the code path for diagnosing infinite value types,
force type lowering to walk a type when emitting its declaration, even if
there are no other references to the type in the program (which is now the
case for public enums which are otherwise not used).
Also XFAIL a DebugInfo test since it is not clear to me what the test does
or how to fix it. The obvious change of adding references to the enum
case constructor function to force it to be emitted did not work.
docs/archive/LangRef.html is flagged as unmaintained, but I didn't see
much else about optionals in the docs so why not update it now.
`emitPreconditionOptionalHasValue` had the switch logic moved from the
standard library to lib/SILGen/SILGenConvert.cpp back in 9c7417edc2
and there's no _preconditionOptionalHasValue intrinsic anymore. Updated
the comment in the headers to clarify.
This commit adds a DebugVariable field that is shared by
- AllocBoxInst
- AllocStackInst
- DebugValueInst
- DebugValueAddrInst
Currently DebugVariable only holds the Swift argument number.
This allows us to retire several expensive heuristics in IRGen that
attempted to identify which local variables actually where arguments
and recover their relative order.
Memory footprint notes:
This commit adds a 4-byte field to 4 SILInstructin subclasses.
This was offset by 8ab1e2dd50
which removed 20 bytes from *every* SILInstruction.
Caveats:
This commit surfaces a known bug in FunctionSigantureOpts, tracked in
rdar://problem/23727705 — debug info for exploded function arguments
cannot be expressed until this is fixed.
This reapplies ed2b16dc5a with a bugfix for
generic function arrguments and an additional testcase.
<rdar://problem/21185379&22705926>
This commit adds a DebugVariable field that is shared by
- AllocBoxInst
- AllocStackInst
- DebugValueInst
- DebugValueAddrInst
Currently DebugVariable only holds the Swift argument number.
This allows us to retire several expensive heuristics in IRGen that
attempted to identify which local variables actually where arguments
and recover their relative order.
Memory footprint notes:
This commit adds a 4-byte field to 4 SILInstructin subclasses.
This was offset by 8ab1e2dd50
which removed 20 bytes from *every* SILInstruction.
Caveats:
This commit surfaces a known bug in FunctionSigantureOpts, tracked in
rdar://problem/23727705 — debug info for exploded function arguments
cannot be expressed until this is fixed.
<rdar://problem/21185379&22705926>
The drivers for this change are providing a simpler API to SIL pass
authors, having a more efficient of the in-memory representation,
and ruling out an entire class of common bugs that usually result
in hard-to-debug backend crashes.
Summary
-------
SILInstruction
Old New
+---------------+ +------------------+ +-----------------+
|SILInstruction | |SILInstruction | |SILDebugLocation |
+---------------+ +------------------+ +-----------------+
| ... | | ... | | ... |
|SILLocation | |SILDebugLocation *| -> |SILLocation |
|SILDebugScope *| +------------------+ |SILDebugScope * |
+---------------+ +-----------------+
We’re introducing a new class SILDebugLocation which represents the
combination of a SILLocation and a SILDebugScope.
Instead of storing an inline SILLocation and a SILDebugScope pointer,
SILInstruction now only has one SILDebugLocation pointer. The APIs of
SILBuilder and SILDebugLocation guarantees that every SILInstruction
has a nonempty SILDebugScope.
Developer-visible changes include:
SILBuilder
----------
In the old design SILBuilder populated the InsertedInstrs list to
allow setting the debug scopes of all built instructions in bulk
at the very end (as the responsibility of the user). In the new design,
SILBuilder now carries a "current debug scope" state and immediately
sets the debug scope when an instruction is inserted.
This fixes a use-after-free issue with with SIL passes that delete
instructions before destroying the SILBuilder that created them.
Because of this, SILBuilderWithScopes no longer needs to be a template,
which simplifies its call sites.
SILInstruction
--------------
It is neither possible or necessary to manually call setDebugScope()
on a SILInstruction any more. The function still exists as a private
method, but is only used when splicing instructions from one function
to another.
Efficiency
----------
In addition to dropping 20 bytes from each SILInstruction,
SILDebugLocations are now allocated in the SILModule's bump pointer
allocator and are uniqued by SILBuilder. Unfortunately repeat compiles
of the standard library already vary by about 5% so I couldn’t yet
produce reliable numbers for how much this saves overall.
rdar://problem/22017421
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>.
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.
Previously, SILGen would store a null pointer into the self box upon
encountering a constructor delegation that consumes self. This was a
constant source of bugs. Now, use the new analysis to make this use
DI information instead, emitting an extra bit at runtime if necessary.
Also re-organize the DI tests for initializers, and add CHECK: lines
instead of just asserting we don't crash or diagnose.
Swift SVN r32604
When emitting a RebindSelfInConstructorExpr, the first access of
'self' would take the self value out of the box, since the call
consumes it. This caused a miscompile if we have to load instance
variables to form the call, since then we would try to load from
the box again, dereferencing a null pointer. Now, store the taken
self value and borrow it on subsequent access.
This is a regression from r31141.
Fixes <rdar://problem/22939666>.
Swift SVN r32407
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
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
- 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
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
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
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
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
This reverts commit r30272.
There's a way to fix Builtin.reinterpretCast that preserves SILGen
RValue invariants better according to JohnM. So although these changes
are valid, there will be no way for me to test them.
After reverting this, I will roll back in the change to
emitImplicitValueConstructor because I think the old code was
violating SILGen invariants.
Swift SVN r30306
This is required in order to fix Builtin.reinterpretCast for
address-only types. That upcoming fix will include a test case that
exposes this SILGen path.
Swift SVN r30272
The other part of rdar://problem/21444126. This is a little trickier since SIL doesn't track uses of witness tables in a principled way. Track uses in SILGen by putting a "SILGenBuilder" wrapper in front of SILBuilder, which marks conformances from apply, existential erasure, and metatype lookup instructions as used, so we can avoid emitting shared Clang importer witnesses when they aren't needed.
Swift SVN r29544
This isn't as straightforward as it should be, since EnumElementDecls aren't AbstractFunctionDecls, but luckily there's only one trivial curry level with a thin metatype parameter.
Swift SVN r28991
When emitting try_apply, don't start a new scope between adding
a cleanup and forwarding the value. This would leave behind a
dead cleanup, which would fire an assertion in emitSharedCaseBlocks().
Fixes <rdar://problem/20923654>.
Swift SVN r28572
instead of being an expression.
To the user, this has a couple of behavior changes, stemming from its non-expression-likeness.
- #available cannot be parenthesized anymore
- #available is in its own clause, not used in a 'where' clause of if/let.
Also, the implementation in the compiler is simpler and fits the model better. This
fixes:
<rdar://problem/20904820> Following a "let" condition with #available is incorrectly rejected
Swift SVN r28521