Skip to content

Commit ee06256

Browse files
authored
Merge pull request #12260 from slavapestov/sil-objc-method
Split off objc_method / objc_super_method from class_method / super_method
2 parents bd0a683 + 1632b73 commit ee06256

File tree

88 files changed

+858
-591
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+858
-591
lines changed

docs/SIL.rst

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ Some additional meaningful categories of type:
628628

629629
- A *heap object reference* type is a type whose representation consists of a
630630
single strong-reference-counted pointer. This includes all class types,
631-
the ``Builtin.NativeObject`` and ``Builtin.UnknownObject`` types, and
631+
the ``Builtin.NativeObject`` and ``AnyObject`` types, and
632632
archetypes that conform to one or more class protocols.
633633
- A *reference type* is more general in that its low-level representation may
634634
include additional global pointers alongside a strong-reference-counted
@@ -734,7 +734,7 @@ The following types are considered layout-compatible:
734734
``B`` and a derived class ``D`` inheriting from ``B``, a value of
735735
type ``B`` referencing an instance of type ``D`` is layout compatible with
736736
both ``B`` and ``D``, as well as ``Builtin.NativeObject`` and
737-
``Builtin.UnknownObject``. It is not layout compatible with an unrelated class
737+
``AnyObject``. It is not layout compatible with an unrelated class
738738
type ``E``.
739739
- For payloaded enums, the payload type of the first payloaded case is
740740
layout-compatible with the enum (*not* commutatively).
@@ -1034,11 +1034,14 @@ VTables
10341034
sil-vtable-entry ::= sil-decl-ref ':' sil-linkage? sil-function-name
10351035

10361036
SIL represents dynamic dispatch for class methods using the `class_method`_,
1037-
`super_method`_, and `dynamic_method`_ instructions. The potential destinations
1038-
for these dispatch operations are tracked in ``sil_vtable`` declarations for
1039-
every class type. The declaration contains a mapping from every method of the
1040-
class (including those inherited from its base class) to the SIL function that
1041-
implements the method for that class::
1037+
`super_method`_, `objc_method`_, `objc_super_method`_ and `dynamic_method`_
1038+
instructions.
1039+
1040+
The potential destinations for `class_method`_ and `super_method`_ are
1041+
tracked in ``sil_vtable`` declarations for every class type. The declaration
1042+
contains a mapping from every method of the class (including those inherited
1043+
from its base class) to the SIL function that implements the method for that
1044+
class::
10421045

