Note that SILModule::lookUpWitnessTable() only attempts to deserialize
the witness table if we already have a declaration. In the
SILLinkerVisitor, we would call lookUpWitnessTable(), see if it returned
null, create a declaration, and if deserializeLazily is true, we would
call lookUpWitnessTable() again; this time, there was a declaration, and
we would deserialize the witness table.
However, if there was already a witness table declaration when we first
called lookUpWitnessTable(), we would trigger deserialization, even if
deserializeLazily is false.
Change the first call to pass false.
I had to update a couple of tests; I believe they were already somewhat
nonsensical.
All callers were doing the same thing here, so move it inside the
function. Also, change getRootNormalConformance(), which is deprecated,
to getRootConformance().
This is the first in a sequence of patches that implement various optimizations
to transform load [copy] into load_borrow.
The optimization works by looking for a load [copy] that:
1. Only has destroy_value as consuming users. This implies that we do not need
to pass off the in memory value at +1 and that we can use a +0 value.
2. Is loading from a memory location that is never written to or only written to
after all uses of the load [copy].
and then RAUW the load [copy] with a load_borrow and convertes the destroy_value
to end_borrow.
NOTE: I also a .def file for AccessedStorage so we can do visitors over the
kinds. The reason I want to do this is to ensure that people update these
optimizations if we add new storage kinds.
Adds memory objects and addresses to the constant interpreter, and
teaches the constant interpreter to interpret various instructions that
deal with memory and addresses.
Previously the cast optimizer bailed out on any conformance with
requirements.
We can now constant-propagate this:
```
protocol P {}
struct S<E> {
var e: E
}
extension S : P where E == Int {}
func specializeMe<T>(_ t: T) {
if let p = t as? P {
// do fast things.
}
}
specializeMe(S(e: 0))
```
This turns out to be as simple as calling the TypeChecker.
<rdar://problem/46375150> Inlining does not seem to handle
specialization properly for Data.
This enabled two SIL transformations required to optimize
the code above:
(1) The witness method call can be devirtualized.
(2) The allows expensive dynamic runtime checks such as:
unconditional_checked_cast_addr Array<UInt8> in %array : $*Array<UInt8> to ContiguousBytes in %protocol : $*ContiguousBytes
Will be converted into:
%value = init_existential_addr %existential : $*ContiguousBytes, $Array<UInt8>
store %array to %value : $*Array<UInt8>
In a previous commit, I banned in the verifier any SILValue from producing
ValueOwnershipKind::Any in preparation for this.
This change arises out of discussions in between John, Andy, and I around
ValueOwnershipKind::Trivial. The specific realization was that this ownership
kind was an unnecessary conflation of the a type system idea (triviality) with
an ownership idea (@any, an ownership kind that is compatible with any other
ownership kind at value merge points and can only create). This caused the
ownership model to have to contort to handle the non-payloaded or trivial cases
of non-trivial enums. This is unnecessary if we just eliminate the any case and
in the verifier separately verify that trivial => @any (notice that we do not
verify that @any => trivial).
NOTE: This is technically an NFC intended change since I am just replacing
Trivial with Any. That is why if you look at the tests you will see that I
actually did not need to update anything except removing some @trivial ownership
since @any ownership is represented without writing @any in the parsed sil.
rdar://46294760
We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.
Patch produced by
for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
* Remove apparently obsolete builtin functions.
- Remove s_to_u_checked_conversion and u_to_s_checked_conversion functions from builtin AST parsing, SIL/IR generation and from SIL optimisations.
* Remove apparently obsolete builtin functions - unit tests.
- Remove unit tests for SIL transformations relating to s_to_u_checked_conversion and u_to_s_checked_conversion builtin functions.
When the Clang importer imports the components of a C function pointer
type, it generally translates foreign types into their native equivalents,
just for the convenience of Swift code working with those functions.
However, this translation must be unambiguously reversible, so (among
other things) it cannot do this when the native type is also a valid
foreign type. Specifically, this means that the Clang importer cannot
import ObjCBool as Swift.Bool in these positions because Swift.Bool
corresponds directly to the C type _Bool.
SIL type lowering manually reverses the type-import process using
a combination of duplicated logic and an abstraction pattern which
includes information about the original Clang type that was imported.
This abstraction pattern is generally able to tell SIL type lowering
exactly what type to reverse to. However, @convention(c) function
types may appear in positions from which it is impossible to recover
the original Clang function type; therefore the reversal must be
faithful to the proper rules. To do this we must propagate
bridgeability just as the imported would.
This reversal system is absolutely crazy, and we should really just
- record an unbridged function type for imported declarations and
- record an unbridged function type and Clang function type for
@convention (c) function types whenever we create them.
But for now, it's what we've got.
rdar://43656704
This is in preparation for verifying that when ownership verification is enabled
that only enums and trivial values can have any ownership. I am doing this in
preparation for eliminating ValueOwnershipKind::Trivial.
rdar://46294760
We already assume in the given static method that the module is a non-null
pointer. So rather than us indirecting a ref to a pointer and then dereferencing
the pointer, we instead use the ref in the module implementation and dereference
the pointer.
rdar://46294760
Adds a stat to SILInstruction's transferNodesFromList to record the
number of times an instruction is transfered to another block. This is
the only way I can think of to detect quadratic behavior of passes
that split basic blocks.
Implements a constant interpreter that can deal with basic integer operations.
Summary of the features that it includes:
* builtin integer values, and builtin integer insts
* struct and tuple values, and insts that construct and extract them (necessary to use stdlib integers)
* function referencing and application (necessary to call stdlib integer functions)
* error handling data structures and logic, for telling you why your value is not evaluatable
* metatype values (not necessary for integers, but it's only a few extra lines, so I thought it would be more trouble than it's worth to put them in a separate PR)
* conditional branches (ditto)
We want removing a property override to be a resilient change, so
keypaths should not reference them, preferring to reference the
base declaration instead.
- Existentials may eventually be able to conform to protocols
- Functions may grow new arms we haven't designed and implemented yet,
which could influence how they cast in the future.
rdar://problem/38684452
The SIL verifier was asserting while attempting to prove that all
formal accesses are well-formed. This is necessary because
unrecognized access could lead to invalid whole-module optimization.
We would like to eliminate address-phis from SIL, but there are still
optimizer passes that produce them. For now, the best we can do is
hope to recover the original base of each phi value and prove they are
actually the same value. They should be because the optimizer
produced the phi through block cloning.
Fixes <rdar://problem/46114512> SIL verification failed: Unknown
formal access pattern: storage