@@ -812,6 +812,10 @@ class SILInstruction : public llvm::ilist_node<SILInstruction> {
812
812
813
813
// / This is supportable but usually suggests a logic mistake.
814
814
static bool classof (const ValueBase *) = delete;
815
+
816
+ protected:
817
+ unsigned getCachedFieldIndex (NominalTypeDecl *decl, VarDecl *property);
818
+ unsigned getCachedCaseIndex (EnumElementDecl *enumElement);
815
819
};
816
820
817
821
inline SILNodePointer::SILNodePointer (const SILInstruction *inst) :
@@ -6010,6 +6014,7 @@ class EnumInst
6010
6014
: public InstructionBase<SILInstructionKind::EnumInst,
6011
6015
FirstArgOwnershipForwardingSingleValueInst> {
6012
6016
friend SILBuilder;
6017
+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
6013
6018
6014
6019
Optional<FixedOperandList<1 >> OptionalOperand;
6015
6020
EnumElementDecl *Element;
@@ -6019,6 +6024,8 @@ class EnumInst
6019
6024
ValueOwnershipKind forwardingOwnershipKind)
6020
6025
: InstructionBase(DebugLoc, ResultTy, forwardingOwnershipKind),
6021
6026
Element (Element) {
6027
+ SILNode::Bits.EnumInst .CaseIndex = InvalidCaseIndex;
6028
+
6022
6029
if (Operand) {
6023
6030
OptionalOperand.emplace (this , Operand);
6024
6031
}
@@ -6027,6 +6034,16 @@ class EnumInst
6027
6034
public:
6028
6035
EnumElementDecl *getElement () const { return Element; }
6029
6036
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
+
6030
6047
bool hasOperand () const { return OptionalOperand.hasValue (); }
6031
6048
SILValue getOperand () const { return OptionalOperand->asValueArray ()[0 ]; }
6032
6049
@@ -6048,6 +6065,7 @@ class UncheckedEnumDataInst
6048
6065
: public UnaryInstructionBase<SILInstructionKind::UncheckedEnumDataInst,
6049
6066
FirstArgOwnershipForwardingSingleValueInst> {
6050
6067
friend SILBuilder;
6068
+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
6051
6069
6052
6070
EnumElementDecl *Element;
6053
6071
@@ -6056,11 +6074,23 @@ class UncheckedEnumDataInst
6056
6074
ValueOwnershipKind forwardingOwnershipKind)
6057
6075
: UnaryInstructionBase(DebugLoc, Operand, ResultTy,
6058
6076
forwardingOwnershipKind),
6059
- Element (Element) {}
6077
+ Element (Element) {
6078
+ SILNode::Bits.UncheckedEnumDataInst .CaseIndex = InvalidCaseIndex;
6079
+ }
6060
6080
6061
6081
public:
6062
6082
EnumElementDecl *getElement () const { return Element; }
6063
6083
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
+
6064
6094
EnumDecl *getEnumDecl () const {
6065
6095
auto *E = getOperand ()->getType ().getEnumOrBoundGenericEnum ();
6066
6096
assert (E && " Operand of unchecked_enum_data must be of enum type" );
@@ -6086,15 +6116,28 @@ class InitEnumDataAddrInst
6086
6116
SingleValueInstruction>
6087
6117
{
6088
6118
friend SILBuilder;
6119
+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
6089
6120
6090
6121
EnumElementDecl *Element;
6091
6122
6092
6123
InitEnumDataAddrInst (SILDebugLocation DebugLoc, SILValue Operand,
6093
6124
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
+ }
6095
6128
6096
6129
public:
6097
6130
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
+ }
6098
6141
};
6099
6142
6100
6143
// / InjectEnumAddrInst - Tags an enum as containing a case. The data for
@@ -6104,15 +6147,28 @@ class InjectEnumAddrInst
6104
6147
NonValueInstruction>
6105
6148
{
6106
6149
friend SILBuilder;
6150
+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
6107
6151
6108
6152
EnumElementDecl *Element;
6109
6153
6110
6154
InjectEnumAddrInst (SILDebugLocation DebugLoc, SILValue Operand,
6111
6155
EnumElementDecl *Element)
6112
- : UnaryInstructionBase(DebugLoc, Operand), Element(Element) {}
6156
+ : UnaryInstructionBase(DebugLoc, Operand), Element(Element) {
6157
+ SILNode::Bits.InjectEnumAddrInst .CaseIndex = InvalidCaseIndex;
6158
+ }
6113
6159
6114
6160
public:
6115
6161
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
+ }
6116
6172
};
6117
6173
6118
6174
// / Invalidate an enum value and take ownership of its payload data
@@ -6122,34 +6178,35 @@ class UncheckedTakeEnumDataAddrInst
6122
6178
SingleValueInstruction>
6123
6179
{
6124
6180
friend SILBuilder;
6181
+ enum : unsigned { InvalidCaseIndex = ~unsigned (0 ) };
6125
6182
6126
6183
EnumElementDecl *Element;
6127
6184
6128
6185
UncheckedTakeEnumDataAddrInst (SILDebugLocation DebugLoc, SILValue Operand,
6129
6186
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
+ }
6131
6190
6132
6191
public:
6133
6192
EnumElementDecl *getElement () const { return Element; }
6134
6193
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
+
6135
6204
EnumDecl *getEnumDecl () const {
6136
6205
auto *E = getOperand ()->getType ().getEnumOrBoundGenericEnum ();
6137
6206
assert (E && " Operand of unchecked_take_enum_data_addr must be of enum"
6138
6207
" type" );
6139
6208
return E;
6140
6209
}
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
- }
6153
6210
};
6154
6211
6155
6212
// Abstract base class of all select instructions like select_enum,
@@ -6520,19 +6577,6 @@ class TupleElementAddrInst
6520
6577
}
6521
6578
};
6522
6579
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
-
6536
6580
unsigned getNumFieldsInNominal (NominalTypeDecl *decl);
6537
6581
6538
6582
// / Get the property for a struct or class by its unique index, or nullptr if
@@ -6579,12 +6623,14 @@ class FieldIndexCacheBase : public ParentTy {
6579
6623
6580
6624
VarDecl *getField () const { return field; }
6581
6625
6582
- unsigned getFieldIndex () const {
6626
+ unsigned getFieldIndex () {
6583
6627
unsigned idx = SILNode::Bits.FieldIndexCacheBase .FieldIndex ;
6584
6628
if (idx != InvalidFieldIndex)
6585
6629
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;
6588
6634
}
6589
6635
6590
6636
NominalTypeDecl *getParentDecl () const {
@@ -6600,13 +6646,6 @@ class FieldIndexCacheBase : public ParentTy {
6600
6646
kind == SILNodeKind::StructElementAddrInst ||
6601
6647
kind == SILNodeKind::RefElementAddrInst;
6602
6648
}
6603
-
6604
- private:
6605
- unsigned cacheFieldIndex () {
6606
- unsigned index = swift::getFieldIndex (getParentDecl (), getField ());
6607
- SILNode::Bits.FieldIndexCacheBase .FieldIndex = index;
6608
- return index;
6609
- }
6610
6649
};
6611
6650
6612
6651
// / Extract a physical, fragile field out of a value of struct type.
0 commit comments