@@ -127,51 +127,6 @@ template<Lattice L> class StackLattice {
127
127
return value;
128
128
}
129
129
130
- // When taking the LUB, we take the LUBs of the elements of each stack
131
- // starting from the top of the stack. So, LUB([b, a], [b', a']) is
132
- // [LUB(b, b'), LUB(a, a')]. If one stack is higher than the other,
133
- // the bottom of the higher stack will be kept, while the LUB of the
134
- // corresponding tops of each stack will be taken. For instance,
135
- // LUB([d, c, b, a], [b', a']) is [d, c, LUB(b, b'), LUB(a, a')].
136
- //
137
- // We start at the top because it makes taking the LUB of stacks with
138
- // different scope easier, as mentioned at the top of the file. It also
139
- // fits with the conception of the stack starting at the top and having
140
- // an infinite bottom, which allows stacks of different height and scope
141
- // to be easily joined.
142
- bool makeLeastUpperBound (const Element& other) noexcept {
143
- // Top element cases, since top elements don't actually have the stack
144
- // value.
145
- if (isTop ()) {
146
- return false ;
147
- } else if (other.isTop ()) {
148
- stackValue.reset ();
149
- return true ;
150
- }
151
-
152
- bool modified = false ;
153
-
154
- // Merge the shorter height stack with the top of the longer height
155
- // stack. We do this by taking the LUB of each pair of matching elements
156
- // from both stacks.
157
- auto otherIt = other.stackValue ->crbegin ();
158
- auto thisIt = stackValue->rbegin ();
159
- for (;
160
- thisIt != stackValue->rend () && otherIt != other.stackValue ->crend ();
161
- ++thisIt, ++otherIt) {
162
- modified |= thisIt->makeLeastUpperBound (*otherIt);
163
- }
164
-
165
- // If the other stack is higher, append the bottom of it to our current
166
- // stack.
167
- for (; otherIt != other.stackValue ->crend (); ++otherIt) {
168
- stackValue->push_front (*otherIt);
169
- modified = true ;
170
- }
171
-
172
- return modified;
173
- }
174
-
175
130
void print (std::ostream& os) {
176
131
if (isTop ()) {
177
132
os << " TOP STACK" << std::endl;
@@ -188,6 +143,8 @@ template<Lattice L> class StackLattice {
188
143
friend StackLattice;
189
144
};
190
145
146
+ Element getBottom () const noexcept { return Element{}; }
147
+
191
148
// Like in computing the LUB, we compare the tops of the two stacks, as it
192
149
// handles the case of stacks of different scopes. Comparisons are done by
193
150
// element starting from the top.
@@ -258,7 +215,50 @@ template<Lattice L> class StackLattice {
258
215
}
259
216
}
260
217
261
- Element getBottom () const noexcept { return Element{}; }
218
+ // When taking the LUB, we take the LUBs of the elements of each stack
219
+ // starting from the top of the stack. So, LUB([b, a], [b', a']) is
220
+ // [LUB(b, b'), LUB(a, a')]. If one stack is higher than the other,
221
+ // the bottom of the higher stack will be kept, while the LUB of the
222
+ // corresponding tops of each stack will be taken. For instance,
223
+ // LUB([d, c, b, a], [b', a']) is [d, c, LUB(b, b'), LUB(a, a')].
224
+ //
225
+ // We start at the top because it makes taking the LUB of stacks with
226
+ // different scope easier, as mentioned at the top of the file. It also
227
+ // fits with the conception of the stack starting at the top and having
228
+ // an infinite bottom, which allows stacks of different height and scope
229
+ // to be easily joined.
230
+ bool join (Element& self, const Element& other) const noexcept {
231
+ // Top element cases, since top elements don't actually have the stack
232
+ // value.
233
+ if (self.isTop ()) {
234
+ return false ;
235
+ } else if (other.isTop ()) {
236
+ self.stackValue .reset ();
237
+ return true ;
238
+ }
239
+
240
+ bool modified = false ;
241
+
242
+ // Merge the shorter height stack with the top of the longer height
243
+ // stack. We do this by taking the LUB of each pair of matching elements
244
+ // from both stacks.
245
+ auto selfIt = self.stackValue ->rbegin ();
246
+ auto otherIt = other.stackValue ->crbegin ();
247
+ for (; selfIt != self.stackValue ->rend () &&
248
+ otherIt != other.stackValue ->crend ();
249
+ ++selfIt, ++otherIt) {
250
+ modified |= lattice.join (*selfIt, *otherIt);
251
+ }
252
+
253
+ // If the other stack is higher, append the bottom of it to our current
254
+ // stack.
255
+ for (; otherIt != other.stackValue ->crend (); ++otherIt) {
256
+ self.stackValue ->push_front (*otherIt);
257
+ modified = true ;
258
+ }
259
+
260
+ return modified;
261
+ }
262
262
};
263
263
264
264
} // namespace wasm::analysis
0 commit comments