10431046
class A {
10441047
func foo()
@@ -1592,9 +1595,9 @@ typed, so aliasing of classes is constrained by the type system as follows:
15921595
including a Swift class instance, a box allocated by ``alloc_box``,
15931596
or a thick function's closure context.
15941597
It may not alias natively Objective-C class instances.
1595-
* A ``Builtin.UnknownObject`` or ``Builtin.BridgeObject`` may alias
1596-
any class instance, whether Swift or Objective-C, but may not alias
1597-
non-class-instance heap objects.
1598+
* An ``AnyObject`` or ``Builtin.BridgeObject`` may alias any class instance,
1599+
whether Swift or Objective-C, but may not alias non-class-instance
1600+
heap objects.
15981601
* Two values of the same class type ``$C`` may alias. Two values of related
15991602
class type ``$B`` and ``$D``, where there is a subclass relationship between
16001603
``$B`` and ``$D``, may alias. Two values of unrelated class types may not
@@ -2937,24 +2940,19 @@ method name segment.
29372940
Dynamic Dispatch
29382941
~~~~~~~~~~~~~~~~
29392942

2940-
These instructions perform dynamic lookup of class and generic methods. They
2941-
share a common set of attributes::
2943+
These instructions perform dynamic lookup of class and generic methods.
29422944

2943-
sil-method-attributes ::= '[' 'volatile'? ']'
2945+
The ``class_method`` and ``super_method`` instructions must reference
2946+
Swift native methods and always use vtable dispatch.
29442947

2945-
The ``volatile`` attribute on a dynamic dispatch instruction indicates that
2946-
the method lookup is semantically required (as, for example, in Objective-C).
2947-
When the type of a dynamic dispatch instruction's operand is known,
2948-
optimization passes can promote non-``volatile`` dispatch instructions
2949-
into static ``function_ref`` instructions.
2948+
The ``objc_method``, ``objc_super_method`` and ``dynamic_method``
2949+
instructions must reference Objective-C methods (indicated by the
2950+
``foreign`` marker on a method reference, as in
2951+
``#NSObject.description!1.foreign``).
29502952

2951-
If a dynamic dispatch instruction references an Objective-C method
2952-
(indicated by the ``foreign`` marker on a method reference, as in
2953-
``#NSObject.description!1.foreign``), then the instruction
2954-
represents an ``objc_msgSend`` invocation. ``objc_msgSend`` invocations can
2955-
only be used as the callee of an ``apply`` instruction or ``partial_apply``
2956-
instruction. They cannot be stored or used as ``apply`` or ``partial_apply``
2957-
arguments. ``objc_msgSend`` invocations must always be ``volatile``.
2953+
Note that ``objc_msgSend`` invocations can only be used as the callee
2954+
of an ``apply`` instruction or ``partial_apply`` instruction. They cannot
2955+
be stored or used as ``apply`` or ``partial_apply`` arguments.
29582956

29592957
class_method
29602958
````````````
@@ -2963,30 +2961,55 @@ class_method
29632961
sil-instruction ::= 'class_method' sil-method-attributes?
29642962
sil-operand ',' sil-decl-ref ':' sil-type
29652963

2966-
%1 = class_method %0 : $T, #T.method!1 : $@convention(thin) U -> V
2964+
%1 = class_method %0 : $T, #T.method!1 : $@convention(class_method) U -> V
29672965
// %0 must be of a class type or class metatype $T
2968-
// #T.method!1 must be a reference to a dynamically-dispatched method of T or
2969-
// of one of its superclasses, at uncurry level >= 1
2966+
// #T.method!1 must be a reference to a Swift native method of T or
2967+
// of one of its superclasses, at uncurry level == 1
29702968
// %1 will be of type $U -> V
29712969

29722970
Looks up a method based on the dynamic type of a class or class metatype
2973-
instance. It is undefined behavior if the class value is null and the
2974-
method is not an Objective-C method.
2971+
instance. It is undefined behavior if the class value is null.
29752972

2976-
If:
2973+
If the static type of the class instance is known, or the method is known
2974+
to be final, then the instruction is a candidate for devirtualization
2975+
optimization. A devirtualization pass can consult the module's `VTables`_
2976+
to find the SIL function that implements the method and promote the
2977+
instruction to a static `function_ref`_.
29772978

2978-
- the instruction is not ``[volatile]``,
2979-
- the referenced method is not a ``foreign`` method,
2980-
- and the static type of the class instance is known, or the method is known
2981-
to be final,
2979+
objc_method
2980+
```````````
2981+
::
29822982

2983-
then the instruction is a candidate for devirtualization optimization. A
2984-
devirtualization pass can consult the module's `VTables`_ to find the
2985-
SIL function that implements the method and promote the instruction to a
2986-
static `function_ref`_.
2983+
sil-instruction ::= 'objc_method' sil-method-attributes?
2984+
sil-operand ',' sil-decl-ref ':' sil-type
2985+
2986+
%1 = objc_method %0 : $T, #T.method!1.foreign : $@convention(objc_method) U -> V
2987+
// %0 must be of a class type or class metatype $T
2988+
// #T.method!1 must be a reference to an Objective-C method of T or
2989+
// of one of its superclasses, at uncurry level == 1
2990+
// %1 will be of type $U -> V
2991+
2992+
Performs Objective-C method dispatch using ``objc_msgSend()``.
2993+
2994+
Objective-C method calls are never candidates for devirtualization.
29872995

29882996
super_method
29892997
````````````
2998+
::
2999+
3000+
sil-instruction ::= 'super_method' sil-method-attributes?
3001+
sil-operand ',' sil-decl-ref ':' sil-type
3002+
3003+
%1 = super_method %0 : $T, #Super.method!1 : $@convention(thin) U -> V
3004+
// %0 must be of a non-root class type or class metatype $T
3005+
// #Super.method!1 must be a reference to a native Swift method of T's
3006+
// superclass or of one of its ancestor classes, at uncurry level >= 1
3007+
// %1 will be of type $@convention(thin) U -> V
3008+
3009+
Looks up a method in the superclass of a class or class metatype instance.
3010+
3011+
objc_super_method
3012+
`````````````````
29903013
::
29913014

29923015
sil-instruction ::= 'super_method' sil-method-attributes?
@@ -2998,11 +3021,8 @@ super_method
29983021
// superclass or of one of its ancestor classes, at uncurry level >= 1
29993022
// %1 will be of type $@convention(thin) U -> V
30003023

3001-
Looks up a method in the superclass of a class or class metatype instance.
3002-
Note that for native Swift methods, ``super.method`` calls are statically
3003-
dispatched, so this instruction is only valid for Objective-C methods.
3004-
It is undefined behavior if the class value is null and the method is
3005-
not an Objective-C method.
3024+
This instruction performs an Objective-C message send using
3025+
``objc_msgSuper()``.
30063026

30073027
witness_method
30083028
``````````````
@@ -3040,13 +3060,13 @@ dynamic_method
30403060
// or protocol type
30413061
//
30423062
// The "self" argument of the method type $@convention(thin) U -> V must be
3043-
// Builtin.UnknownObject
3063+
// AnyObject
30443064

30453065
Looks up the implementation of an Objective-C method with the same
30463066
selector as the named method for the dynamic type of the
30473067
value inside an existential container. The "self" operand of the result
30483068
function value is represented using an opaque type, the value for which must
3049-
be projected out as a value of type ``Builtin.UnknownObject``.
3069+
be projected out as a value of type ``AnyObject``.
30503070

30513071
It is undefined behavior if the dynamic type of the operand does not
30523072
have an implementation for the Objective-C method with the selector to
@@ -4363,7 +4383,7 @@ ref_to_raw_pointer
43634383
sil-instruction ::= 'ref_to_raw_pointer' sil-operand 'to' sil-type
43644384

43654385
%1 = ref_to_raw_pointer %0 : $C to $Builtin.RawPointer
4366-
// $C must be a class type, or Builtin.NativeObject, or Builtin.UnknownObject
4386+
// $C must be a class type, or Builtin.NativeObject, or AnyObject
43674387
// %1 will be of type $Builtin.RawPointer
43684388

43694389
Converts a heap object reference to a ``Builtin.RawPointer``. The ``RawPointer``
@@ -4378,7 +4398,7 @@ raw_pointer_to_ref
43784398
sil-instruction ::= 'raw_pointer_to_ref' sil-operand 'to' sil-type
43794399

43804400
%1 = raw_pointer_to_ref %0 : $Builtin.RawPointer to $C
4381-
// $C must be a class type, or Builtin.NativeObject, or Builtin.UnknownObject
4401+
// $C must be a class type, or Builtin.NativeObject, or AnyObject
43824402
// %1 will be of type $C
43834403

43844404
Converts a ``Builtin.RawPointer`` back to a heap object reference. Casting

include/swift/SIL/PatternMatch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,9 @@ UNARY_OP_MATCH_WITH_ARG_MATCHER(StructElementAddrInst)
367367
UNARY_OP_MATCH_WITH_ARG_MATCHER(LoadInst)
368368
UNARY_OP_MATCH_WITH_ARG_MATCHER(RefElementAddrInst)
369369
UNARY_OP_MATCH_WITH_ARG_MATCHER(ClassMethodInst)
370+
UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCMethodInst)
370371
UNARY_OP_MATCH_WITH_ARG_MATCHER(SuperMethodInst)
372+
UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCSuperMethodInst)
371373
UNARY_OP_MATCH_WITH_ARG_MATCHER(DynamicMethodInst)
372374
UNARY_OP_MATCH_WITH_ARG_MATCHER(OpenExistentialAddrInst)
373375
UNARY_OP_MATCH_WITH_ARG_MATCHER(OpenExistentialRefInst)

include/swift/SIL/SILBuilder.h

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,33 +1185,27 @@ class SILBuilder {
11851185
}
11861186

11871187
ClassMethodInst *createClassMethod(SILLocation Loc, SILValue Operand,
1188-
SILDeclRef Member, SILType MethodTy,
1189-
bool Volatile = false) {
1188+
SILDeclRef Member, SILType MethodTy) {
11901189
return insert(new (getModule()) ClassMethodInst(
1191-
getSILDebugLocation(Loc), Operand, Member, MethodTy, Volatile));
1190+
getSILDebugLocation(Loc), Operand, Member, MethodTy));
11921191
}
11931192

