This handles the case where the left hand side of the cast is known
to be class-like, and the right hand side is known at compile time
to be a protocol composition type.
Note that this change results in a small optimization -- a checked
cast of a metatype known to be a class metatype to a class-constrained
existential metatype no longer has to emit an explicit check that
the source is class-constrained.
Fully dynamic casts are coming up next.
Replace a few usages of TypeBase::getExistentialTypeProtocols(),
which I'm going to remove.
NFC for now, since subclass existentials are still not fully
plumbed through here.
Allow it only to have one context parameter, whose ownership convention matches the convention of the resulting thick function, effectively limiting it to binding a closure invocation function to its context.
We're now correctly checking for inheritance, adding @objc methods,
and adding @objc protocols for both CF types and objc_runtime_visible
classes (those without visible symbols). The latter is used for some
of the types in Dispatch, which has exposed some of the classes that
were considered implementation details on past OSs.
We still don't properly implement using 'as?' to check conformance to
a Swift protocol for a CF or objc_runtime_visible type, but we can do
that later.
rdar://problem/26850367
initialization in-place on demand. Initialize parent metadata
references correctly on struct and enum metadata.
Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.
Includes a fix since the earlier commit to make enum metadata
writable if they have an unfilled payload size. This didn't show
up on Darwin because "constant" is currently unenforced there in
global data containing relocations.
This patch requires an associated LLDB change which is being
submitted in parallel.
initialization in-place on demand. Initialize parent metadata
references correctly on struct and enum metadata.
Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.
Each runtime function definition in RuntimeFunctions.def states which calling convention
should be used for this runtime function. But IRGen and LLVMPasses were not always
properly propagating this declared calling convention all the way down to llvm's Call instructions.
In many cases, the standard C convention was set for the call irrespective of the actual calling
convention defined for a given runtime function. As a result, incorrect code was generated.
This commit tries to fix all those places, where such a mismatch was found. In many cases this is
achieved by defining a helper function CreateCall in such a way that makes sure that the call instruction
gets the same calling convention as the one used by its callee operand.
Instead of categorically forbidding caching within a conditional
scope, permit it but remember how to remove the cache entries.
This means that ad-hoc emission code can now get exactly the
right caching behavior if they use this properly. In keeping
with that, adjust a bunch of code to properly nest scopes
according to the conditional paths they enter.
There are several interesting new features here.
The first is that, when emitting a SILFunction, we're now able to
cache type data according to the full dominance structure of the
original function. For example, if we ask for type metadata, and
we've already computed it in a dominating position, we're now able
to re-use that value; previously, we were limited to only doing this
if the value was from the entry block or the LLVM basic block
matched exactly. Since this tracks the SIL dominance relationship,
things in IRGen which add their own control flow must be careful
to suppress caching within blocks that may not dominate the
fallthrough; this mechanism is currently very crude, but could be
made to allow a limited amount of caching within the
conditionally-executed blocks.
This query is done using a proper dominator tree analysis, even at -O0.
I do not expect that we will frequently need to actually build the
tree, and I expect that the code-size benefits of doing a real
analysis will be significant, especially as we move towards making
more metadata lazily computed.
The second feature is that this adds support for "abstract"
cache entries, which indicate that we know how to derive the metadata
but haven't actually done so. This code isn't yet tested, but
it's going to be the basis of making a lot of things much lazier.
We can't bitcast an i64 into an i8*, we have to do an int to pointer
cast instead.
This exposes a new issue, where dynamic casts do not support casting
from Optional<A> to A -- tracked in <rdar://problem/23122310>.
Fixes <rdar://problem/23055035>.
Swift SVN r32704
rdar://22666588
This change removes a comparison and a branch on every virtual call. Before this
change we were generating code for comparing the metadata to figure out if the
incoming instance is an 'exact' cast, and then we checked if the result of the
cast was zero. This is unnecessary because we can simply reuse the result of the
exact metadata comparison. Moreover, we know that the metadata instance can't be
zero because we've emitted a load to that address that did not trap.
%1 = getelementptr inbounds %C4main1X, %C4main1X* %0 ...
%.metadata = load %swift.type*, %swift.type** %1 // Loading %0
%2 = icmp eq %swift.type* %.metadata, bitcast (...)
%3 = icmp ne %C4main1X* %0, null ; <----------- %0 can't be null.
%4 = and i1 %3, %2
br i1 %4, label %5, label %7
Swift SVN r31920
And they're not even guaranteed to be casts to ObjC classes. They might be
Swift subclasses of ObjC classes.
This fixes a type-safety hole where, e.g. a generic cast from NSPredicate
to NSDate was allowed because we were checking against NSObject.
rdar://problem/22242369
Swift SVN r31153
emitScalarExistentialDowncast() would return an explosion consisting
of the original input value, followed by witness tables returned by
calling emitExistentialScalarCastFn().
The result of this explosion was then tested by comparing the first
element against NULL, which is wrong, since the first element was
set to the input value unconditionally.
Address this by changing the dynamic cast functions to take the value
as the first argument, and return it as the first element of the
return tuple. The value is not used directly, only set to NULL if the
cast fails. This makes the NULL check in visitCheckedCastBranchInst()
work as intended.
Note that now the result of the cast becomes a different LLVM value
than the input. With the dynamic cast function inlined, this should
not be an issue, since this is already the case for dynamic class cast.
There are also perhaps too many bitcast instructions generated now.
This could be cleaned up.
Fixes <rdar://problem/20920874>.
Swift SVN r28712
All llvm::Functions created during IRGen will have target-cpu and target-features
attributes if they are non-null.
Update testing cases to expect the attribute in function definition.
Add testing case function-target-features.swift to verify target-cpu and
target-features.
rdar://20772331
Swift SVN r28186
Fixes rdar://problem/20583365, and incidentally gets test/Interpreter/layout_reabstraction.swift to work without ObjC interop as well.
Swift SVN r27557
This is needed to support inline caching of self.dynamicType.foo().
Fixes <rdar://problem/19888836> Swift compiler segmentation fault during static analysis
Swift SVN r25686
They don't need one, and nobody really conforms to the AnyObject sham protocol at runtime. Fixes rdar://problem/19624697, though there's going to be a similiar problem with metatype-to-AnyObject casts that needs fixing as well.
Swift SVN r24802
The optimizer could eliminate these but isn't there yet. These instructions are valid nonetheless and should be emittable. Fixes rdar://problem/18934125.
Swift SVN r23269
These always fail, and it doesn't make sense to inline this check into the cast site, so provide additional runtime functions for metatype-to-objc-existential casts.
Swift SVN r23237
The code path here is mostly the same as the class cast case--we have to test the ObjC class (if it is a class) against any ObjC protocols, then look up conformances for the native protocols.
Swift SVN r23184