This was already done for getSuccessorBlocks() to distinguish getting successor
blocks from getting the full list of SILSuccessors via getSuccessors(). This
commit just makes all of the successor/predecessor code follow that naming
convention.
Some examples:
getSingleSuccessor() => getSingleSuccessorBlock().
isSuccessor() => isSuccessorBlock().
getPreds() => getPredecessorBlocks().
Really, IMO, we should consider renaming SILSuccessor to a more verbose name so
that it is clear that it is more of an internal detail of SILBasicBlock's
implementation rather than something that one should consider as apart of one's
mental model of the IR when one really wants to be thinking about predecessor
and successor blocks. But that is not what this commit is trying to change, it
is just trying to eliminate a bit of technical debt by making the naming
conventions here consistent.
Before this commit all code relating to handling arguments in SILBasicBlock had
somewhere in the name BB. This is redundant given that the class's name is
already SILBasicBlock. This commit drops those names.
Some examples:
getBBArg() => getArgument()
BBArgList => ArgumentList
bbarg_begin() => args_begin()
This reverts commit 9508fdc8a7 from #5094. Reemitting
case bodies doesn't work if the body contains nested closures or
declarations, since SILGen expects these to only ever be visited once.
Keep in mind that these are approximations that will not impact correctness
since in all cases I ensured that the SIL will be the same after the
OwnershipModelEliminator has run. The cases that I was unsure of I commented
with SEMANTIC ARC TODO. Once we have the verifier any confusion that may have
occurred here will be dealt with.
rdar://28685236
Today, loads and stores are treated as having @unowned(unsafe) ownership
semantics. This leaves the user to specify ownership changes on the loaded or
stored value independently of the load/store by inserting ARC operations. With
the change to Semantic SIL, this will no longer be true. Instead loads, stores
have ownership semantics that one must reason about such as copy, take, and
trivial.
This change moves us closer to that world by eliminating the default
OwnershipQualification argument from create{Load,Store}. This means that the
compiler developer cannot ignore reasoning about the ownership semantics of the
memory operation that they are creating.
Operationally, this is a NFC change since I have just gone through the compiler
and updated all places where we create loads, stores to pass in the former
default argument ({Load,Store}OwnershipQualifier::Unqualified), to
SILBuilder::create{Load,Store}(...). For now, one can just do that in situations
where one needs to create loads/stores, but over time, I am going to tighten the
semantics up via the verifier.
rdar://28685236
Backed off of the implementation with a shared body block, which got
messy really fast with multiple patterns containing address-only values
to pass in, as it led to separated stack alloc/cleanup requirements and
passing stack alloc’d values as block args, aliasing of addresses for
stack cleanup verifying, etc. A mess.
This now does the conservative thing of repeating the body in each
matching pattern block.
Parser now accepts multiple patterns in switch cases that contain variables.
Every pattern must contain the same variable names, but can be in arbitrary
positions. New error for variable that doesn't exist in all patterns.
Sema now checks cases with multiple patterns that each occurence of a variable
name is bound to the same type. New error for unexpected types.
SILGen now shares basic blocks for switch cases that contain multiple
patterns. That BB takes incoming arguments from each applicable pattern match
emission with the specific var decls for the pattern that matched.
Added tests for all three of these, and some simple IDE completion
sanity tests.
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.
_BridgedNSError conformances can affect the runtime behavior of
dynamic casts (e.g. 'is'). Unfortunately, the conformance is not
always emitted, in an effort to save space when not used. This change
forces the conformance witness tables to be emitted when we can detect
a dynamic cast to an _BridgedNSError conforming enum.
Test cases included, as well as a note about a potentially erroneous
path that is not currently handled: when the dynamic cast occurs in a
generic function to a generic type (and thus we are unsure which
conformances we need to pull in).
As there are no instructions left which produce multiple result values, this is a NFC regarding the generated SIL and generated code.
Although this commit is large, most changes are straightforward adoptions to the changes in the ValueBase and SILValue classes.
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
And fix some bugs in the switch implementation I ran into on the way:
- Make getManagedSubobject(CopyOnSuccess) really produce a CopyOnSuccess ConsumableManagedValue;
- Avoid invalidating address-only enums when they can't be unconditionally taken by copying the enum before projecting it. Ideally there'd be a copy_enum_data_addr instruction to do this more efficiently.
Swift SVN r29817
I didn't add anything to the table, just made use of what was already there.
We have plenty of additional calls to getIdentifier that could probably benefit
from this kind of easy access as well.
This commit also removes FOUNDATION_MODULE_NAME and OBJC_MODULE_NAME from
Strings.h. Neither of these is likely to change in the future, and both
already have KnownIdentifiers equivalents in use.
No intended functionality change.
Swift SVN r29292
Failure paths need to maintain a consistent view of the cleanup state, so we can't just branch to a common exit point and fixup the cleanup state later. Fixes rdar://problem/21087371.
Swift SVN r29287
This simplifies the cleanup juggling we have to do, making it easier to get to the fix for rdar://problem/21087371. NFC yet (since emitting casts one at a time is equivalent to pretending we emit them simultaneously like we were).
Swift SVN r29277
checked_cast_br promises to maintain RC identity, but a cast from an ErrorType-conforming class to NSError may change the RC identity by bridging. Make sure that potential class-to-NSError casts go through the indirect cast entry points for now. The runtime implementation still needs to be fixed to handle the class-to-NSError case, but this is part of rdar://problem/21116814.
Swift SVN r29089
- Enable 'catch is NSError' and 'catch let e as NSError {' patterns to
a) work, and b) be considered to be exhaustive catches. This enables
people to catch an error and *use* it as an NSError directly, instead
of having to do boiler-platey cases. This is particularly important
for the migrator.
- Do not warn about non-noop coersion casts (like "_ as NSError" when
matching an ErrorType), since they provide useful type adjustment to
the subpattern. Still warn on noop ones.
- Simplify CatchStmt::isSyntacticallyExhaustive to use
Pattern::isRefutablePattern. Add a FIXME, because the parser is guiding
closure "throws" inference before the pattern is type checked, which means
that it is incorrect (but only in subtle cases).
- When diagnosing pointless 'as' patterns like:
switch 4 {
case _ as Int: break
say "'as' test is always true" instead of "'is' test is always true".
Swift SVN r28774