Skip to content

Commit fc9a7b7

Browse files
authored
Merge pull request #12057 from rjmccall/sil-nodes
Divide the SIL concepts of values and instructions
2 parents 661be49 + ab3f77b commit fc9a7b7

File tree

200 files changed

+6208
-4995
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

200 files changed

+6208
-4995
lines changed

docs/SIL.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ Here is an example of a ``.sil`` file::
167167
%2 = struct_extract %0 : $Point, #Point.x
168168
%3 = struct_extract %0 : $Point, #Point.y
169169
%4 = apply %1(%2, %3) : $(Double, Double) -> Double
170-
%5 = return %4 : Double
170+
return %4 : Double
171171
}
172172

173173
// Define a SIL vtable. This matches dynamically-dispatched method
@@ -4625,7 +4625,7 @@ unconditional_checked_cast_addr
46254625
sil-type 'in' sil-operand 'to'
46264626
sil-type 'in' sil-operand
46274627

4628-
%1 = unconditional_checked_cast_addr $A in %0 : $*@thick A to $B in $*@thick B
4628+
unconditional_checked_cast_addr $A in %0 : $*@thick A to $B in $*@thick B
46294629
// $A and $B must be both addresses
46304630
// %1 will be of type $*B
46314631
// $A is destroyed during the conversion. There is no implicit copy.

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,8 @@ ERROR(expected_sil_instr_start_of_line,none,
511511
"SIL instructions must be at the start of a line", ())
512512
ERROR(expected_equal_in_sil_instr,none,
513513
"expected '=' in SIL instruction", ())
514+
ERROR(wrong_result_count_in_sil_instr,none,
515+
"wrong number of results for SIL instruction, expected %0", (unsigned))
514516
ERROR(expected_sil_instr_opcode,none,
515517
"expected SIL instruction opcode", ())
516518
ERROR(expected_tok_in_sil_instr,none,

include/swift/Basic/ArrayRefView.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ template <class Orig, class Projected, Projected (&Project)(const Orig &),
2929
class ArrayRefView {
3030
llvm::ArrayRef<Orig> Array;
3131
public:
32+
ArrayRefView() {}
3233
ArrayRefView(llvm::ArrayRef<Orig> array) : Array(array) {}
3334

3435
class iterator {
@@ -111,6 +112,41 @@ class ArrayRefView {
111112
"original array access not enabled for this view");
112113
return Array;
113114
}
115+
116+
friend bool operator==(ArrayRefView lhs, ArrayRefView rhs) {
117+
if (lhs.size() != rhs.size())
118+
return false;
119+
for (auto i : indices(lhs))
120+
if (lhs[i] != rhs[i])
121+
return false;
122+
return true;
123+
}
124+
friend bool operator==(llvm::ArrayRef<Projected> lhs, ArrayRefView rhs) {
125+
if (lhs.size() != rhs.size())
126+
return false;
127+
for (auto i : indices(lhs))
128+
if (lhs[i] != rhs[i])
129+
return false;
130+
return true;
131+
}
132+
friend bool operator==(ArrayRefView lhs, llvm::ArrayRef<Projected> rhs) {
133+
if (lhs.size() != rhs.size())
134+
return false;
135+
for (auto i : indices(lhs))
136+
if (lhs[i] != rhs[i])
137+
return false;
138+
return true;
139+
}
140+
141+
friend bool operator!=(ArrayRefView lhs, ArrayRefView rhs) {
142+
return !(lhs == rhs);
143+
}
144+
friend bool operator!=(llvm::ArrayRef<Projected> lhs, ArrayRefView rhs) {
145+
return !(lhs == rhs);
146+
}
147+
friend bool operator!=(ArrayRefView lhs, llvm::ArrayRef<Projected> rhs) {
148+
return !(lhs == rhs);
149+
}
114150
};
115151

116152
} // end namespace swift

include/swift/Basic/Range.h

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,47 @@ namespace swift {
6363
return result;
6464
}
6565

