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().
SubstitutionMaps are now just a trivial pointer-sized value, so
pass them by value instead.
I did have to move a couple of functors from Type.h to SubstitutionMap.h
to resolve some issues with forward declarations.
LinkNormal mode is used by the mandatory pipeline. It only needs
to deserialize what is necessary for code generation, that is
functions with shared linkage that must be emitted into the client.
PublicNonABI function declarations deserialize as HiddenExternal,
then become SharedExternal after the body has been deserialized.
So try deserializing HiddenExternal too.
NFC until mandatory inlining is no longer eagerly deserializing.
Instead of threading a boolean through the whole visitor, just
set an instance variable when we do deserialize something.
Note that previously, processFunction() almost always returned
true. As a result, the SILLinker pass would call invalidateAnalysis()
for every function with a body. Fixing this changed optimizer
output in one test; this warrants further investigation.
PublicNonABI function declarations deserialize as HiddenExternal,
then become SharedExternal after the body has been deserialized.
So try deserializing HiddenExternal too.
NFC until mandatory inlining is no longer eagerly deserializing.
The second worklist was immediately drained after visiting each
SIL instruction, so it didn't really avoid any recursion.
Simplify the control flow by immediately deserializing the
function and then adding it to the primary worklist.
This was completely dead code. Note that it was adding vtable
entries to the wrong worklist -- any functions on 'Worklist'
are not deserialized, only the functions *they reference* are
deserialized. So adding an external declaration to 'Worklist'
accomplishes nothing.
Mandatory inlining performs devirtualization, which is able
to deserialize vtables on its own. And since class methods
cannot be @_transparent, we don't have to deserialize any
vtable entries unless we're in LinkAll mode, which indicates
we're running the performance pipeline.
Code may end up indirectly using a witness table for a Clang-imported type by inlining code that used the conformance from another module, in which case we need to ensure we have a local definition at hand in the inlining module so we can have something to link against independently. This needs to be fixed from both sides:
- During serialization, serialize not only witness tables from the current module, but from Clang-imported modules too
- During deserialization, when the SILLinker walks a loaded module, ensure that all shared conformances get deserialized, including those from ApplyInsts and inherited/associated type protocol requirements.
Fixes rdar://problem/38687726.
Code may end up indirectly using a witness table for a Clang-imported type by inlining code that used the conformance from another module, in which case we need to ensure we have a local definition at hand in the inlining module so we can have something to link against independently. This needs to be fixed from both sides:
- During serialization, serialize not only witness tables from the current module, but from Clang-imported modules too, so that their definitions can be used by other modules that inline code from the current module
- During IRGen, when we emit a reference to a SILWitnessTable or SILFunction declaration with shared linkage, attempt to deserialize the definition on demand
Fixes rdar://problem/38687726.
This generalizes a hack where re-abstraction thunks become fragile on contact
with fragile functions.
The old policy was:
- [fragile] functions always serialized
- [reabstraction_thunk] transitively referenced from fragile always serialized
The new policy is:
- [serialized] functions always serialized
- [serializable] functions transitively referenced from serialized functions
are always serialized
- Most kinds of thunks can now be [serializable], allowing them to be shared
between serialized and non-serialized code without any issues, as long as the
body of the thunk is sufficiently "simple" (doesn't reference private
symbols or performs direct access to resilient types)
This reverts commit 1b3d29a163, reversing
changes made to b32424953e.
We're seeing a handful of issues from turning on inlining of generics,
so I'm reverting to unblock the bots.
For this we need to store the linkage of the “original” method implementation in the vtable.
Otherwise DeadFunctionElimination thinks that the method implementation is not public but private (which is the linkage of the thunk).
The big part of this change is to extend SILVTable to store the linkage (+ serialization, printing, etc.).
fixes rdar://problem/29841635
It it now possible to check if a function with a given name and a given linkage exists in one of the modules,
even if the current module contains a function with this name but a difference linkage.
This is useful e.g. for performing a lookup of pre-specializations.