Motivation: `GenericSignatureImpl::getCanonicalSignature` crashes for
`GenericSignature` with underlying `nullptr`. This led to verbose workarounds
when computing `CanGenericSignature` from `GenericSignature`.
Solution: `GenericSignature::getCanonicalSignature` is a wrapper around
`GenericSignatureImpl::getCanonicalSignature` that returns the canonical
signature, or `nullptr` if the underlying pointer is `nullptr`.
Rewrite all verbose workarounds using `GenericSignature::getCanonicalSignature`.
This mostly requires changing various entry points to pass around a
TypeConverter instead of a SILModule. I've left behind entry points
that take a SILModule for a few methods like SILType::subst() to
avoid creating even more churn.
box descriptors
We want to substitute opaque result types in addTypeRef but when we pass
SILFunctionTypes this would fail because AST type substitution does not
support lowered SIL types.
Instead add addLoweredTypeRef which substitutes based on SILTypes.
rdar://54529445
In too many places, we were calling into `emitDynamicTypeOfOpaqueHeapObject` even when we had
more specific type information about the heap object we were querying. Replace all calls with
`emitDynamicTypeOfHeapObject`, which uses the best available access path and completely avoids
runtime calls for pure Swift classes and heap objects. When targeting non-ObjC-interop platforms,
we also know we never need to call `swift_getObjectType`, so avoid doing so altogether.
This indicates that the "self" argument to the current function is always dynamically of the exact
static base class type, allowing metadata accesses in IRGen to use the local self metadata to answer
metadata requests for the class type. Set this attribute on allocating entry points of designated
inits, which is one of the most common places where we emit redundant metadata accesses.
Don't use the beginning of the basic block as insertion point if 'local
self' is an llvm::Instruction (i.e a cast from the argument llvm::Value
has been insterted) rather use the 'local self' value as insertion point.
Fixes a dominance issue because we inserted at the beginning of the
basic block.
rdar://51186963
An @objc convenience initializer can replace 'self'. Since IRGen
has no way to tell what the new 'self' value is from looking at
SIL, it always refers back to the original 'self' argument when
recovering DynamicSelfType metadata. This could cause a crash
if the metadata was used after the 'self' value had been
replaced.
To fix the crash, always insert the metadata recovery into the
entry block, where the 'self' value should be valid (even if
uninitialized, the 'isa' pointer should be correct).
Fixes <rdar://problem/50594689>.
This simplifies some boilerplate, and in particular, some SIL verifier
logic; and fixes a couple bugs related to always loadable reference
storage types.
At Odebug we print the full path to the file and in optimized mode no
file name will be included.
This mirrors what we do in Swift's asserts.
rdar://47880964
This silences the instances of the warning from Visual Studio about not all
codepaths returning a value. This makes the output more readable and less
likely to lose useful warnings. NFC.
This does the same thing as taking the AST type and running it through mapTypeOutOfContext, but
saves call sites from having to do the unwrap-rewrap dance.
These functions don't accept local variable heap memory, although the names make it sound like they work on anything. When you try, they mistakenly identify such things as ObjC objects, call through to the equivalent objc_* function, and crash confusingly. This adds Object to the name of each one to make it more clear what they accept.
rdar://problem/37285743
This allows us to layout-optimize Optional<T> when T is a struct with an
extra-inhabitant-bearing field anywhere in its definition, not only at
the beginning. rdar://problem/43019427
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.
A Swift subclass of an ObjC class can be dynamically subclassed, but `type(of:)` shouldn't return the artificial subclass, since that's not what -class does for ObjC classes, and people expect `Bundle(for: type(of: c))` to work like `[NSBundle bundleForClass: [c class]]` would in ObjC. Fixes rdar://problem/37319860.
When we use type(of: x) on a class in an ObjC bridged context, the optimizer turns this into a SIL `value_metatype @objc` operation, which is supposed to get the dynamic type of the object as an ObjC class. This was previously lowered by IRGen into a `object_getClass` call, which extracts the isa pointer from the object, but is inconsistent with the `-class` method in ObjC or with the Swift-native behavior, which both look through artificial subclasses, proxies, and so on. This inconsistency led to observably different behavior between debug and release builds and between ObjC-bridged and native entry points, so provide an alternative runtime entry point that replicates the behavior of getting a native Swift class. Fixes SR-7258.
Most of the work of this patch is just propagating metadata states
throughout the system, especially local-type-data caching and
metadata-path resolution. It took a few design revisions to get both
DynamicMetadataRequest and MetadataResponse to a shape that felt
right and seemed to make everything easier.
The design is laid out pretty clearly (I hope) in the comments on
DynamicMetadataRequest and MetadataResponse, so I'm not going to
belabor it again here. Instead, I'll list out the work that's still
outstanding:
- I'm sure there are places we're asking for complete metadata where
we could be asking for something weaker.
- I need to actually test the runtime behavior to verify that it's
breaking the cycles it's supposed to, instead of just not regressing
anything else.
- I need to add something to the runtime to actually force all the
generic arguments of a generic type to be complete before reporting
completion. I think we can get away with this for now because all
existing types construct themselves completely on the first request,
but there might be a race condition there if another asks for the
type argument, gets an abstract metadata, and constructs a type with
it without ever needing it to be completed.
- Non-generic resilient types need to be switched over to an IRGen
pattern that supports initialization suspension.
- We should probably space out the MetadataStates so that there's some
space between Abstract and Complete.
- The runtime just calmly sits there, never making progress and
permanently blocking any waiting threads, if you actually form an
unresolvable metadata dependency cycle. It is possible to set up such
a thing in a way that Sema can't diagnose, and we should detect it at
runtime. I've set up some infrastructure so that it should be
straightforward to diagnose this, but I haven't actually implemented
the diagnostic yet.
- It's not clear to me that swift_checkMetadataState is really cheap
enough that it doesn't make sense to use a cache for type-fulfilled
metadata in associated type access functions. Fortunately this is not
ABI-affecting, so we can evaluate it anytime.
- Type layout really seems like a lot of code now that we sometimes
need to call swift_checkMetadataState for generic arguments. Maybe
we can have the runtime do this by marking low bits or something, so
that a TypeLayoutRef is actually either (1) a TypeLayout, (2) a known
layout-complete metadata, or (3) a metadata of unknown state. We could
do that later with a flag, but we'll need to at least future-proof by
allowing the runtime functions to return a MetadataDependency.
Abstract type/heap metadata access goes into MetadataRequest.
Metadata access starting from a heap object goes into GenHeap.
Accessing various components of class metadata goes into GenClass
or MetadataLayout.
Will be used to verify that withoutActuallyEscaping's block does not
escape the closure.
``%escaping = is_escaping_closure %closure`` tests the reference count. If the
closure is not uniquely referenced it prints out and error message and
returns true. Otherwise, it returns false. The returned result can be
used with a ``cond_fail %escaping`` instruction to abort the program.
rdar://35525730
This commit is mostly refactoring.
*) Introduce a new OptimizationMode enum and use that in SILOptions and IRGenOptions
*) Allow the optimization mode also be specified for specific SILFunctions. This is not used in this commit yet and thus still a NFC.
Also, fixes a minor bug: we didn’t run mandatory IRGen passes for functions with @_semantics("optimize.sil.never")
This is different from swift_deallocObject in that it applies to objects
at +1 while swift_deallocObject actually only applies to objects whose
state is deiniting (swift_release was called).