Skip to content

Commit

Permalink
SIL: Remove dynamic_method instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
slavapestov committed Oct 4, 2017
1 parent aceb620 commit e806b62
Show file tree
Hide file tree
Showing 26 changed files with 29 additions and 186 deletions.
44 changes: 4 additions & 40 deletions docs/SIL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1034,8 +1034,7 @@ VTables
sil-vtable-entry ::= sil-decl-ref ':' sil-linkage? sil-function-name

SIL represents dynamic dispatch for class methods using the `class_method`_,
`super_method`_, `objc_method`_, `objc_super_method`_ and `dynamic_method`_
instructions.
`super_method`_, `objc_method`_, and `objc_super_method`_ instructions.

The potential destinations for `class_method`_ and `super_method`_ are
tracked in ``sil_vtable`` declarations for every class type. The declaration
Expand Down Expand Up @@ -2945,10 +2944,9 @@ These instructions perform dynamic lookup of class and generic methods.
The ``class_method`` and ``super_method`` instructions must reference
Swift native methods and always use vtable dispatch.

The ``objc_method``, ``objc_super_method`` and ``dynamic_method``
instructions must reference Objective-C methods (indicated by the
``foreign`` marker on a method reference, as in
``#NSObject.description!1.foreign``).
The ``objc_method`` and ``objc_super_method`` instructions must reference
Objective-C methods (indicated by the ``foreign`` marker on a method
reference, as in ``#NSObject.description!1.foreign``).

Note that ``objc_msgSend`` invocations can only be used as the callee
of an ``apply`` instruction or ``partial_apply`` instruction. They cannot
Expand Down Expand Up @@ -3046,40 +3044,6 @@ archetype of the original protocol and have the ``witness_method`` calling
convention. If the referenced protocol is an ``@objc`` protocol, the
resulting type has the ``objc`` calling convention.

dynamic_method
``````````````
::

sil-instruction ::= 'dynamic_method' sil-method-attributes?
sil-operand ',' sil-decl-ref ':' sil-type

%1 = dynamic_method %0 : $P, #X.method!1 : $@convention(thin) U -> V
// %0 must be of a protocol or protocol composition type $P,
// where $P contains the Swift.DynamicLookup protocol
// #X.method!1 must be a reference to an @objc method of any class
// or protocol type
//
// The "self" argument of the method type $@convention(thin) U -> V must be
// AnyObject

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

It is undefined behavior if the dynamic type of the operand does not
have an implementation for the Objective-C method with the selector to
which the ``dynamic_method`` instruction refers, or if that
implementation has parameter or result types that are incompatible
with the method referenced by ``dynamic_method``.
This instruction should only be used in cases where its result will be
immediately consumed by an operation that performs the selector check
itself (e.g., an ``apply`` that lowers to ``objc_msgSend``).
To query whether the operand has an implementation for the given
method and safely handle the case where it does not, use
`dynamic_method_br`_.

Function Application
~~~~~~~~~~~~~~~~~~~~

Expand Down
1 change: 0 additions & 1 deletion include/swift/SIL/PatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,6 @@ UNARY_OP_MATCH_WITH_ARG_MATCHER(ClassMethodInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCMethodInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(SuperMethodInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCSuperMethodInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(DynamicMethodInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(OpenExistentialAddrInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(OpenExistentialRefInst)
UNARY_OP_MATCH_WITH_ARG_MATCHER(OpenExistentialValueInst)
Expand Down
7 changes: 0 additions & 7 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1218,13 +1218,6 @@ class SILBuilder {
&getFunction(), OpenedArchetypes, Volatile));
}

DynamicMethodInst *createDynamicMethod(SILLocation Loc, SILValue Operand,
SILDeclRef Member, SILType MethodTy) {
return insert(DynamicMethodInst::create(
getSILDebugLocation(Loc), Operand, Member, MethodTy,
&getFunction(), OpenedArchetypes));
}

OpenExistentialAddrInst *
createOpenExistentialAddr(SILLocation Loc, SILValue Operand, SILType SelfTy,
OpenedExistentialAccess ForAccess) {
Expand Down
11 changes: 0 additions & 11 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -1601,17 +1601,6 @@ SILCloner<ImplClass>::visitWitnessMethodInst(WitnessMethodInst *Inst) {
Inst->isVolatile()));
}

template<typename ImplClass>
void
SILCloner<ImplClass>::visitDynamicMethodInst(DynamicMethodInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst,
getBuilder().createDynamicMethod(getOpLocation(Inst->getLoc()),
getOpValue(Inst->getOperand()),
Inst->getMember(),
getOpType(Inst->getType())));
}

template<typename ImplClass>
void
SILCloner<ImplClass>::visitOpenExistentialAddrInst(OpenExistentialAddrInst *Inst) {
Expand Down
24 changes: 0 additions & 24 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4983,30 +4983,6 @@ class WitnessMethodInst final
}
};

/// Given the address of a value of AnyObject protocol type and a method
/// constant referring to some Objective-C method, performs dynamic method
/// lookup to extract the implementation of that method. This method lookup
/// can fail at run-time
class DynamicMethodInst final
: public UnaryInstructionWithTypeDependentOperandsBase<
SILInstructionKind::DynamicMethodInst,
DynamicMethodInst,
MethodInst>
{
friend SILBuilder;

DynamicMethodInst(SILDebugLocation DebugLoc, SILValue Operand,
ArrayRef<SILValue> TypeDependentOperands,
SILDeclRef Member, SILType Ty)
: UnaryInstructionWithTypeDependentOperandsBase(DebugLoc, Operand,
TypeDependentOperands, Ty, Member) {}

static DynamicMethodInst *
create(SILDebugLocation DebugLoc, SILValue Operand,
SILDeclRef Member, SILType Ty, SILFunction *F,
SILOpenedArchetypesState &OpenedArchetypes);
};

/// Access allowed to the opened value by the open_existential_addr instruction.
/// Allowing mutable access to the opened existential requires a boxed
/// existential value's box to be unique.
Expand Down
4 changes: 1 addition & 3 deletions include/swift/SIL/SILNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,7 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
MethodInst, None, DoesNotRelease)
SINGLE_VALUE_INST(WitnessMethodInst, witness_method,
MethodInst, None, DoesNotRelease)
SINGLE_VALUE_INST(DynamicMethodInst, dynamic_method,
MethodInst, None, DoesNotRelease)
SINGLE_VALUE_INST_RANGE(MethodInst, ClassMethodInst, DynamicMethodInst)
SINGLE_VALUE_INST_RANGE(MethodInst, ClassMethodInst, WitnessMethodInst)

