We were not using the primary benefits of an intrusive list, namely the
ability to insert or remove from the middle of the list, so let's switch
to a plain vector. This also avoids linked-list pointer chasing.
The differentiation transform does the following:
- Canonicalizes differentiability witnesses by filling in missing derivative
function entries.
- Canonicalizes `differentiable_function` instructions by filling in missing
derivative function operands.
- If necessary, performs automatic differentiation: generating derivative
functions for original functions.
- When encountering non-differentiability code, produces a diagnostic and
errors out.
Partially resolves TF-1211: add the main canonicalization loop.
To incrementally stage changes, derivative functions are currently created
with empty bodies that fatal error with a nice message.
Derivative emitters will be upstreamed separately.
Add ExecuteSILPipelineRequest which executes a
pipeline plan on a given SIL (and possibly IRGen)
module. This serves as a top-level request for
the SILOptimizer that we'll be able to hang
dependencies off.
... including all SIL functions with are transitively referenced from such witness tables.
After the last devirtualizer run witness tables are not needed in the optimizer anymore.
We can delete witness tables with an available-externally linkage. IRGen does not emit such witness tables anyway.
This can save a little bit of compile time, because it reduces the amount of SIL at the end of the optimizer pipeline.
It also reduces the size of the SIL output after the optimizer, which makes debugging the SIL output easier.
This is needed for cross-module-optimization: CMO marks functions as inlinable. If a private or internal method is referenced from such an inlinable function, it must not be eliminated by dead function elimination after serialization (a method is basically an AbstractFunctionDecl).
For SILFunctions we can do this by simply setting the linkage, but for methods we need another mechanism.
The XXOptUtils.h convention is already established and parallels
the SIL/XXUtils convention.
New:
- InstOptUtils.h
- CFGOptUtils.h
- BasicBlockOptUtils.h
- ValueLifetime.h
Removed:
- Local.h
- Two conflicting CFG.h files
This reorganization is helpful before I introduce more
utilities for block cloning similar to SinkAddressProjections.
Move the control flow utilies out of Local.h, which was an
unreadable, unprincipled mess. Rename it to InstOptUtils.h, and
confine it to small APIs for working with individual instructions.
These are the optimizer's additions to /SIL/InstUtils.h.
Rename CFG.h to CFGOptUtils.h and remove the one in /Analysis. Now
there is only SIL/CFG.h, resolving the naming conflict within the
swift project (this has always been a problem for source tools). Limit
this header to low-level APIs for working with branches and CFG edges.
Add BasicBlockOptUtils.h for block level transforms (it makes me sad
that I can't use BBOptUtils.h, but SIL already has
BasicBlockUtils.h). These are larger APIs for cloning or removing
whole blocks.
We used to look at the vtable entry's linkage to determine if the
vtable entry was dead, in case the vtable entry linkage was more
visible than the method being overridden.
This hack is no longer needed now that a method override more
visible than its base introduces a new vtable entry.
With the advent of dynamic_function_ref the actual callee of such a ref
my vary. Optimizations should not assume to know the content of a
function referenced by dynamic_function_ref. Introduce
getReferencedFunctionOrNull which will return null for such function
refs. And getInitialReferencedFunction to return the referenced
function.
Use as appropriate.
rdar://50959798
This normalizes the creation of pass pipelines by ensuring that all pass
pipelines take a SILOption instead of only some. It also makes it so that we do
not need to propagate options through various pipeline creation helpers.
SILWitnessTable::Entry already contains a superset of what was supported
by SILDefaultWitnessTable::Entry, the latter of which only had “no entry”
and “method” states. Make SILDefaultWitnessTable::Entry an alias for
SILWitnessTable::Entry, and unify all of the parsing/printing/
(de)serialization logic.
SIL will not generate calls to protocol requirements that override
other protocol requirements, so all of the witness table entries for
the overriding arguments are dynamically dead. Remove them from the
witness tables entirely.
Implements rdar://problem/43870489, reducing the size of the standard
library binary by 196k.
ClassDecl::getSuperclass() produces a complete interface type describing the
superclass of a class, including any generic arguments (for a generic type).
Most callers only need the referenced ClassDecl, which is (now) cheaper
to compute: switch those callers over to ClassDecl::getSuperclassDecl().
Fixes an existing test for SR-5993.
The other side of #17404. Since we don't want to generate up front key path metadata for properties/subscripts with no withheld implementation details, the client should generate a key path component that can be used to represent a key path component based on its public interface.
* SILModule::isVisibleExternally utility for VarDecls.
* Fix the SIL parser so it doesn't drop global variable decls.
This information was getting lost in SIL printing/parsing.
Some passes rely on it. Regardless of whether passes should rely on it,
it is totally unacceptable for the SIL passes to have subtle differences
in behavior depending on the frontend mode. So, if we don't want passes
to rely on global variable decls, that needs to be enforced by the API
independent of how the frontend is invoked or how SIL is serialized.
* Use custom DemangleOptions to lookup global variable identifiers.
Client code can make a best effort at emitting a key path referencing a property with its publicly exposed API, which in the common case will match what the defining module would produce as the canonical key path component representation of the declaration. We can reduce the code size impact of these descriptors by not emitting them when there's no hidden or possibly-resiliently-changed-in-the-past information about a storage declaration, having the property descriptor symbol reference a sentinel value telling client key paths to use their definition of the key path component.
This will allow key paths to resiliently reference public properties from other binaries by referencing a descriptor vended by the originating binary. NFC yet, this just provides printing/parsing/verification of the new component.
@_silgen_name and @_cdecl functions are assumed to be referenced from
C code. Public and internal functions marked as such must not be deleted
by the optimizer, and their C symbols must be public or hidden respectively.
rdar://33924873, SR-6209
Transparent functions are emitted into the client in most cases, so there is no need to keep them alive in the defining module unless they are used there.
The only exception are transparent global initializers, because bodies of global initializer functions are never SIL serialized and are always IRGened into the defining module, so that clients can invoke them
This change results in small code size reductions of the binaries being produced after recent changes related to the early SIL serialization and the removal of -sil-serialize-all mode.
Fixes rdar://problem/35022861
These show up specifically when someone forms a keypath to an ObjC
property in a category. They're no-ops from the perspective of
DFE but the code has to intentionally skip the case if it wants to
avoid the subsequent llvm_unreachable.
rdar://34913689
Recent changes that eliminated the -sil-serialize-all mode and adding this check to IRGen allow us to get rid of ExternalFunctionDefinitionsElimination and ExternalDefsToDecls passes, which are not needed anymore.
Pre-specializations need some special handling when it comes to the Serialized attribute. Their bodies should not be SIL serialized. Instead, only their declarations should be serialized.
And since their bodies are not serialized and cannot be imported by the client code, it is OK if pre-specializations reference non-fragile functions inside their bodies. Due to the same reason, it is fine if pre-specializations are referenced from fragile functions, even though these pre-specializations are not fragile in a usual sense.
"Accessibility" has a different meaning for app developers, so we've
already deliberately excised it from our diagnostics in favor of terms
like "access control" and "access level". Do the same in the compiler
now that we aren't constantly pulling things into the release branch.
Rename AccessibilityAttr to AccessControlAttr and
SetterAccessibilityAttr to SetterAccessAttr, then track down the last
few uses of "accessibility" that don't have to do with
NSAccessibility. (I left the SourceKit XPC API alone because that's
supposed to be more stable.)
"Accessibility" has a different meaning for app developers, so we've
already deliberately excised it from our diagnostics in favor of terms
like "access control" and "access level". Do the same in the compiler
now that we aren't constantly pulling things into the release branch.
This commit changes the 'Accessibility' enum to be named 'AccessLevel'.
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.