1194-
ClassMethodInst *createClassMethod(SILLocation Loc, SILValue Operand,
1195-
SILDeclRef Member, bool Volatile = false) {
1196-
auto MethodTy = getModule().Types.getConstantOverrideType(Member);
1197-
return createClassMethod(Loc, Operand, Member,
1198-
SILType::getPrimitiveObjectType(MethodTy),
1199-
Volatile);
1193+
SuperMethodInst *createSuperMethod(SILLocation Loc, SILValue Operand,
1194+
SILDeclRef Member, SILType MethodTy) {
1195+
return insert(new (getModule()) SuperMethodInst(
1196+
getSILDebugLocation(Loc), Operand, Member, MethodTy));
12001197
}
12011198

1202-
/// Emit a class_method reference to the least derived overridden decl for
1203-
/// the given method, and upcast the "self" pointer to the matching superclass
1204-
/// type.
1205-
std::pair<ClassMethodInst *, SILValue> emitClassMethod(SILLocation Loc,
1206-
SILValue Self,
1207-
SILDeclRef Member,
1208-
bool Volatile = false);
1199+
ObjCMethodInst *createObjCMethod(SILLocation Loc, SILValue Operand,
1200+
SILDeclRef Member, SILType MethodTy) {
1201+
return insert(new (getModule()) ObjCMethodInst(
1202+
getSILDebugLocation(Loc), Operand, Member, MethodTy));
1203+
}
12091204

1210-
SuperMethodInst *createSuperMethod(SILLocation Loc, SILValue Operand,
1211-
SILDeclRef Member, SILType MethodTy,
1212-
bool Volatile = false) {
1213-
return insert(new (getModule()) SuperMethodInst(
1214-
getSILDebugLocation(Loc), Operand, Member, MethodTy, Volatile));
1205+
ObjCSuperMethodInst *createObjCSuperMethod(SILLocation Loc, SILValue Operand,
1206+
SILDeclRef Member, SILType MethodTy) {
1207+
return insert(new (getModule()) ObjCSuperMethodInst(
1208+
getSILDebugLocation(Loc), Operand, Member, MethodTy));
12151209
}
12161210

12171211
WitnessMethodInst *createWitnessMethod(SILLocation Loc, CanType LookupTy,
@@ -1224,10 +1218,9 @@ class SILBuilder {
12241218
}
12251219

12261220
DynamicMethodInst *createDynamicMethod(SILLocation Loc, SILValue Operand,
1227-
SILDeclRef Member, SILType MethodTy,
1228-
bool Volatile = false) {
1221+
SILDeclRef Member, SILType MethodTy) {
12291222
return insert(DynamicMethodInst::create(
1230-
getSILDebugLocation(Loc), Operand, Member, MethodTy, Volatile,
1223+
getSILDebugLocation(Loc), Operand, Member, MethodTy,
12311224
&getFunction(), OpenedArchetypes));
12321225
}
12331226

include/swift/SIL/SILCloner.h

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,8 +1535,7 @@ SILCloner<ImplClass>::visitClassMethodInst(ClassMethodInst *Inst) {
15351535
getBuilder().createClassMethod(getOpLocation(Inst->getLoc()),
15361536
getOpValue(Inst->getOperand()),
15371537
Inst->getMember(),
1538-
Inst->getType(),
1539-
Inst->isVolatile()));
1538+
Inst->getType()));
15401539
}
15411540