66-
/// A range of integers. This type behaves roughly like an ArrayRef.
67-
template <class T=unsigned> class IntRange {
68-
static_assert(std::is_integral<T>::value, "T must be an integer type");
66+
template <class T, bool IsEnum = std::is_enum<T>::value>
67+
struct IntRangeTraits;
68+
69+
template <class T>
70+
struct IntRangeTraits<T, /*is enum*/ false> {
71+
static_assert(std::is_integral<T>::value,
72+
"argument type of IntRange is either an integer nor an enum");
73+
using int_type = T;
74+
using difference_type = typename std::make_signed<int_type>::type;
75+
76+
static T addOffset(T value, difference_type quantity) {
77+
return T(difference_type(value) + quantity);
78+
}
79+
static difference_type distance(T begin, T end) {
80+
return difference_type(end) - difference_type(begin);
81+
}
82+
};
83+
84+
template <class T>
85+
struct IntRangeTraits<T, /*is enum*/ true> {
86+
using int_type = typename std::underlying_type<T>::type;
87+
using difference_type = typename std::make_signed<int_type>::type;
88+
89+
static T addOffset(T value, difference_type quantity) {
90+
return T(difference_type(value) + quantity);
91+
}
92+
static difference_type distance(T begin, T end) {
93+
return difference_type(end) - difference_type(begin);
94+
}
95+
};
96+
97+
/// A range of integers or enum values. This type behaves roughly
98+
/// like an ArrayRef.
99+
template <class T = unsigned, class Traits = IntRangeTraits<T>>
100+
class IntRange {
69101
T Begin;
70102
T End;
103+
104+
using int_type = typename Traits::int_type;
105+
using difference_type = typename Traits::difference_type;
106+
71107
public:
72108
IntRange() : Begin(0), End(0) {}
73109
IntRange(T end) : Begin(0), End(end) {}
@@ -87,37 +123,48 @@ template <class T=unsigned> class IntRange {
87123
typedef std::random_access_iterator_tag iterator_category;
88124

89125
T operator*() const { return Value; }
90-
iterator &operator++() { Value++; return *this; }
91-
iterator operator++(int) { return iterator(Value++); }
126+
iterator &operator++() {
127+
return *this += 1;
128+
}
129+
iterator operator++(int) {
130+
auto copy = *this;
131+
*this += 1;
132+
return copy;
133+
}
92134
iterator &operator--() {
93-
Value--;
94-
return *this;
135+
return *this -= 1;
136+
}
137+
iterator operator--(int) {
138+
auto copy = *this;
139+
*this -= 1;
140+
return copy;
95141
}
96-
iterator operator--(int) { return iterator(Value--); }
97142
bool operator==(iterator rhs) { return Value == rhs.Value; }
98143
bool operator!=(iterator rhs) { return Value != rhs.Value; }
99144

100145
iterator &operator+=(difference_type i) {
101-
Value += T(i);
146+
Value = Traits::addOffset(Value, i);
102147
return *this;
103148
}
104149
iterator operator+(difference_type i) const {
105-
return iterator(Value + T(i));
150+
return iterator(Traits::adddOfset(Value, i));
106151
}
107152
friend iterator operator+(difference_type i, iterator base) {
108-
return iterator(base.Value + T(i));
153+
return iterator(Traits::addOffset(base.Value, i));
109154
}
110155
iterator &operator-=(difference_type i) {
111-
Value -= T(i);
156+
Value = Traits::addOffset(Value, -i);
112157
return *this;
113158
}
114159
iterator operator-(difference_type i) const {
115-
return iterator(Value - T(i));
160+
return iterator(Traits::addOffset(Value, -i));
116161
}
117162
difference_type operator-(iterator rhs) const {
118-
return difference_type(Value - rhs.Value);
163+
return Traits::distance(rhs.Value, Value);
164+
}
165+
T operator[](difference_type i) const {
166+
return Traits::addOffset(Value, i);
119167
}
120-
T operator[](difference_type i) const { return Value + T(i); }
121168
bool operator<(iterator rhs) const { return Value < rhs.Value; }
122169
bool operator<=(iterator rhs) const { return Value <= rhs.Value; }
123170
bool operator>(iterator rhs) const { return Value > rhs.Value; }
@@ -134,26 +181,27 @@ template <class T=unsigned> class IntRange {
134181
}
135182

136183
bool empty() const { return Begin == End; }
137-
size_t size() const { return End - Begin; }
184+
size_t size() const { return size_t(Traits::distance(Begin, End)); }
138185
T operator[](size_t i) const {
139186
assert(i < size());
140-
return Begin + i;
187+
return Traits::addOffset(Begin, i);
141188
}
142189
T front() const { assert(!empty()); return Begin; }
143-
T back() const { assert(!empty()); return End - 1; }
190+
T back() const { assert(!empty()); return Traits::addOffset(End, -1); }
144191
IntRange drop_back(size_t length = 1) const {
145192
assert(length <= size());
146-
return IntRange(Begin, End - length);
193+
return IntRange(Begin, Traits::addOffset(End, -length));
147194
}
148195

149196
IntRange slice(size_t start) const {
150197
assert(start <= size());
151-
return IntRange(Begin + start, End);
198+
return IntRange(Traits::addOffset(Begin, start), End);
152199
}
153200
IntRange slice(size_t start, size_t length) const {
154201
assert(start <= size());
155-
return IntRange(Begin + start,
156-
Begin + start + std::min(length, End - (Begin + start)));
202+
auto newBegin = Traits::addOffset(Begin, start);
203+
auto newSize = std::min(length, size_t(Traits::distance(newBegin, End)));
204+
return IntRange(newBegin, Traits::addOffset(newBegin, newSize));
157205
}
158206

159207
bool operator==(IntRange other) const {

include/swift/SIL/DebugUtils.h

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ inline bool onlyHaveDebugUses(SILValue V) {
143143
return NonDebugUses.begin() == NonDebugUses.end();
144144
}
145145

146+
/// Return true if all of the results of the given instruction have no uses
147+
/// except debug instructions.
148+
inline bool onlyHaveDebugUsesOfAllResults(SILInstruction *I) {
149+
for (auto result : I->getResults()) {
150+
if (!onlyHaveDebugUses(result))
151+
return false;
152+
}
153+
return true;
154+
}
155+
146156
/// Returns true if a value (e.g. SILInstruction) has exactly one use which is
147157
/// not a debug instruction.
148158
inline bool hasOneNonDebugUse(SILValue V) {
@@ -169,16 +179,26 @@ inline SILInstruction *getSingleNonDebugUser(SILValue V) {
169179
/// incremented.
170180
inline void eraseFromParentWithDebugInsts(SILInstruction *I,
171181
SILBasicBlock::iterator &InstIter) {
172-
while (!I->use_empty()) {
173-
auto *User = I->use_begin()->getUser();
174-
assert(isDebugInst(User));
175-
if (InstIter != SILBasicBlock::iterator() &&
176-
InstIter != I->getParent()->end() &&
177-
&*InstIter == User) {
178-
InstIter++;
182+
auto results = I->getResults();
183+
184+
bool foundAny;
185+
do {
186+
foundAny = false;
187+
for (auto result : results) {
188+
while (!result->use_empty()) {
189+
foundAny = true;
190+
auto *User = result->use_begin()->getUser();
191+
assert(isDebugInst(User));
192+
if (InstIter != SILBasicBlock::iterator() &&
193+
InstIter != I->getParent()->end() &&
194+
&*InstIter == User) {
195+
InstIter++;
196+
}
197+
User->eraseFromParent();
198+
}
179199
}
180-
User->eraseFromParent();
181-
}
200+
} while (foundAny);
201+
182202
I->eraseFromParent();
183203
}
184204

include/swift/SIL/Notifications.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
namespace swift {
1717

18-
class ValueBase;
18+
class SILNode;
1919

2020
/// A protocol (or interface) for handling value deletion notifications.
2121
///
@@ -29,7 +29,7 @@ struct DeleteNotificationHandler {
2929
virtual ~DeleteNotificationHandler() {}
3030

3131
/// Handle the invalidation message for the value \p Value.
32-
virtual void handleDeleteNotification(swift::ValueBase *Value) { }
32+
virtual void handleDeleteNotification(SILNode *value) { }
3333

3434
/// Returns True if the pass, analysis or other entity wants to receive
3535
/// notifications. This callback is called once when the class is being

include/swift/SIL/PatternMatch.h

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -296,19 +296,24 @@ using m_One = match_integer<1>;
296296
// Unary Instructions
297297
//===----------------------------------------------------------------------===//
298298

299-
template<typename OpMatchTy, ValueKind Kind>
299+
template<typename OpMatchTy, SILInstructionKind Kind>
300300
struct UnaryOp_match {
301301
OpMatchTy OpMatch;
302302

303303
UnaryOp_match(const OpMatchTy &Op) : OpMatch(Op) { }
304304

305-
template<typename OpTy>
306-
bool match(OpTy *V) {
307-
if (V->getKind() != Kind)
305+
bool match(SILNode *node) {
306+
if (node->getKind() != SILNodeKind(Kind))
307+
return false;
308+
309+
return match(cast<SILInstruction>(node));
310+
}
311+
312+
bool match(SILInstruction *I) {
313+
if (I->getKind() != Kind)
308314
return false;
309315

310-
auto *I = dyn_cast<SILInstruction>(V);
311-
if (!I || I->getNumOperands() != 1)
316+
if (I->getNumOperands() != 1)
312317
return false;
313318

314319
return OpMatch.match(I->getOperand(0));
@@ -319,7 +324,7 @@ struct UnaryOp_match {
319324
// further matchers to the operands of the unary operation.
320325
#define UNARY_OP_MATCH_WITH_ARG_MATCHER(Class) \
321326
template <typename Ty> \
322-
UnaryOp_match<Ty, ValueKind::Class> \
327+
UnaryOp_match<Ty, SILInstructionKind::Class> \
323328
m_##Class(const Ty &T) { \
324329
return T; \
325330
}
@@ -393,20 +398,25 @@ UNARY_OP_MATCH_WITH_ARG_MATCHER(ReturnInst)
393398
// Binary Instructions
394399
//===----------------------------------------------------------------------===//
395400

396-
template<typename LHSTy, typename RHSTy, ValueKind Kind>
401+
template<typename LHSTy, typename RHSTy, SILInstructionKind Kind>
397402
struct BinaryOp_match {
398403
LHSTy L;
399404
RHSTy R;
400405

401406
BinaryOp_match(const LHSTy &LHS, const RHSTy &RHS) : L(LHS), R(RHS) {}
402407

403-
template<typename OpTy>
404-
bool match(OpTy *V) {
405-
if (V->getKind() != Kind)
408+
bool match(SILNode *node) {
409+
if (node->getKind() != SILNodeKind(Kind))
410+
return false;
411+
412+
return match(cast<SILInstruction>(node));
413+
}
414+
415+
bool match(SILInstruction *I) {
416+
if (I->getKind() != Kind)
406417
return false;
407418

408-
auto *I = dyn_cast<SILInstruction>(V);
409-
if (!I || I->getNumOperands() != 2)
419+
if (I->getNumOperands() != 2)
410420
return false;
411421

412422
return L.match((ValueBase *)I->getOperand(0)) &&
@@ -415,7 +425,7 @@ struct BinaryOp_match {
415425
};
416426

417427
template <typename LTy, typename RTy>
418-
BinaryOp_match<LTy, RTy, ValueKind::IndexRawPointerInst>
428+
BinaryOp_match<LTy, RTy, SILInstructionKind::IndexRawPointerInst>
419429
m_IndexRawPointerInst(const LTy &Left, const RTy &Right) {
420430
return {Left, Right};
421431
}

0 commit comments

Comments
 (0)