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.
Static initializers are now represented by a list of literal and aggregate instructions in a SILGlobalVariable.
For details see SIL.rst.
This representation is cleaner than what we did so far (point to the initializer function and do some pattern matching).
One implication of that change is that now (a subset of) instructions not necessarily have a parent function.
Regarding the generated code it's a NFC.
Also the swift module format didn't change because so far we don't serializer global variables.
This removes the function body, but preserves the SILFunction object, which may be still referenced by different kinds of meta-information e.g. debug info for inlined functions, generic specializations information, etc.
Doing this unconditionally simplifies the code and makes it less error-prone to reference SILFunctions from any kind of meta-information. It just works. No need to set any special flags, etc.
This marker can be used e.g. when a function is referenced from the generic specialization information (or any other kind of metadata) to indicate that this SIL function should not be completely eliminated by the dead function elimination pass even if it is not referenced by any function_ref instruction anymore. Such a function will be preserved in a zombie list instead if it needs to be eliminated.
- SILSerializeAll flag is now stored in the SILOptions and passed around as part of it
- Explicit SILSerializeAll/wholeModuleSerialized/makeModuleFragile API parameters are removed in many places
AccessMarkerElimination now registers a callback so that any subsequently
deserialized function bodies will have access markers stripped for optimization.
rdar:31908496 Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of
incompatible type!") in SILPerformanceInliner
Previously we would drop all serialized SIL from partial swiftmodule
files generated while compiling source in non-WMO mode; all that was
missing was linking it in.
This adds a frontend flag, and a test; driver change is coming up
next.
Progress on <rdar://problem/18913977>.
This fixes a crash when referencing partially-applied methods
from @_inlineable functions.
Also, curry thunks for private methods do not need shared
linkage; private is sufficient.
Also, add a third [serializable] state for functions whose bodies we
*can* serialize, but only do so if they're referenced from another
serialized function.
This will be used for bodies synthesized for imported definitions,
such as init(rawValue:), etc, and various thunks, but for now this
change is NFC.
We didn’t do that if an optimization looked up a witness table.
Fixes rdar://problem/30544344
I couldn’t come up with an isolated test case, but this should be covered with our existing tests.
(The problem shows up when inlining of generics are enabled)
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.
This reverts commit a380855524, reversing
changes made to 66332140f3.
We're seeing a handful of issues from turning on inlining of generics,
so I'm reverting to unblock the bots.
In all cases the DeclCtx field was supposed to be initialized from the
SILLocation of the function, so we can save one pointer per
SILFunction.
There is one test case change where a different (more precise)
diagnostic is being generated after this change.
A witness table is dead if it is not used outside the module (private/internal) and it’s not used by any instruction or other witness table in the module.
Also the meta-type of the conforming type must not escape, because it’s possible to test any opaque type if it conforms to a protocol.
rdar://problem/23026019
The introduction of `llvm.memcpy.element.atomic` would cause an
ambiguity when we did the lookup with the trailing `.` for the type
parameters. The intrinsic itself is not necessarily suffixed with the
type in the identifier. Look up the identifier by explicit name.
The typedef `swift::Module` was a temporary solution that allowed
`swift::Module` to be renamed to `swift::ModuleDecl` without requiring
every single callsite to be modified.
Modify all the callsites, and get rid of the typedef.
Those builtins are: allocWithTailElems_<n>, getTailAddr and projectTailElems
Also rename the "gep" builtin, which indexes raw bytes, to "gepRaw" and add a new "gep" builtin to index in a typed array.
Those builtins are: allocWithTailElems_<n>, getTailAddr and projectTailElems
Also rename the "gep" builtin, which indexes raw bytes, to "gepRaw" and add a new "gep" builtin to index in a typed array.
When devirtualizing witness method and class method calls, we
transform apply instructions operating on the result of a SIL
witness_method or class_method instruction to direct calls of
a function_ref.
The generic signature of the dynamic call site might not match
the generic signature of the static thunk, so the substitution
list from the dynamic apply instruction cannot be used directly;
instead, we must transform it to a substitution list suitable
for the static thunk.
- With witness methods, the method is called using the protocol
requirement's signature, <Self : P, ...>, however the
witness thunk has a generic signature derived from the
concrete witness.
For example, the requirement might have a signature
<Self : P, T>, where the concrete witness thunk might
have a signature <X, Y>, where the concrete conforming type
is G<X, Y>.
At the call site, we substitute Self := G<X', Y'>; however
to be able to call the witness thunk directly, we need to
form substitutions X := X' and Y := Y'.
- A similar situation occurs with class methods when the
dynamically-dispatched call is performed against a derived
class, but devirtualization actually finds the method on a
base class of the derived class.
The base class may have a different number of generic
parameters than the derived class, either because the
derived class makes some generic parameters of the base
class concrete, or if the derived class introduces new
generic parameters of its own.
In both cases, we need to consider the generic signature of the
dynamic call site (the protocol requirement or the derived
class method) as well as the generic signature of the static
thunk, and carefully remap the substitutions from one form
into another.
Previously the optimizer would implicitly rely on substitutions
being in AllArchetypes order, in particular that concatenating
outer substitutions with inner substitutions makes sense.
This assumption is about to go away, so this patch refactors
the optimizer to use some new abstractions for remapping
substitution lists.
This patch is rather large, since it was hard to make this change
incrementally, but most of the changes are mechanical.
Now that we have a lighter-weight data structure in the AST for mapping
interface types to archetypes and vice versa, use that in SIL instead of
a GenericParamList.
This means that when serializing a SILFunction body, we no longer need to
serialize references to archetypes from other modules.
Several methods used for forming substitutions can now be moved from
GenericParamList to GenericEnvironment.
Also, GenericParamList::cloneWithOuterParameters() and
GenericParamList::getEmpty() can now go away, since they were only used
when SILGen-ing witness thunks.
Finally, when printing generic parameters with identical names, the
SIL printer used to number them from highest depth to lowest, by
walking generic parameter lists starting with the innermost one.
Now, ambiguous generic parameters are numbered from lowest depth
to highest, by walking the generic signature, which means test
output in one of the SILGen tests has changed.
One minor revision: this lifts the proposed restriction against
overriding a non-open method with an open one. On reflection,
that was inconsistent with the existing rule permitting non-public
methods to be overridden with public ones. The restriction on
subclassing a non-open class with an open class remains, and is
in fact consistent with the existing access rule.
Previously it assumed that if we succeed in looking up the method in the current
module we must be able to request a definition (vs a declaration).
This is not true. It could be that we had declared the type in a different
module. Always ask for a declaration.
rdar://27547957
If the function we're looking for already exists, it's OK for the definition to have the symbol's for-definition linkage, even if we're only looking for a declaration.
'fileprivate' is considered a broader level of access than 'private',
but for now both of them are still available to the entire file. This
is intended as a migration aid.
One interesting fallout of the "access scope" model described in
758cf64 is that something declared 'private' at file scope is actually
treated as 'fileprivate' for diagnostic purposes. This is something
we can fix later, once the full model is in place. (It's not really
/wrong/ in that they have identical behavior, but diagnostics still
shouldn't refer to a type explicitly declared 'private' as
'fileprivate'.)
As a note, ValueDecl::getEffectiveAccess will always return 'FilePrivate'
rather than 'Private'; for purposes of optimization and code generation,
we should never try to distinguish these two cases.
This should have essentially no effect on code that's /not/ using
'fileprivate' other than altered diagnostics.
Progress on SE-0025 ('fileprivate' and 'private')
This made call sites confusing to read because it doesn't actually
check if the function already exists.
Also fix some minor formatting issues. This came up while I was working
on a fix for a bug that turned out to not be a bug.
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.