15421541
template<typename ImplClass>
@@ -1547,8 +1546,29 @@ SILCloner<ImplClass>::visitSuperMethodInst(SuperMethodInst *Inst) {
15471546
getBuilder().createSuperMethod(getOpLocation(Inst->getLoc()),
15481547
getOpValue(Inst->getOperand()),
15491548
Inst->getMember(),
1550-
Inst->getType(),
1551-
Inst->isVolatile()));
1549+
Inst->getType()));
1550+
}
1551+
1552+
template<typename ImplClass>
1553+
void
1554+
SILCloner<ImplClass>::visitObjCMethodInst(ObjCMethodInst *Inst) {
1555+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1556+
doPostProcess(Inst,
1557+
getBuilder().createObjCMethod(getOpLocation(Inst->getLoc()),
1558+
getOpValue(Inst->getOperand()),
1559+
Inst->getMember(),
1560+
Inst->getType()));
1561+
}
1562+
1563+
template<typename ImplClass>
1564+
void
1565+
SILCloner<ImplClass>::visitObjCSuperMethodInst(ObjCSuperMethodInst *Inst) {
1566+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1567+
doPostProcess(Inst,
1568+
getBuilder().createObjCSuperMethod(getOpLocation(Inst->getLoc()),
1569+
getOpValue(Inst->getOperand()),
1570+
Inst->getMember(),
1571+
Inst->getType()));
15521572
}
15531573

15541574
template<typename ImplClass>
@@ -1589,8 +1609,7 @@ SILCloner<ImplClass>::visitDynamicMethodInst(DynamicMethodInst *Inst) {
15891609
getBuilder().createDynamicMethod(getOpLocation(Inst->getLoc()),
15901610
getOpValue(Inst->getOperand()),
15911611
Inst->getMember(),
1592-
getOpType(Inst->getType()),
1593-
Inst->isVolatile()));
1612+
getOpType(Inst->getType())));
15941613
}
15951614

15961615
template<typename ImplClass>

0 commit comments

Comments
 (0)