12
12
13
13
#define DEBUG_TYPE " sil-projection"
14
14
#include " swift/SIL/Projection.h"
15
+ #include " swift/Basic/IndexTrie.h"
15
16
#include " swift/Basic/NullablePtr.h"
16
- #include " swift/SIL/SILBuilder.h"
17
- #include " swift/SIL/InstructionUtils.h"
18
17
#include " swift/SIL/DebugUtils.h"
18
+ #include " swift/SIL/InstructionUtils.h"
19
+ #include " swift/SIL/SILBuilder.h"
19
20
#include " swift/SIL/SILUndef.h"
20
21
#include " llvm/ADT/None.h"
21
22
#include " llvm/Support/Debug.h"
@@ -42,22 +43,27 @@ static_assert(std::is_standard_layout<Projection>::value,
42
43
// / Return true if IndexVal is a constant index representable as unsigned
43
44
// / int. We do not support symbolic projections yet, only 32-bit unsigned
44
45
// / integers.
45
- bool swift::getIntegerIndex (SILValue IndexVal, unsigned &IndexConst) {
46
- if (auto *IndexLiteral = dyn_cast<IntegerLiteralInst>(IndexVal)) {
47
- APInt ConstInt = IndexLiteral->getValue ();
48
- // IntegerLiterals are signed.
49
- if (ConstInt.isIntN (32 ) && ConstInt.isNonNegative ()) {
50
- IndexConst = (unsigned )ConstInt.getSExtValue ();
51
- return true ;
52
- }
53
- }
54
- return false ;
46
+ bool swift::getIntegerIndex (SILValue IndexVal, int &IndexConst) {
47
+ auto *IndexLiteral = dyn_cast<IntegerLiteralInst>(IndexVal);
48
+ if (!IndexLiteral)
49
+ return false ;
50
+
51
+ APInt ConstInt = IndexLiteral->getValue ();
52
+ // Reserve 1 bit for encoding. See AccessPath::Index.
53
+ if (!ConstInt.isSignedIntN (31 ))
54
+ return false ;
55
+
56
+ IndexConst = ConstInt.getSExtValue ();
57
+ assert (((IndexConst << 1 ) >> 1 ) == IndexConst);
58
+ return true ;
55
59
}
56
60
57
61
// ===----------------------------------------------------------------------===//
58
62
// Projection
59
63
// ===----------------------------------------------------------------------===//
60
64
65
+ constexpr int ProjectionIndex::TailIndex;
66
+
61
67
Projection::Projection (SingleValueInstruction *I) : Value() {
62
68
if (!I)
63
69
return ;
@@ -72,21 +78,21 @@ Projection::Projection(SingleValueInstruction *I) : Value() {
72
78
auto *SEAI = cast<StructElementAddrInst>(I);
73
79
Value = ValueTy (ProjectionKind::Struct, SEAI->getFieldIndex ());
74
80
assert (getKind () == ProjectionKind::Struct);
75
- assert (getIndex () == SEAI->getFieldIndex ());
81
+ assert (getIndex () == int ( SEAI->getFieldIndex () ));
76
82
break ;
77
83
}
78
84
case SILInstructionKind::StructExtractInst: {
79
85
auto *SEI = cast<StructExtractInst>(I);
80
86
Value = ValueTy (ProjectionKind::Struct, SEI->getFieldIndex ());
81
87
assert (getKind () == ProjectionKind::Struct);
82
- assert (getIndex () == SEI->getFieldIndex ());
88
+ assert (getIndex () == int ( SEI->getFieldIndex () ));
83
89
break ;
84
90
}
85
91
case SILInstructionKind::RefElementAddrInst: {
86
92
auto *REAI = cast<RefElementAddrInst>(I);
87
93
Value = ValueTy (ProjectionKind::Class, REAI->getFieldIndex ());
88
94
assert (getKind () == ProjectionKind::Class);
89
- assert (getIndex () == REAI->getFieldIndex ());
95
+ assert (getIndex () == int ( REAI->getFieldIndex () ));
90
96
break ;
91
97
}
92
98
case SILInstructionKind::RefTailAddrInst: {
@@ -108,28 +114,28 @@ Projection::Projection(SingleValueInstruction *I) : Value() {
108
114
auto *TEI = cast<TupleExtractInst>(I);
109
115
Value = ValueTy (ProjectionKind::Tuple, TEI->getFieldIndex ());
110
116
assert (getKind () == ProjectionKind::Tuple);
111
- assert (getIndex () == TEI->getFieldIndex ());
117
+ assert (getIndex () == int ( TEI->getFieldIndex () ));
112
118
break ;
113
119
}
114
120
case SILInstructionKind::TupleElementAddrInst: {
115
121
auto *TEAI = cast<TupleElementAddrInst>(I);
116
122
Value = ValueTy (ProjectionKind::Tuple, TEAI->getFieldIndex ());
117
123
assert (getKind () == ProjectionKind::Tuple);
118
- assert (getIndex () == TEAI->getFieldIndex ());
124
+ assert (getIndex () == int ( TEAI->getFieldIndex () ));
119
125
break ;
120
126
}
121
127
case SILInstructionKind::UncheckedEnumDataInst: {
122
128
auto *UEDI = cast<UncheckedEnumDataInst>(I);
123
129
Value = ValueTy (ProjectionKind::Enum, UEDI->getElementNo ());
124
130
assert (getKind () == ProjectionKind::Enum);
125
- assert (getIndex () == UEDI->getElementNo ());
131
+ assert (getIndex () == int ( UEDI->getElementNo () ));
126
132
break ;
127
133
}
128
134
case SILInstructionKind::UncheckedTakeEnumDataAddrInst: {
129
135
auto *UTEDAI = cast<UncheckedTakeEnumDataAddrInst>(I);
130
136
Value = ValueTy (ProjectionKind::Enum, UTEDAI->getElementNo ());
131
137
assert (getKind () == ProjectionKind::Enum);
132
- assert (getIndex () == UTEDAI->getElementNo ());
138
+ assert (getIndex () == int ( UTEDAI->getElementNo () ));
133
139
break ;
134
140
}
135
141
case SILInstructionKind::IndexAddrInst: {
@@ -138,9 +144,10 @@ Projection::Projection(SingleValueInstruction *I) : Value() {
138
144
// updated and a MaxLargeIndex will need to be used here. Currently we
139
145
// represent large Indexes using a 64 bit integer, so we don't need to mess
140
146
// with anything.
141
- unsigned NewIndex = 0 ;
147
+ int NewIndex = 0 ;
142
148
auto *IAI = cast<IndexAddrInst>(I);
143
- if (getIntegerIndex (IAI->getIndex (), NewIndex)) {
149
+ // TODO: handle negative indices
150
+ if (getIntegerIndex (IAI->getIndex (), NewIndex) && NewIndex >= 0 ) {
144
151
Value = ValueTy (ProjectionKind::Index, NewIndex);
145
152
assert (getKind () == ProjectionKind::Index);
146
153
assert (getIndex () == NewIndex);
@@ -321,10 +328,6 @@ void Projection::getFirstLevelProjections(
321
328
322
329
if (auto *C = Ty.getClassOrBoundGenericClass ()) {
323
330
unsigned Count = 0 ;
324
- for (auto *superDecl = C->getSuperclassDecl (); superDecl != nullptr ;
325
- superDecl = superDecl->getSuperclassDecl ()) {
326
- Count += superDecl->getStoredProperties ().size ();
327
- }
328
331
for (auto *VDecl : C->getStoredProperties ()) {
329
332
(void ) VDecl;
330
333
Projection P (ProjectionKind::Class, Count++);
0 commit comments