// Conversions
ABSTRACT_SINGLE_VALUE_INST(ConversionInst, SingleValueInstruction)
Expand Down
7 changes: 0 additions & 7 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,6 @@ class IRGenSILFunction :
void visitObjCMethodInst(ObjCMethodInst *i);
void visitObjCSuperMethodInst(ObjCSuperMethodInst *i);
void visitWitnessMethodInst(WitnessMethodInst *i);
void visitDynamicMethodInst(DynamicMethodInst *i);

void visitAllocValueBufferInst(AllocValueBufferInst *i);
void visitProjectValueBufferInst(ProjectValueBufferInst *i);
Expand Down Expand Up @@ -5001,12 +5000,6 @@ IRGenSILFunction::visitProjectExistentialBoxInst(ProjectExistentialBoxInst *i) {
}
}

void IRGenSILFunction::visitDynamicMethodInst(DynamicMethodInst *i) {
assert(i->getMember().isForeign && "dynamic_method requires [objc] method");
setLoweredObjCMethod(i, i->getMember());
return;
}

void IRGenSILFunction::visitWitnessMethodInst(swift::WitnessMethodInst *i) {
// For Objective-C classes we need to arrange for a msgSend
// to happen when the method is called.
Expand Down
9 changes: 0 additions & 9 deletions lib/IRGen/LoadableByAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,6 @@ void LargeValueVisitor::mapValueStorage() {
case SILInstructionKind::SuperMethodInst:
case SILInstructionKind::ObjCMethodInst:
case SILInstructionKind::ObjCSuperMethodInst:
case SILInstructionKind::DynamicMethodInst:
case SILInstructionKind::WitnessMethodInst: {
// TODO Any more instructions to add here?
auto *MI = dyn_cast<MethodInst>(currIns);
Expand Down Expand Up @@ -2037,14 +2036,6 @@ static void rewriteFunction(StructLoweringState &pass,
newSILType);
break;
}
case SILInstructionKind::DynamicMethodInst: {
auto *DMI = dyn_cast<DynamicMethodInst>(instr);
assert(DMI && "ValueKind is Witness Method but dyn_cast failed");
SILValue selfValue = instr->getOperand(0);
newInstr = methodBuilder.createDynamicMethod(loc, selfValue, member,
newSILType);
break;
}
case SILInstructionKind::WitnessMethodInst: {
auto *WMI = dyn_cast<WitnessMethodInst>(instr);
assert(!WMI->isVolatile());
Expand Down
6 changes: 1 addition & 5 deletions lib/ParseSIL/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3784,8 +3784,7 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
case SILInstructionKind::ClassMethodInst:
case SILInstructionKind::SuperMethodInst:
case SILInstructionKind::ObjCMethodInst:
case SILInstructionKind::ObjCSuperMethodInst:
case SILInstructionKind::DynamicMethodInst: {
case SILInstructionKind::ObjCSuperMethodInst: {
SILDeclRef Member;
SILType MethodTy;
SourceLoc TyLoc;
Expand Down Expand Up @@ -3816,9 +3815,6 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
case SILInstructionKind::ObjCSuperMethodInst:
ResultVal = B.createObjCSuperMethod(InstLoc, Val, Member, MethodTy);
break;
case SILInstructionKind::DynamicMethodInst:
ResultVal = B.createDynamicMethod(InstLoc, Val, Member, MethodTy);
break;
}
break;
}
Expand Down
17 changes: 0 additions & 17 deletions lib/SIL/SILInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1615,23 +1615,6 @@ WitnessMethodInst::create(SILDebugLocation Loc, CanType LookupType,
Ty, TypeDependentOperands, Volatile);
}

DynamicMethodInst *
DynamicMethodInst::create(SILDebugLocation DebugLoc, SILValue Operand,
SILDeclRef Member, SILType Ty, SILFunction *F,
SILOpenedArchetypesState &OpenedArchetypes) {
SILModule &Mod = F->getModule();
SmallVector<SILValue, 8> TypeDependentOperands;
collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, *F,
Ty.getSwiftRValueType());

unsigned size =
totalSizeToAlloc<swift::Operand>(1 + TypeDependentOperands.size());
void *Buffer = Mod.allocateInst(size, alignof(DynamicMethodInst));
return ::new (Buffer) DynamicMethodInst(DebugLoc, Operand,
TypeDependentOperands,
Member, Ty);
}

ObjCMethodInst *
ObjCMethodInst::create(SILDebugLocation DebugLoc, SILValue Operand,
SILDeclRef Member, SILType Ty, SILFunction *F,
Expand Down
1 change: 0 additions & 1 deletion lib/SIL/SILOwnershipVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,6 @@ ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, SuperMethod)
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, ObjCSuperMethod)
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, BridgeObjectToWord)
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, CopyBlock)
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, DynamicMethod)
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, OpenExistentialBox)
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefTailAddr)
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefToRawPointer)
Expand Down
6 changes: 0 additions & 6 deletions lib/SIL/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1631,12 +1631,6 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
}
*this << " : " << WMI->getType();
}
void visitDynamicMethodInst(DynamicMethodInst *DMI) {
printMethodInst(DMI, DMI->getOperand());
*this << " : " << DMI->getMember().getDecl()->getInterfaceType();
*this << ", ";
*this << DMI->getType();
}
void visitOpenExistentialAddrInst(OpenExistentialAddrInst *OI) {
if (OI->getAccessKind() == OpenedExistentialAccess::Immutable)
*this << "immutable_access ";
Expand Down
20 changes: 0 additions & 20 deletions lib/SIL/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2194,26 +2194,6 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
return SILType::getPrimitiveObjectType(fnTy);
}

