This removes an intricate set of invariants that must be kept consistent
between Parse and SILGen. It will also make it easier to implement local
variables with 'lazy' and property wrappers in the future.
Just as with conformances, we can detect that a delayed function
needs to be added to the queue from 'first principles' rather than
walking the ExternalDefinitions list.
This completely eliminates the ExternalDefinitions walk from SILGen,
which has several advantages:
- It fixes a source of quadratic behavior. In batch mode, type checking
produces a list of external definitions shared across all primary
files. Then, SILGen runs once per primary file, building a delayed
emission map every time.
- It allows SILGen to emit external definitions which only come into
existence as a result of lazy conformance checking. Previously,
anything that was added after SILGen performed its walk over the
external definitions list would not be emitted.
Instead of visiting all types in the ExternalDefinitions list and
queuing up their conformances, just emit conformances as needed
when they are first referenced.
ManagedValue::{forward,assign}Into both have the signature SILGenFunction &,
SILLocation, SILValue. For some reason copyInto has SILLocation and SILValue
swapped. This commit standardizes copyInto to match the others.
These can be recreated if needed in a client library. To do this, I've
added a new ConformanceLookupKind::NonInherited, which can also be
used elsewhere in the project where we're already filtering out
inherited conformances some other way.
Note that this doesn't drop inherited conformances from the entire
serialized interface, just from the list that a class explicitly
declares. They still get referenced sometimes.
rdar://problem/50541451 and possibly others
This is a large patch; I couldn't split it up further while still
keeping things working. There are four things being changed at
once here:
- Places that call SILType::isAddressOnly()/isLoadable() now call
the SILFunction overload and not the SILModule one.
- SILFunction's overloads of getTypeLowering() and getLoweredType()
now pass the function's resilience expansion down, instead of
hardcoding ResilienceExpansion::Minimal.
- Various other places with '// FIXME: Expansion' now use a better
resilience expansion.
- A few tests were updated to reflect SILGen's improved code
generation, and some new tests are added to cover more code paths
that previously were uncovered and only manifested themselves as
standard library build failures while I was working on this change.
Currently Sema completes all _ObjectiveCBridgeable conformances it thinks
are needed in SILGen and runtime dynamic casts, but that's about to change.
When emitting conformances for an imported type we would skip incomplete
conformances. Now that we have a long-lived type checker instance, there
is no longer any reason to do that. Looking up witnesses from an
incomplete conformance will trigger conformance checking as needed.
Furthermore, conformances emitted in this path are emitted lazily, so if
a conformance is not used, no conformance checking will take place.
A change in behavior only occurs after subsequent changes to remove Sema's
eager checking of ClangImporter-synthesized _ObjectiveCBridgeable
conformances; at that point, we must be prepared to lazily emit these
incomplete conformances.
The initializer associated with a lazy property should not be executed
directly, because it is subsumed by code synthesized into the
getter. Generalize the terminology here so we can re-use this path for
property delegate initialization.
To represent the abstracted interface of an opaque type, we need a generic signature that refines
the outer context generic signature with an additional generic parameter representing the underlying
type and its exposed constraints. Opaque types also need to be keyed by their originating decl, so
that we can treat values of the same opaque type as the same. When we check a FuncDecl with an
opaque type specified as its return type, create an OpaqueTypeDecl and associate it with the
originating decl. (A representation for *types* derived from the opaque decl will come next.)
Sorting of DeclContext-local protocols and conformances shouldn't ever
be necessary, because the underlying data structures that produce
these lists should be deterministic. Sorting can hide any
non-determinism, so stop doing it and we can address the underlying
nondeterminism.
Removes the _getBuiltinLogicValue intrinsic in favor of an open-coded
struct_extract in SIL. This removes Sema's last non-literal use of builtin
integer types and unblocks a bunch of cleanup.
This patch would be NFC, but it improves line information for conditional expression codegen.
When an on-demand accessor is synthesized while checking a conformance,
make sure it ends up in the 'external declarations' list so that SILGen
can emit it.
Fixes <rdar://problem/46503121>, and part of <rdar://problem/46186045>.
The problem here is that we were taking advantage of swift not-trashing the
original memory location after performing a load [take] to use load [take] as a
+0 load. This breaks the ownership verifier since the load [take] is never
actually destroyed. Instead this commit changes this code to use a load_borrow.
I found this when trying to enable ownership verification on
test/SILGen/indirect_enum.swift using some out of tree work that should have
fixed all of the ownership issues with SILGenPattern. Turns out I can just
enable ownership verification with just this change... so I did that as well in
this PR.
rdar://29791263
Delay allocating the result buffer for an opened Self return until right before it's needed. When a mutating method is invoked on an existential, the Self type won't be opened until late, when the formal access to the mutable value begins. Fixes rdar://problem/43507711.
The storage kind has been replaced with three separate "impl kinds",
one for each of the basic access kinds (read, write, and read/write).
This makes it far easier to mix-and-match implementations of different
accessors, as well as subtleties like implementing both a setter
and an independent read/write operation.
AccessStrategy has become a bit more explicit about how exactly the
access should be implemented. For example, the accessor-based kinds
now carry the exact accessor intended to be used. Also, I've shifted
responsibilities slightly between AccessStrategy and AccessSemantics
so that AccessSemantics::Ordinary can be used except in the sorts of
semantic-bypasses that accessor synthesis wants. This requires
knowing the correct DC of the access when computing the access strategy;
the upshot is that SILGenFunction now needs a DC.
Accessor synthesis has been reworked so that only the declarations are
built immediately; body synthesis can be safely delayed out of the main
decl-checking path. This caused a large number of ramifications,
especially for lazy properties, and greatly inflated the size of this
patch. That is... really regrettable. The impetus for changing this
was necessity: I needed to rework accessor synthesis to end its reliance
on distinctions like Stored vs. StoredWithTrivialAccessors, and those
fixes were exposing serious re-entrancy problems, and fixing that... well.
Breaking the fixes apart at this point would be a serious endeavor.
LLVM r334399 (and related Clang changes) moved clang::VersionTuple to
llvm::VersionTuple. Update Swift to match.
Patch by Jason Molenda.
rdar://problem/41025046
Replace two prominent uses of SubstitutionList, in ConcreteDeclRef and
Witness, with SubstitutionMap. Deal with the myriad places where we
now have substitution maps and need substitution lists (or vice versa)
caused by this change.
Overall, removes ~50 explicit uses of SubstitutionList (of ~400).
closure lifetimes.
SILGen will now unconditionally emit
%cvt = convert_escape_to_noescape [guaranteed] %op
instructions. The mandatory ClosureLifetimeFixup pass ensures that %op's
lifetime spans %cvt's uses.
The code in DefiniteInitialization that handled a subset of cases is
removed.
This patch both makes debug variable information it optional on
alloc_stack and alloc_box instructions, and forced variable
information on debug_value and debug_value_addr instructions. The
change of the interface uncovered a plethora of bugs in SILGen,
SILTransform, and IRGen's LoadableByAddress pass.
Most importantly this fixes the previously commented part of the
DebugInfo/local-vars.swift.gyb testcase.
rdar://problem/37720555
Previously SwitchEnumBuilder was in SILGenBuilder.{h,cpp} and
SwitchEnumCaseFullExpr was in its own file. This really made no sense since:
1. The two classes are inherently related to each other so really should be
together in the source base.
2. SwitchEnumBuilder uses a SILGenBuilder, but is really a separate independent
concept/entity, so there really is no reason to keep it in SILGenBuilder.cpp.
Just a quick fix to eliminate something that was bugging me.
NFC.
These accesses can't be recognized as obviously local temporaries in the
verification pass, so the only way to exhaustively verify exclusivity is by
added unenforced markers.
SILGen currently only emits unenforced markers under -verify-exlcusivity. Once
opaque values is the only supported SILGen mode, then we should turn the markers
on by default (SILGen should not have different modes of operation).
- Emit a withoutActuallyEscapingClosure partial apply
This is to convert an @noescape closure to an escaping closure.
This needs to be done in preparation of @noescape closure contexts
becoming trivial.
- Insert escaping to noescape conversions
- Fix SILGen for @noescape
- Postpone closure cleanups to outside the argument scope
- Apply postponement recursively for closures passed to subscripts
- Only skip applying escapeness conversions for Swift thick functions
- Fix parameter convention for noescape closures in thunks
Part of:
SR-5441
rdar://36116691
* Implement #warning and #error
* Fix #warning/#error in switch statements
* Fix AST printing for #warning/#error
* Add to test case
* Add extra handling to ParseDeclPoundDiagnostic
* fix dumping
* Consume the right paren even in the failure case
* Diagnose extra tokens on the same line after a diagnostic directive
This has three principal advantages:
- It gives some additional type-safety when working
with known accessors.
- It makes it significantly easier to test whether a declaration
is an accessor and encourages the use of a common idiom.
- It saves a small amount of memory in both FuncDecl and its
serialized form.
Specifically, load profiler counts corresponding to 'if' AST nodes and
attach them to the corresponding CondBranchInst's in SIL.
This is done using dirty tricks and isn't tested well enough :(.
- Hack the SIL printer to make profile count loading testable.
- Hack the profiler's counter map to store the indices of parent
region counters in entries for 'else stmts' and 'else exprs'.
It's too early to hack up the SILOptimizer to propagate profile counts.
It doesn't seem too hard, but I definitely don't know the code well
enough to write tests for it :(. So that's still a TODO.
Next, we should be able to produce some acutual llvm branch_weight
metadata!
introduce a common superclass, SILNode.
This is in preparation for allowing instructions to have multiple
results. It is also a somewhat more elegant representation for
instructions that have zero results. Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction. Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.
A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.
Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.