Skip to content

Commit ea0da3f

Browse files
authored
Merge pull request #34074 from atrick/make-fieldidx-unique
Change SIL ref_element_addr getFieldNo() to return a unique index.
2 parents 5f92463 + 5ae231e commit ea0da3f

38 files changed

+142
-95
lines changed

include/swift/SIL/PatternMatch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ template <typename LTy> struct tupleextractoperation_ty {
406406

407407
template <typename ITy> bool match(ITy *V) {
408408
if (auto *TEI = dyn_cast<TupleExtractInst>(V)) {
409-
return TEI->getFieldNo() == index &&
409+
return TEI->getFieldIndex() == index &&
410410
L.match((ValueBase *)TEI->getOperand());
411411
}
412412

include/swift/SIL/Projection.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,13 @@ struct ProjectionIndex {
152152
}
153153
case ValueKind::StructElementAddrInst: {
154154
StructElementAddrInst *SEA = cast<StructElementAddrInst>(V);
155-
Index = SEA->getFieldNo();
155+
Index = SEA->getFieldIndex();
156156
Aggregate = SEA->getOperand();
157157
break;
158158
}
159159
case ValueKind::RefElementAddrInst: {
160160
RefElementAddrInst *REA = cast<RefElementAddrInst>(V);
161-
Index = REA->getFieldNo();
161+
Index = REA->getFieldIndex();
162162
Aggregate = REA->getOperand();
163163
break;
164164
}
@@ -177,19 +177,19 @@ struct ProjectionIndex {
177177
}
178178
case ValueKind::TupleElementAddrInst: {
179179
TupleElementAddrInst *TEA = cast<TupleElementAddrInst>(V);
180-
Index = TEA->getFieldNo();
180+
Index = TEA->getFieldIndex();
181181
Aggregate = TEA->getOperand();
182182
break;
183183
}
184184
case ValueKind::StructExtractInst: {
185185
StructExtractInst *SEA = cast<StructExtractInst>(V);
186-
Index = SEA->getFieldNo();
186+
Index = SEA->getFieldIndex();
187187
Aggregate = SEA->getOperand();
188188
break;
189189
}
190190
case ValueKind::TupleExtractInst: {
191191
TupleExtractInst *TEA = cast<TupleExtractInst>(V);
192-
Index = TEA->getFieldNo();
192+
Index = TEA->getFieldIndex();
193193
Aggregate = TEA->getOperand();
194194
break;
195195
}
@@ -302,10 +302,9 @@ class Projection {
302302
assert(isValid());
303303
assert((getKind() == ProjectionKind::Struct ||
304304
getKind() == ProjectionKind::Class));
305-
assert(BaseType.getNominalOrBoundGenericNominal() &&
306-
"This should only be called with a nominal type");
307-
auto *NDecl = BaseType.getNominalOrBoundGenericNominal();
308-
return NDecl->getStoredProperties()[getIndex()];
305+
auto *nominalDecl = BaseType.getNominalOrBoundGenericNominal();
306+
assert(nominalDecl && "This should only be called with a nominal type");
307+
return getIndexedField(nominalDecl, getIndex());
309308
}
310309

311310
EnumElementDecl *getEnumElementDecl(SILType BaseType) const {

include/swift/SIL/SILCloner.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,7 +1946,7 @@ SILCloner<ImplClass>::visitTupleExtractInst(TupleExtractInst *Inst) {
19461946
recordClonedInstruction(
19471947
Inst, getBuilder().createTupleExtract(
19481948
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1949-
Inst->getFieldNo(), getOpType(Inst->getType())));
1949+
Inst->getFieldIndex(), getOpType(Inst->getType())));
19501950
}
19511951

19521952
template<typename ImplClass>
@@ -1956,7 +1956,7 @@ SILCloner<ImplClass>::visitTupleElementAddrInst(TupleElementAddrInst *Inst) {
19561956
recordClonedInstruction(
19571957
Inst, getBuilder().createTupleElementAddr(
19581958
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1959-
Inst->getFieldNo(), getOpType(Inst->getType())));
1959+
Inst->getFieldIndex(), getOpType(Inst->getType())));
19601960
}
19611961

19621962
template<typename ImplClass>

include/swift/SIL/SILInstruction.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5715,7 +5715,7 @@ class TupleExtractInst
57155715
}
57165716

57175717
public:
5718-
unsigned getFieldNo() const {
5718+
unsigned getFieldIndex() const {
57195719
return SILInstruction::Bits.TupleExtractInst.FieldNo;
57205720
}
57215721

@@ -5747,7 +5747,7 @@ class TupleElementAddrInst
57475747
}
57485748