void checkDynamicMethodInst(DynamicMethodInst *EMI) {
requireObjectType(SILFunctionType, EMI, "result of dynamic_method");
SILType operandType = EMI->getOperand()->getType();

require(EMI->getMember().getDecl()->isObjC(), "method must be @objc");
if (!EMI->getMember().getDecl()->isInstanceMember()) {
require(operandType.is<MetatypeType>(),
"operand must have metatype type");
require(operandType.castTo<MetatypeType>()
->getInstanceType()->mayHaveSuperclass(),
"operand must have metatype of class or class-bounded type");
}

require(getDynamicMethodType(operandType, EMI->getMember())
.getSwiftRValueType()
->isBindableTo(EMI->getType().getSwiftRValueType()),
"result must be of the method's type");
verifyOpenedArchetype(EMI, EMI->getType().getSwiftRValueType());
}

void checkClassMethodInst(ClassMethodInst *CMI) {
auto member = CMI->getMember();
auto overrideTy = TC.getConstantOverrideType(member);
Expand Down
1 change: 0 additions & 1 deletion lib/SIL/ValueOwnershipKindClassifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ CONSTANT_OWNERSHIP_INST(Trivial, BeginAccess)
CONSTANT_OWNERSHIP_INST(Trivial, BridgeObjectToWord)
CONSTANT_OWNERSHIP_INST(Trivial, ClassMethod)
CONSTANT_OWNERSHIP_INST(Trivial, ObjCMethod)
CONSTANT_OWNERSHIP_INST(Trivial, DynamicMethod)
CONSTANT_OWNERSHIP_INST(Trivial, ExistentialMetatype)
CONSTANT_OWNERSHIP_INST(Trivial, FloatLiteral)
CONSTANT_OWNERSHIP_INST(Trivial, FunctionRef)
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ class Callee {
Scope S(SGF, Loc);
ManagedValue self =
SelfValue.getValue().borrow(SGF).getAsSingleValue(SGF);
SILValue fn = SGF.B.createDynamicMethod(
SILValue fn = SGF.B.createObjCMethod(
Loc, self.getValue(), *constant,
SILType::getPrimitiveObjectType(closureType));
return ManagedValue::forUnmanaged(fn);
Expand Down
1 change: 0 additions & 1 deletion lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ CalleeList CalleeCache::getCalleeListForCalleeKind(SILValue Callee) const {
return getCalleeList(cast<ClassMethodInst>(Callee));

case ValueKind::SuperMethodInst:
case ValueKind::DynamicMethodInst:
case ValueKind::ObjCMethodInst:
case ValueKind::ObjCSuperMethodInst:
return CalleeList();
Expand Down
1 change: 0 additions & 1 deletion lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ static bool isNonWritableMemoryAddress(SILNode *V) {
case SILNodeKind::SuperMethodInst:
case SILNodeKind::ObjCMethodInst:
case SILNodeKind::ObjCSuperMethodInst:
case SILNodeKind::DynamicMethodInst:
case SILNodeKind::StringLiteralInst:
case SILNodeKind::ThinToThickFunctionInst:
case SILNodeKind::ThinFunctionToPointerInst:
Expand Down
1 change: 0 additions & 1 deletion lib/SILOptimizer/Utils/SILInliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,6 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
case SILInstructionKind::AutoreleaseValueInst:
case SILInstructionKind::UnmanagedAutoreleaseValueInst:
case SILInstructionKind::DynamicMethodBranchInst:
case SILInstructionKind::DynamicMethodInst:
case SILInstructionKind::EnumInst:
case SILInstructionKind::IndexAddrInst:
case SILInstructionKind::TailAddrInst:
Expand Down
8 changes: 1 addition & 7 deletions lib/Serialization/DeserializeSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1897,8 +1897,7 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
case SILInstructionKind::ClassMethodInst:
case SILInstructionKind::SuperMethodInst:
case SILInstructionKind::ObjCMethodInst:
case SILInstructionKind::ObjCSuperMethodInst:
case SILInstructionKind::DynamicMethodInst: {
case SILInstructionKind::ObjCSuperMethodInst: {
// Format: a type, an operand and a SILDeclRef. Use SILOneTypeValuesLayout:
// type, Attr, SILDeclRef (DeclID, Kind, uncurryLevel), and an operand.
unsigned NextValueIndex = 0;
Expand Down Expand Up @@ -1932,11 +1931,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
getLocalValue(ListOfValues[NextValueIndex], operandTy),
DRef, Ty);
break;
case SILInstructionKind::DynamicMethodInst:
ResultVal = Builder.createDynamicMethod(Loc,
getLocalValue(ListOfValues[NextValueIndex], operandTy),
DRef, Ty);
break;
}
break;
}
Expand Down
15 changes: 0 additions & 15 deletions lib/Serialization/SerializeSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1755,21 +1755,6 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
(unsigned)Ty.getCategory(), ListOfValues);
break;
}
case SILInstructionKind::DynamicMethodInst: {
// Format: a type, an operand and a SILDeclRef. Use SILOneTypeValuesLayout:
// type, Attr, SILDeclRef (DeclID, Kind, uncurryLevel),
// and an operand.
const DynamicMethodInst *DMI = cast<DynamicMethodInst>(&SI);
SILType Ty = DMI->getType();
SmallVector<ValueID, 9> ListOfValues;
handleMethodInst(DMI, DMI->getOperand(), ListOfValues);

SILOneTypeValuesLayout::emitRecord(Out, ScratchRecord,
SILAbbrCodes[SILOneTypeValuesLayout::Code], (unsigned)SI.getKind(),
S.addTypeRef(Ty.getSwiftRValueType()),
(unsigned)Ty.getCategory(), ListOfValues);
break;
}
case SILInstructionKind::DynamicMethodBranchInst: {
// Format: a typed value, a SILDeclRef, a BasicBlock ID for method,
// a BasicBlock ID for no method. Use SILOneTypeValuesLayout.
Expand Down
4 changes: 2 additions & 2 deletions test/SIL/Parser/undef.sil
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ bb0:
class_method undef : $C, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
// CHECK: super_method undef : $D, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
super_method undef : $D, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
// CHECK: dynamic_method undef : $C, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
dynamic_method undef : $C, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
// CHECK: objc_method undef : $C, #C.fn!1.foreign : (C) -> () -> (), $@convention(objc_method) (C) -> ()
objc_method undef : $C, #C.fn!1.foreign : (C) -> () -> (), $@convention(objc_method) (C) -> ()

// Function Application

Expand Down
Loading

0 comments on commit e806b62

Please sign in to comment.