@@ -856,38 +856,95 @@ inline SingleValueInstruction *SILNode::castToSingleValueInstruction() {
856856 }
857857}
858858
859- #define DEFINE_ABSTRACT_SINGLE_VALUE_INST_BOILERPLATE (ID ) \
860- static bool classof (const SILNode *node) { \
861- return node->getKind () >= SILNodeKind::First_##ID && \
862- node->getKind () <= SILNodeKind::Last_##ID; \
863- } \
864- static bool classof (const SingleValueInstruction *inst) { \
865- return inst->getKind () >= SILInstructionKind::First_##ID && \
866- inst->getKind () <= SILInstructionKind::Last_##ID; \
859+ #define DEFINE_ABSTRACT_SINGLE_VALUE_INST_BOILERPLATE (ID ) \
860+ static bool classof (const SILNode *node) { \
861+ return node->getKind () >= SILNodeKind::First_##ID && \
862+ node->getKind () <= SILNodeKind::Last_##ID; \
863+ } \
864+ static bool classof (const SingleValueInstruction *inst) { \
865+ return inst->getKind () >= SILInstructionKind::First_##ID && \
866+ inst->getKind () <= SILInstructionKind::Last_##ID; \
867+ }
868+
869+ // / Abstract base class used for isa checks on instructions to determine if they
870+ // / forward ownership and to verify that the set of ownership instructions and
871+ // / the ownership utilities stay in sync via assertions.
872+ // /
873+ // / NOTE: We assume that the constructor for the instruction subclass that
874+ // / initializes the kind field on our object is run before our constructor runs.
875+ class OwnershipForwardingInst {
876+ ValueOwnershipKind ownershipKind;
877+
878+ protected:
879+ OwnershipForwardingInst (SILInstructionKind kind,
880+ ValueOwnershipKind ownershipKind)
881+ : ownershipKind(ownershipKind) {
882+ assert (classof (kind) && " Invalid subclass?!" );
883+ }
884+
885+ public:
886+ ValueOwnershipKind getOwnershipKind () const { return ownershipKind; }
887+
888+ void setOwnershipKind (ValueOwnershipKind newKind) { ownershipKind = newKind; }
889+
890+ static bool classof (const SILNode *node) {
891+ if (auto *i = dyn_cast<SILInstruction>(node))
892+ return classof (i);
893+ return false ;
867894 }
868895
896+ // Defined inline below due to forward declaration issues.
897+ static bool classof (const SILInstruction *inst);
898+
899+ // / Define inline below due to forward declaration issues.
900+ static bool classof (SILInstructionKind kind);
901+ };
902+
869903// / A single value inst that forwards a static ownership from one (or all) of
870904// / its operands.
871905// /
872906// / The ownership kind is set on construction and afterwards must be changed
873907// / explicitly using setOwnershipKind().
874- class OwnershipForwardingSingleValueInst : public SingleValueInstruction {
875- ValueOwnershipKind ownershipKind;
876-
908+ class OwnershipForwardingSingleValueInst : public SingleValueInstruction ,
909+ public OwnershipForwardingInst {
877910protected:
878911 OwnershipForwardingSingleValueInst (SILInstructionKind kind,
879912 SILDebugLocation debugLoc, SILType ty,
880913 ValueOwnershipKind ownershipKind)
881914 : SingleValueInstruction(kind, debugLoc, ty),
882- ownershipKind ( ownershipKind) {
883- assert (ownershipKind );
915+ OwnershipForwardingInst (kind, ownershipKind) {
916+ assert (classof (kind) && " classof missing new subclass?! " );
884917 }
885918
886919public:
887- ValueOwnershipKind getOwnershipKind () const { return ownershipKind; }
888- void setOwnershipKind (ValueOwnershipKind newOwnershipKind) {
889- ownershipKind = newOwnershipKind;
890- assert (ownershipKind);
920+ static bool classof (const SILNode *node) {
921+ if (auto *i = dyn_cast<SILInstruction>(node))
922+ return classof (i);
923+ return false ;
924+ }
925+
926+ static bool classof (SILInstructionKind kind) {
927+ switch (kind) {
928+ case SILInstructionKind::MarkUninitializedInst:
929+ case SILInstructionKind::StructInst:
930+ case SILInstructionKind::ObjectInst:
931+ case SILInstructionKind::TupleInst:
932+ case SILInstructionKind::EnumInst:
933+ case SILInstructionKind::UncheckedEnumDataInst:
934+ case SILInstructionKind::SelectValueInst:
935+ case SILInstructionKind::OpenExistentialRefInst:
936+ case SILInstructionKind::InitExistentialRefInst:
937+ case SILInstructionKind::MarkDependenceInst:
938+ case SILInstructionKind::LinearFunctionInst:
939+ case SILInstructionKind::DifferentiableFunctionInst:
940+ return true ;
941+ default :
942+ return false ;
943+ }
944+ }
945+
946+ static bool classof (const SILInstruction *inst) {
947+ return classof (inst->getKind ());
891948 }
892949};
893950
@@ -4430,19 +4487,42 @@ class ConversionInst : public SingleValueInstruction {
44304487
44314488// / A conversion inst that produces a static OwnershipKind set upon the
44324489// / instruction's construction.
4433- class OwnershipForwardingConversionInst : public ConversionInst {
4434- ValueOwnershipKind ownershipKind;
4435-
4490+ class OwnershipForwardingConversionInst : public ConversionInst ,
4491+ public OwnershipForwardingInst {
44364492protected:
44374493 OwnershipForwardingConversionInst (SILInstructionKind kind,
44384494 SILDebugLocation debugLoc, SILType ty,
44394495 ValueOwnershipKind ownershipKind)
4440- : ConversionInst(kind, debugLoc, ty), ownershipKind(ownershipKind) {}
4496+ : ConversionInst(kind, debugLoc, ty),
4497+ OwnershipForwardingInst (kind, ownershipKind) {
4498+ assert (classof (kind) && " classof missing subclass?!" );
4499+ }
44414500
44424501public:
4443- ValueOwnershipKind getOwnershipKind () const { return ownershipKind; }
4444- void setOwnershipKind (ValueOwnershipKind newOwnershipKind) {
4445- ownershipKind = newOwnershipKind;
4502+ static bool classof (const SILNode *node) {
4503+ if (auto *i = dyn_cast<SILInstruction>(node))
4504+ return classof (i);
4505+ return false ;
4506+ }
4507+
4508+ static bool classof (const SILInstruction *inst) {
4509+ return classof (inst->getKind ());
4510+ }
4511+
4512+ static bool classof (SILInstructionKind kind) {
4513+ switch (kind) {
4514+ case SILInstructionKind::ConvertFunctionInst:
4515+ case SILInstructionKind::UpcastInst:
4516+ case SILInstructionKind::UncheckedRefCastInst:
4517+ case SILInstructionKind::UncheckedValueCastInst:
4518+ case SILInstructionKind::RefToBridgeObjectInst:
4519+ case SILInstructionKind::BridgeObjectToRefInst:
4520+ case SILInstructionKind::ThinToThickFunctionInst:
4521+ case SILInstructionKind::UnconditionalCheckedCastInst:
4522+ return true ;
4523+ default :
4524+ return false ;
4525+ }
44464526 }
44474527};
44484528
@@ -5610,22 +5690,35 @@ class SelectEnumInstBase
56105690};
56115691
56125692// / A select enum inst that produces a static OwnershipKind.
5613- class OwnershipForwardingSelectEnumInstBase : public SelectEnumInstBase {
5614- ValueOwnershipKind ownershipKind;
5615-
5693+ class OwnershipForwardingSelectEnumInstBase : public SelectEnumInstBase ,
5694+ public OwnershipForwardingInst {
56165695protected:
56175696 OwnershipForwardingSelectEnumInstBase (
56185697 SILInstructionKind kind, SILDebugLocation debugLoc, SILType type,
56195698 bool defaultValue, Optional<ArrayRef<ProfileCounter>> caseCounts,
56205699 ProfileCounter defaultCount, ValueOwnershipKind ownershipKind)
56215700 : SelectEnumInstBase(kind, debugLoc, type, defaultValue, caseCounts,
56225701 defaultCount),
5623- ownershipKind (ownershipKind) {}
5702+ OwnershipForwardingInst (kind, ownershipKind) {
5703+ assert (classof (kind) && " classof missing subclass" );
5704+ }
56245705
56255706public:
5626- ValueOwnershipKind getOwnershipKind () const { return ownershipKind; }
5627- void setOwnershipKind (ValueOwnershipKind newOwnershipKind) {
5628- ownershipKind = newOwnershipKind;
5707+ static bool classof (const SILNode *node) {
5708+ if (auto *i = dyn_cast<SILInstruction>(node))
5709+ return classof (i);
5710+ return false ;
5711+ }
5712+
5713+ static bool classof (const SILInstruction *i) { return classof (i->getKind ()); }
5714+
5715+ static bool classof (SILInstructionKind kind) {
5716+ switch (kind) {
5717+ case SILInstructionKind::SelectEnumInst:
5718+ return true ;
5719+ default :
5720+ return false ;
5721+ }
56295722 }
56305723};
56315724
@@ -7327,18 +7420,31 @@ class TermInst : public NonValueInstruction {
73277420 }
73287421};
73297422
7330- class OwnershipForwardingTermInst : public TermInst {
7331- ValueOwnershipKind ownershipKind;
7332-
7423+ class OwnershipForwardingTermInst : public TermInst ,
7424+ public OwnershipForwardingInst {
73337425protected:
73347426 OwnershipForwardingTermInst (SILInstructionKind kind,
73357427 SILDebugLocation debugLoc,
73367428 ValueOwnershipKind ownershipKind)
7337- : TermInst(kind, debugLoc), ownershipKind(ownershipKind) {}
7429+ : TermInst(kind, debugLoc), OwnershipForwardingInst(kind, ownershipKind) {
7430+ assert (classof (kind));
7431+ }
73387432
73397433public:
7340- ValueOwnershipKind getOwnershipKind () const { return ownershipKind; }
7341- void setOwnershipKind (ValueOwnershipKind newKind) { ownershipKind = newKind; }
7434+ static bool classof (const SILNode *node) {
7435+ if (auto *i = dyn_cast<SILInstruction>(node))
7436+ return classof (i);
7437+ return false ;
7438+ }
7439+
7440+ static bool classof (const SILInstruction *inst) {
7441+ return classof (inst->getKind ());
7442+ }
7443+
7444+ static bool classof (SILInstructionKind kind) {
7445+ return kind == SILInstructionKind::SwitchEnumInst ||
7446+ kind == SILInstructionKind::CheckedCastBranchInst;
7447+ }
73427448};
73437449
73447450// / UnreachableInst - Position in the code which would be undefined to reach.
@@ -8771,19 +8877,33 @@ SILFunction *ApplyInstBase<Impl, Base, false>::getCalleeFunction() const {
87718877}
87728878
87738879class OwnershipForwardingMultipleValueInstruction
8774- : public MultipleValueInstruction {
8775- ValueOwnershipKind ownershipKind;
8776-
8880+ : public MultipleValueInstruction,
8881+ public OwnershipForwardingInst {
87778882public:
87788883 OwnershipForwardingMultipleValueInstruction (SILInstructionKind kind,
87798884 SILDebugLocation loc,
87808885 ValueOwnershipKind ownershipKind)
8781- : MultipleValueInstruction(kind, loc), ownershipKind(ownershipKind) {}
8886+ : MultipleValueInstruction(kind, loc),
8887+ OwnershipForwardingInst (kind, ownershipKind) {
8888+ assert (classof (kind) && " Missing subclass from classof?!" );
8889+ }
87828890
8783- // / Returns the preferred ownership kind of this multiple value instruction.
8784- ValueOwnershipKind getOwnershipKind () const { return ownershipKind; }
8785- void setOwnershipKind (ValueOwnershipKind newOwnershipKind) {
8786- ownershipKind = newOwnershipKind;
8891+ static bool classof (const SILNode *n) {
8892+ if (auto *i = dyn_cast<SILInstruction>(n))
8893+ return classof (i);
8894+ return false ;
8895+ }
8896+
8897+ static bool classof (const SILInstruction *i) { return classof (i->getKind ()); }
8898+
8899+ static bool classof (SILInstructionKind kind) {
8900+ switch (kind) {
8901+ case SILInstructionKind::DestructureTupleInst:
8902+ case SILInstructionKind::DestructureStructInst:
8903+ return true ;
8904+ default :
8905+ return false ;
8906+ }
87878907 }
87888908};
87898909
@@ -8953,6 +9073,22 @@ inline bool Operand::isTypeDependent() const {
89539073 return getUser ()->isTypeDependentOperand (*this );
89549074}
89559075
9076+ inline bool OwnershipForwardingInst::classof (const SILInstruction *inst) {
9077+ return OwnershipForwardingSingleValueInst::classof (inst) ||
9078+ OwnershipForwardingTermInst::classof (inst) ||
9079+ OwnershipForwardingConversionInst::classof (inst) ||
9080+ OwnershipForwardingSelectEnumInstBase::classof (inst) ||
9081+ OwnershipForwardingMultipleValueInstruction::classof (inst);
9082+ }
9083+
9084+ inline bool OwnershipForwardingInst::classof (SILInstructionKind kind) {
9085+ return OwnershipForwardingSingleValueInst::classof (kind) ||
9086+ OwnershipForwardingTermInst::classof (kind) ||
9087+ OwnershipForwardingConversionInst::classof (kind) ||
9088+ OwnershipForwardingSelectEnumInstBase::classof (kind) ||
9089+ OwnershipForwardingMultipleValueInstruction::classof (kind);
9090+ }
9091+
89569092} // end swift namespace
89579093
89589094// ===----------------------------------------------------------------------===//
0 commit comments