57495749
public:
5750-
unsigned getFieldNo() const {
5750+
unsigned getFieldIndex() const {
57515751
return SILInstruction::Bits.TupleElementAddrInst.FieldNo;
57525752
}
57535753

@@ -5757,6 +5757,26 @@ class TupleElementAddrInst
57575757
}
57585758
};
57595759

5760+
/// Get a unique index for a struct or class field in layout order.
5761+
///
5762+
/// Precondition: \p decl must be a non-resilient struct or class.
5763+
///
5764+
/// Precondition: \p field must be a stored property declared in \p decl,
5765+
/// not in a superclass.
5766+
///
5767+
/// Postcondition: The returned index is unique across all properties in the
5768+
/// object, including properties declared in a superclass.
5769+
unsigned getFieldIndex(NominalTypeDecl *decl, VarDecl *property);
5770+
5771+
/// Get the property for a struct or class by its unique index.
5772+
///
5773+
/// Precondition: \p decl must be a non-resilient struct or class.
5774+
///
5775+
/// Precondition: \p index must be the index of a stored property
5776+
/// (as returned by getFieldIndex()) which is declared
5777+
/// in \p decl, not in a superclass.
5778+
VarDecl *getIndexedField(NominalTypeDecl *decl, unsigned index);
5779+
57605780
/// A common base for instructions that require a cached field index.
57615781
///
57625782
/// "Field" is a term used here to refer to the ordered, accessible stored
@@ -5791,8 +5811,7 @@ class FieldIndexCacheBase : public SingleValueInstruction {
57915811

57925812
VarDecl *getField() const { return field; }
57935813

5794-
// FIXME: this should be called getFieldIndex().
5795-
unsigned getFieldNo() const {
5814+
unsigned getFieldIndex() const {
57965815
unsigned idx = SILInstruction::Bits.FieldIndexCacheBase.FieldIndex;
57975816
if (idx != InvalidFieldIndex)
57985817
return idx;

lib/IRGen/IRGenSIL.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3787,7 +3787,7 @@ void IRGenSILFunction::visitTupleExtractInst(swift::TupleExtractInst *i) {
37873787
projectTupleElementFromExplosion(*this,
37883788
baseType,
37893789
fullTuple,
3790-
i->getFieldNo(),
3790+
i->getFieldIndex(),
37913791
output);
37923792
(void)fullTuple.claimAll();
37933793
setLoweredExplosion(i, output);
@@ -3799,7 +3799,7 @@ void IRGenSILFunction::visitTupleElementAddrInst(swift::TupleElementAddrInst *i)
37993799
SILType baseType = i->getOperand()->getType();
38003800

38013801
Address field = projectTupleElementAddress(*this, base, baseType,
3802-
i->getFieldNo());
3802+
i->getFieldIndex());
38033803
setLoweredAddress(i, field);
38043804
}
38053805

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ BuiltinInst *SILGlobalVariable::getOffsetSubtract(const TupleExtractInst *TE,
8585
// Match the pattern:
8686
// tuple_extract(usub_with_overflow(x, integer_literal, integer_literal 0), 0)
8787

88-
if (TE->getFieldNo() != 0)
88+
if (TE->getFieldIndex() != 0)
8989
return nullptr;
9090

9191
auto *BI = dyn_cast<BuiltinInst>(TE->getOperand());

lib/SIL/IR/SILInstruction.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ namespace {
579579
auto *X = cast<TupleExtractInst>(LHS);
580580
if (X->getTupleType() != RHS->getTupleType())
581581
return false;
582-
if (X->getFieldNo() != RHS->getFieldNo())
582+
if (X->getFieldIndex() != RHS->getFieldIndex())
583583
return false;
584584
return true;
585585
}
@@ -590,7 +590,7 @@ namespace {
590590
auto *X = cast<TupleElementAddrInst>(LHS);
591591
if (X->getTupleType() != RHS->getTupleType())
592592
return false;
593-
if (X->getFieldNo() != RHS->getFieldNo())
593+
if (X->getFieldIndex() != RHS->getFieldIndex())
594594
return false;
595595
return true;
596596
}

lib/SIL/IR/SILInstructions.cpp

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,7 +1258,7 @@ bool TupleExtractInst::isTrivialEltOfOneRCIDTuple() const {
12581258
// parent tuple has only one non-trivial field.
12591259
bool FoundNonTrivialField = false;
12601260
SILType OpTy = getOperand()->getType();
1261-
unsigned FieldNo = getFieldNo();
1261+
unsigned FieldNo = getFieldIndex();
12621262

12631263
// For each element index of the tuple...
12641264
for (unsigned i = 0, e = getNumTupleElts(); i != e; ++i) {
@@ -1300,7 +1300,7 @@ bool TupleExtractInst::isEltOnlyNonTrivialElt() const {
13001300
// Ok, we know that the elt we are extracting is non-trivial. Make sure that
13011301
// we have no other non-trivial elts.
13021302
SILType OpTy = getOperand()->getType();
1303-
unsigned FieldNo = getFieldNo();
1303+
unsigned FieldNo = getFieldIndex();
13041304

13051305
// For each element index of the tuple...
13061306
for (unsigned i = 0, e = getNumTupleElts(); i != e; ++i) {
@@ -1323,18 +1323,43 @@ bool TupleExtractInst::isEltOnlyNonTrivialElt() const {
13231323
return true;
13241324
}
13251325

1326-
unsigned FieldIndexCacheBase::cacheFieldIndex() {
1327-
unsigned i = 0;
1328-
for (VarDecl *property : getParentDecl()->getStoredProperties()) {
1326+
/// Get a unique index for a struct or class field in layout order.
1327+
unsigned swift::getFieldIndex(NominalTypeDecl *decl, VarDecl *field) {
1328+
unsigned index = 0;
1329+
if (auto *classDecl = dyn_cast<ClassDecl>(decl)) {
1330+
for (auto *superDecl = classDecl->getSuperclassDecl(); superDecl != nullptr;
1331+
superDecl = superDecl->getSuperclassDecl()) {
1332+
index += superDecl->getStoredProperties().size();
1333+
}
1334+
}
1335+
for (VarDecl *property : decl->getStoredProperties()) {
13291336
if (field == property) {
1330-
SILInstruction::Bits.FieldIndexCacheBase.FieldIndex = i;
1331-
return i;
1337+
return index;
13321338
}
1333-
++i;
1339+
++index;
13341340
}
13351341
llvm_unreachable("The field decl for a struct_extract, struct_element_addr, "
1336-
"or ref_element_addr must be an accessible stored property "
1337-
"of the operand's type");
1342+
"or ref_element_addr must be an accessible stored "
1343+
"property of the operand type");
1344+
}
1345+
1346+
/// Get the property for a struct or class by its unique index.
1347+
VarDecl *swift::getIndexedField(NominalTypeDecl *decl, unsigned index) {
1348+
if (auto *classDecl = dyn_cast<ClassDecl>(decl)) {
1349+
for (auto *superDecl = classDecl->getSuperclassDecl(); superDecl != nullptr;
1350+
superDecl = superDecl->getSuperclassDecl()) {
1351+
assert(index >= superDecl->getStoredProperties().size()
1352+
&& "field index cannot refer to a superclass field");
1353+
index -= superDecl->getStoredProperties().size();
1354+
}
1355+
}
1356+
return decl->getStoredProperties()[index];
1357+
}
1358+
1359+
unsigned FieldIndexCacheBase::cacheFieldIndex() {
1360+
unsigned index = ::getFieldIndex(getParentDecl(), getField());
1361+
SILInstruction::Bits.FieldIndexCacheBase.FieldIndex = index;
1362+
return index;
13381363
}
13391364

13401365
// FIXME: this should be cached during cacheFieldIndex().

lib/SIL/IR/SILPrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,11 +1773,11 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
17731773
}
17741774

17751775
void visitTupleExtractInst(TupleExtractInst *EI) {
1776-
*this << getIDAndType(EI->getOperand()) << ", " << EI->getFieldNo();
1776+
*this << getIDAndType(EI->getOperand()) << ", " << EI->getFieldIndex();
17771777
}
17781778

17791779
void visitTupleElementAddrInst(TupleElementAddrInst *EI) {
1780-
*this << getIDAndType(EI->getOperand()) << ", " << EI->getFieldNo();
1780+
*this << getIDAndType(EI->getOperand()) << ", " << EI->getFieldIndex();
17811781
}
17821782
void visitStructExtractInst(StructExtractInst *EI) {
17831783
*this << getIDAndType(EI->getOperand()) << ", #";

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ AccessedStorage::AccessedStorage(SILValue base, Kind kind) {
118118
// conservative given that classes are not "uniquely identified".
119119
auto *REA = cast<RefElementAddrInst>(base);
120120
value = stripBorrow(REA->getOperand());
121-
setElementIndex(REA->getFieldNo());
121+
setElementIndex(REA->getFieldIndex());
122122
break;
123123
}
124124
case Tail: {
@@ -156,7 +156,7 @@ const ValueDecl *AccessedStorage::getDecl() const {
156156

157157
case Class: {
158158
auto *decl = getObject()->getType().getNominalOrBoundGenericNominal();
159-
return decl->getStoredProperties()[getPropertyIndex()];
159+
return getIndexedField(decl, getPropertyIndex());
160160
}
161161
case Tail:
162162
return nullptr;

0 commit comments

Comments
 (0)