@@ -812,6 +812,10 @@ class SILInstruction : public llvm::ilist_node<SILInstruction> {
812812
813813 // / This is supportable but usually suggests a logic mistake.
814814 static bool classof (const ValueBase *) = delete;
815+
816+ protected:
817+ unsigned getCachedFieldIndex (NominalTypeDecl *decl, VarDecl *property);
818+ unsigned getCachedCaseIndex (EnumElementDecl *enumElement);
815819};
816820
817821inline SILNodePointer::SILNodePointer (const SILInstruction *inst) :
@@ -6010,6 +6014,7 @@ class EnumInst
60106014 : public InstructionBase<SILInstructionKind::EnumInst,
60116015 FirstArgOwnershipForwardingSingleValueInst> {
60126016 friend SILBuilder;
6017+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
60136018
60146019 Optional<FixedOperandList<1 >> OptionalOperand;
60156020 EnumElementDecl *Element;
@@ -6019,6 +6024,8 @@ class EnumInst
60196024 ValueOwnershipKind forwardingOwnershipKind)
60206025 : InstructionBase(DebugLoc, ResultTy, forwardingOwnershipKind),
60216026 Element (Element) {
6027+ SILNode::Bits.EnumInst .CaseIndex = InvalidCaseIndex;
6028+
60226029 if (Operand) {
60236030 OptionalOperand.emplace (this , Operand);
60246031 }
@@ -6027,6 +6034,16 @@ class EnumInst
60276034public:
60286035 EnumElementDecl *getElement () const { return Element; }
60296036
6037+ unsigned getCaseIndex () {
6038+ unsigned idx = SILNode::Bits.EnumInst .CaseIndex ;
6039+ if (idx != InvalidCaseIndex)
6040+ return idx;
6041+
6042+ unsigned index = getCachedCaseIndex (getElement ());
6043+ SILNode::Bits.EnumInst .CaseIndex = index;
6044+ return index;
6045+ }
6046+
60306047 bool hasOperand () const { return OptionalOperand.hasValue (); }
60316048 SILValue getOperand () const { return OptionalOperand->asValueArray ()[0 ]; }
60326049
@@ -6048,6 +6065,7 @@ class UncheckedEnumDataInst
60486065 : public UnaryInstructionBase<SILInstructionKind::UncheckedEnumDataInst,
60496066 FirstArgOwnershipForwardingSingleValueInst> {
60506067 friend SILBuilder;
6068+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
60516069
60526070 EnumElementDecl *Element;
60536071
@@ -6056,11 +6074,23 @@ class UncheckedEnumDataInst
60566074 ValueOwnershipKind forwardingOwnershipKind)
60576075 : UnaryInstructionBase(DebugLoc, Operand, ResultTy,
60586076 forwardingOwnershipKind),
6059- Element (Element) {}
6077+ Element (Element) {
6078+ SILNode::Bits.UncheckedEnumDataInst .CaseIndex = InvalidCaseIndex;
6079+ }
60606080
60616081public:
60626082 EnumElementDecl *getElement () const { return Element; }
60636083
6084+ unsigned getCaseIndex () {
6085+ unsigned idx = SILNode::Bits.UncheckedEnumDataInst .CaseIndex ;
6086+ if (idx != InvalidCaseIndex)
6087+ return idx;
6088+
6089+ unsigned index = getCachedCaseIndex (getElement ());
6090+ SILNode::Bits.UncheckedEnumDataInst .CaseIndex = index;
6091+ return index;
6092+ }
6093+
60646094 EnumDecl *getEnumDecl () const {
60656095 auto *E = getOperand ()->getType ().getEnumOrBoundGenericEnum ();
60666096 assert (E && " Operand of unchecked_enum_data must be of enum type" );
@@ -6086,15 +6116,28 @@ class InitEnumDataAddrInst
60866116 SingleValueInstruction>
60876117{
60886118 friend SILBuilder;
6119+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
60896120
60906121 EnumElementDecl *Element;
60916122
60926123 InitEnumDataAddrInst (SILDebugLocation DebugLoc, SILValue Operand,
60936124 EnumElementDecl *Element, SILType ResultTy)
6094- : UnaryInstructionBase(DebugLoc, Operand, ResultTy), Element(Element) {}
6125+ : UnaryInstructionBase(DebugLoc, Operand, ResultTy), Element(Element) {
6126+ SILNode::Bits.InitEnumDataAddrInst .CaseIndex = InvalidCaseIndex;
6127+ }
60956128
60966129public:
60976130 EnumElementDecl *getElement () const { return Element; }
6131+
6132+ unsigned getCaseIndex () {
6133+ unsigned idx = SILNode::Bits.InitEnumDataAddrInst .CaseIndex ;
6134+ if (idx != InvalidCaseIndex)
6135+ return idx;
6136+
6137+ unsigned index = getCachedCaseIndex (getElement ());
6138+ SILNode::Bits.InitEnumDataAddrInst .CaseIndex = index;
6139+ return index;
6140+ }
60986141};
60996142
61006143// / InjectEnumAddrInst - Tags an enum as containing a case. The data for
@@ -6104,15 +6147,28 @@ class InjectEnumAddrInst
61046147 NonValueInstruction>
61056148{
61066149 friend SILBuilder;
6150+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
61076151
61086152 EnumElementDecl *Element;
61096153
61106154 InjectEnumAddrInst (SILDebugLocation DebugLoc, SILValue Operand,
61116155 EnumElementDecl *Element)
6112- : UnaryInstructionBase(DebugLoc, Operand), Element(Element) {}
6156+ : UnaryInstructionBase(DebugLoc, Operand), Element(Element) {
6157+ SILNode::Bits.InjectEnumAddrInst .CaseIndex = InvalidCaseIndex;
6158+ }
61136159
61146160public:
61156161 EnumElementDecl *getElement () const { return Element; }
6162+
6163+ unsigned getCaseIndex () {
6164+ unsigned idx = SILNode::Bits.InjectEnumAddrInst .CaseIndex ;
6165+ if (idx != InvalidCaseIndex)
6166+ return idx;
6167+
6168+ unsigned index = getCachedCaseIndex (getElement ());
6169+ SILNode::Bits.InjectEnumAddrInst .CaseIndex = index;
6170+ return index;
6171+ }
61166172};
61176173
61186174// / Invalidate an enum value and take ownership of its payload data
@@ -6122,34 +6178,35 @@ class UncheckedTakeEnumDataAddrInst
61226178 SingleValueInstruction>
61236179{
61246180 friend SILBuilder;
6181+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
61256182
61266183 EnumElementDecl *Element;
61276184
61286185 UncheckedTakeEnumDataAddrInst (SILDebugLocation DebugLoc, SILValue Operand,
61296186 EnumElementDecl *Element, SILType ResultTy)
6130- : UnaryInstructionBase(DebugLoc, Operand, ResultTy), Element(Element) {}
6187+ : UnaryInstructionBase(DebugLoc, Operand, ResultTy), Element(Element) {
6188+ SILNode::Bits.UncheckedTakeEnumDataAddrInst .CaseIndex = InvalidCaseIndex;
6189+ }
61316190
61326191public:
61336192 EnumElementDecl *getElement () const { return Element; }
61346193
6194+ unsigned getCaseIndex () {
6195+ unsigned idx = SILNode::Bits.UncheckedTakeEnumDataAddrInst .CaseIndex ;
6196+ if (idx != InvalidCaseIndex)
6197+ return idx;
6198+
6199+ unsigned index = getCachedCaseIndex (getElement ());
6200+ SILNode::Bits.UncheckedTakeEnumDataAddrInst .CaseIndex = index;
6201+ return index;
6202+ }
6203+
61356204 EnumDecl *getEnumDecl () const {
61366205 auto *E = getOperand ()->getType ().getEnumOrBoundGenericEnum ();
61376206 assert (E && " Operand of unchecked_take_enum_data_addr must be of enum"
61386207 " type" );
61396208 return E;
61406209 }
6141-
6142- unsigned getElementNo () const {
6143- unsigned i = 0 ;
6144- for (EnumElementDecl *E : getEnumDecl ()->getAllElements ()) {
6145- if (E == Element)
6146- return i;
6147- ++i;
6148- }
6149- llvm_unreachable (
6150- " An unchecked_enum_data_addr's enumdecl should have at least "
6151- " on element, the element that is being extracted" );
6152- }
61536210};
61546211
61556212// Abstract base class of all select instructions like select_enum,
@@ -6520,19 +6577,6 @@ class TupleElementAddrInst
65206577 }
65216578};
65226579
6523- // / Get a unique index for a struct or class field in layout order.
6524- // /
6525- // / Precondition: \p decl must be a non-resilient struct or class.
6526- // /
6527- // / Precondition: \p field must be a stored property declared in \p decl,
6528- // / not in a superclass.
6529- // /
6530- // / Postcondition: The returned index is unique across all properties in the
6531- // / object, including properties declared in a superclass.
6532- unsigned getFieldIndex (NominalTypeDecl *decl, VarDecl *property);
6533-
6534- unsigned getCaseIndex (EnumElementDecl *enumElement);
6535-
65366580unsigned getNumFieldsInNominal (NominalTypeDecl *decl);
65376581
65386582// / Get the property for a struct or class by its unique index, or nullptr if
@@ -6579,12 +6623,14 @@ class FieldIndexCacheBase : public ParentTy {
65796623
65806624 VarDecl *getField () const { return field; }
65816625
6582- unsigned getFieldIndex () const {
6626+ unsigned getFieldIndex () {
65836627 unsigned idx = SILNode::Bits.FieldIndexCacheBase .FieldIndex ;
65846628 if (idx != InvalidFieldIndex)
65856629 return idx;
6586-
6587- return const_cast <FieldIndexCacheBase *>(this )->cacheFieldIndex ();
6630+
6631+ idx = ParentTy::getCachedFieldIndex (getParentDecl (), getField ());
6632+ SILNode::Bits.FieldIndexCacheBase .FieldIndex = idx;
6633+ return idx;
65886634 }
65896635
65906636 NominalTypeDecl *getParentDecl () const {
@@ -6600,13 +6646,6 @@ class FieldIndexCacheBase : public ParentTy {
66006646 kind == SILNodeKind::StructElementAddrInst ||
66016647 kind == SILNodeKind::RefElementAddrInst;
66026648 }
6603-
6604- private:
6605- unsigned cacheFieldIndex () {
6606- unsigned index = swift::getFieldIndex (getParentDecl (), getField ());
6607- SILNode::Bits.FieldIndexCacheBase .FieldIndex = index;
6608- return index;
6609- }
66106649};
66116650
66126651// / Extract a physical, fragile field out of a value of struct type.
0 commit comments