OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ | 5 #ifndef VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ |
6 #define VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ | 6 #define VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ |
7 | 7 |
8 #include "vm/flow_graph.h" | 8 #include "vm/flow_graph.h" |
9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
10 | 10 |
11 namespace dart { | 11 namespace dart { |
12 | 12 |
13 class RangeBoundary : public ValueObject { | 13 class RangeBoundary : public ValueObject { |
14 public: | 14 public: |
15 enum Kind { | 15 enum Kind { |
16 kUnknown, | 16 kUnknown, |
17 kNegativeInfinity, | 17 kNegativeInfinity, |
18 kPositiveInfinity, | 18 kPositiveInfinity, |
19 kSymbol, | 19 kSymbol, |
20 kConstant, | 20 kConstant, |
21 }; | 21 }; |
22 | 22 |
23 enum RangeSize { | 23 enum RangeSize { |
24 kRangeBoundarySmi, | 24 kRangeBoundarySmi, |
25 kRangeBoundaryInt32, | |
25 kRangeBoundaryInt64, | 26 kRangeBoundaryInt64, |
26 }; | 27 }; |
27 | 28 |
28 RangeBoundary() : kind_(kUnknown), value_(0), offset_(0) { } | 29 RangeBoundary() : kind_(kUnknown), value_(0), offset_(0) { } |
29 | 30 |
30 RangeBoundary(const RangeBoundary& other) | 31 RangeBoundary(const RangeBoundary& other) |
31 : ValueObject(), | 32 : ValueObject(), |
32 kind_(other.kind_), | 33 kind_(other.kind_), |
33 value_(other.value_), | 34 value_(other.value_), |
34 offset_(other.offset_) { } | 35 offset_(other.offset_) { } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 // Construct a RangeBoundary for the constant MinSmi value. | 68 // Construct a RangeBoundary for the constant MinSmi value. |
68 static RangeBoundary MinSmi() { | 69 static RangeBoundary MinSmi() { |
69 return FromConstant(Smi::kMinValue); | 70 return FromConstant(Smi::kMinValue); |
70 } | 71 } |
71 | 72 |
72 // Construct a RangeBoundary for the constant MaxSmi value. | 73 // Construct a RangeBoundary for the constant MaxSmi value. |
73 static RangeBoundary MaxSmi() { | 74 static RangeBoundary MaxSmi() { |
74 return FromConstant(Smi::kMaxValue); | 75 return FromConstant(Smi::kMaxValue); |
75 } | 76 } |
76 | 77 |
77 // Construct a RangeBoundary for the constant kMin value. | 78 // Construct a RangeBoundary for the constant kMin value. |
78 static RangeBoundary MinConstant() { | 79 static RangeBoundary MinConstant() { |
79 return FromConstant(kMin); | 80 return FromConstant(kMin); |
80 } | 81 } |
81 | 82 |
82 // Construct a RangeBoundary for the constant kMax value. | 83 // Construct a RangeBoundary for the constant kMax value. |
83 static RangeBoundary MaxConstant() { | 84 static RangeBoundary MaxConstant() { |
84 return FromConstant(kMax); | 85 return FromConstant(kMax); |
85 } | 86 } |
86 | 87 |
88 // Construct a RangeBoundary for the constant kMin value. | |
89 static RangeBoundary MinConstant(RangeSize size) { | |
90 switch (size) { | |
91 case kRangeBoundarySmi: | |
92 return FromConstant(Smi::kMinValue); | |
93 case kRangeBoundaryInt32: | |
94 return FromConstant(kMinInt32); | |
95 case kRangeBoundaryInt64: | |
96 return FromConstant(kMinInt64); | |
97 } | |
98 UNREACHABLE(); | |
99 return FromConstant(kMinInt64); | |
100 } | |
101 | |
102 static RangeBoundary MaxConstant(RangeSize size) { | |
103 switch (size) { | |
104 case kRangeBoundarySmi: | |
105 return FromConstant(Smi::kMaxValue); | |
106 case kRangeBoundaryInt32: | |
107 return FromConstant(kMaxInt32); | |
108 case kRangeBoundaryInt64: | |
109 return FromConstant(kMaxInt64); | |
110 } | |
111 UNREACHABLE(); | |
112 return FromConstant(kMaxInt64); | |
113 } | |
114 | |
115 | |
87 // Given two boundaries a and b, select one of them as c so that | 116 // Given two boundaries a and b, select one of them as c so that |
88 // | 117 // |
89 // inf {[a, ...) ^ [b, ...)} >= inf {c} | 118 // inf {[a, ...) ^ [b, ...)} >= inf {c} |
90 // | 119 // |
91 static RangeBoundary IntersectionMin(RangeBoundary a, RangeBoundary b); | 120 static RangeBoundary IntersectionMin(RangeBoundary a, RangeBoundary b); |
92 | 121 |
93 // Given two boundaries a and b, select one of them as c so that | 122 // Given two boundaries a and b, select one of them as c so that |
94 // | 123 // |
95 // sup {(..., a] ^ (..., b]} <= sup {c} | 124 // sup {(..., a] ^ (..., b]} <= sup {c} |
96 // | 125 // |
97 static RangeBoundary IntersectionMax(RangeBoundary a, RangeBoundary b); | 126 static RangeBoundary IntersectionMax(RangeBoundary a, RangeBoundary b); |
98 | 127 |
99 // Given two boundaries a and b compute boundary c such that | 128 // Given two boundaries a and b compute boundary c such that |
100 // | 129 // |
101 // inf {[a, ...) U [b, ...)} >= inf {c} | 130 // inf {[a, ...) U [b, ...)} >= inf {c} |
102 // | 131 // |
103 // Try to select c such that it is as close to inf {[a, ...) U [b, ...)} | 132 // Try to select c such that it is as close to inf {[a, ...) U [b, ...)} |
104 // as possible. | 133 // as possible. |
105 static RangeBoundary JoinMin(RangeBoundary a, RangeBoundary b); | 134 static RangeBoundary JoinMin(RangeBoundary a, |
135 RangeBoundary b, | |
136 RangeBoundary::RangeSize size); | |
106 | 137 |
107 // Given two boundaries a and b compute boundary c such that | 138 // Given two boundaries a and b compute boundary c such that |
108 // | 139 // |
109 // sup {(..., a] U (..., b]} <= sup {c} | 140 // sup {(..., a] U (..., b]} <= sup {c} |
110 // | 141 // |
111 // Try to select c such that it is as close to sup {(..., a] U (..., b]} | 142 // Try to select c such that it is as close to sup {(..., a] U (..., b]} |
112 // as possible. | 143 // as possible. |
113 static RangeBoundary JoinMax(RangeBoundary a, RangeBoundary b); | 144 static RangeBoundary JoinMax(RangeBoundary a, |
145 RangeBoundary b, | |
146 RangeBoundary::RangeSize size); | |
114 | 147 |
115 // Returns true when this is a constant that is outside of Smi range. | 148 // Returns true when this is a constant that is outside of Smi range. |
116 bool OverflowedSmi() const { | 149 bool OverflowedSmi() const { |
117 return (IsConstant() && !Smi::IsValid(ConstantValue())) || IsInfinity(); | 150 return (IsConstant() && !Smi::IsValid(ConstantValue())) || IsInfinity(); |
118 } | 151 } |
119 | 152 |
153 bool Overflowed(RangeBoundary::RangeSize size) const { | |
154 ASSERT(IsConstantOrInfinity()); | |
155 return !Equals(Clamp(size)); | |
156 } | |
157 | |
120 // Returns true if this outside mint range. | 158 // Returns true if this outside mint range. |
121 bool OverflowedMint() const { | 159 bool OverflowedMint() const { |
122 return IsInfinity(); | 160 return IsInfinity(); |
123 } | 161 } |
124 | 162 |
125 // -/+ infinity are clamped to MinConstant/MaxConstant of the given type. | 163 // -/+ infinity are clamped to MinConstant/MaxConstant of the given type. |
126 RangeBoundary Clamp(RangeSize size) const { | 164 RangeBoundary Clamp(RangeSize size) const { |
127 if (IsNegativeInfinity()) { | 165 if (IsNegativeInfinity()) { |
128 return (size == kRangeBoundaryInt64) ? MinConstant() : MinSmi(); | 166 return RangeBoundary::MinConstant(size); |
129 } | 167 } |
168 | |
130 if (IsPositiveInfinity()) { | 169 if (IsPositiveInfinity()) { |
131 return (size == kRangeBoundaryInt64) ? MaxConstant() : MaxSmi(); | 170 return RangeBoundary::MaxConstant(size); |
132 } | 171 } |
133 if ((size == kRangeBoundarySmi) && IsConstant()) { | 172 |
134 if (ConstantValue() <= Smi::kMinValue) { | 173 if (IsConstant()) { |
135 return MinSmi(); | 174 const RangeBoundary range_min = RangeBoundary::MinConstant(size); |
175 const RangeBoundary range_max = RangeBoundary::MaxConstant(size); | |
176 | |
177 if (ConstantValue() <= range_min.ConstantValue()) { | |
178 return range_min; | |
136 } | 179 } |
137 if (ConstantValue() >= Smi::kMaxValue) { | 180 if (ConstantValue() >= range_max.ConstantValue()) { |
138 return MaxSmi(); | 181 return range_max; |
139 } | 182 } |
140 } | 183 } |
184 | |
141 // If this range is a symbolic range, we do not clamp it. | 185 // If this range is a symbolic range, we do not clamp it. |
142 // This could lead to some imprecision later on. | 186 // This could lead to some imprecision later on. |
143 return *this; | 187 return *this; |
144 } | 188 } |
145 | 189 |
146 bool IsSmiMinimumOrBelow() const { | 190 bool IsMinimumOrBelow(RangeSize size) const { |
147 return IsNegativeInfinity() || | 191 return IsNegativeInfinity() || |
148 (IsConstant() && (ConstantValue() <= Smi::kMinValue)); | 192 (IsConstant() && |
193 (ConstantValue() <= RangeBoundary::MinConstant(size).ConstantValue())); | |
149 } | 194 } |
150 | 195 |
151 bool IsSmiMaximumOrAbove() const { | 196 bool IsMaximumOrAbove(RangeSize size) const { |
152 return IsPositiveInfinity() || | 197 return IsPositiveInfinity() || |
153 (IsConstant() && (ConstantValue() >= Smi::kMaxValue)); | 198 (IsConstant() && |
154 } | 199 (ConstantValue() >= RangeBoundary::MaxConstant(size).ConstantValue())); |
155 | |
156 bool IsMinimumOrBelow() const { | |
157 return IsNegativeInfinity() || (IsConstant() && (ConstantValue() == kMin)); | |
158 } | |
159 | |
160 bool IsMaximumOrAbove() const { | |
161 return IsPositiveInfinity() || (IsConstant() && (ConstantValue() == kMax)); | |
162 } | 200 } |
163 | 201 |
164 intptr_t kind() const { | 202 intptr_t kind() const { |
165 return kind_; | 203 return kind_; |
166 } | 204 } |
167 | 205 |
168 // Kind tests. | 206 // Kind tests. |
169 bool IsUnknown() const { return kind_ == kUnknown; } | 207 bool IsUnknown() const { return kind_ == kUnknown; } |
170 bool IsConstant() const { return kind_ == kConstant; } | 208 bool IsConstant() const { return kind_ == kConstant; } |
171 bool IsSymbol() const { return kind_ == kSymbol; } | 209 bool IsSymbol() const { return kind_ == kSymbol; } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 | 276 |
239 // Attempts to calculate a - b when: | 277 // Attempts to calculate a - b when: |
240 // a is a symbol and b is a constant | 278 // a is a symbol and b is a constant |
241 // returns true if it succeeds, output is in result. | 279 // returns true if it succeeds, output is in result. |
242 static bool SymbolicSub(const RangeBoundary& a, | 280 static bool SymbolicSub(const RangeBoundary& a, |
243 const RangeBoundary& b, | 281 const RangeBoundary& b, |
244 RangeBoundary* result); | 282 RangeBoundary* result); |
245 | 283 |
246 bool Equals(const RangeBoundary& other) const; | 284 bool Equals(const RangeBoundary& other) const; |
247 | 285 |
286 int64_t UpperBound(RangeSize size) const { | |
287 return UpperBound().Clamp(size).ConstantValue(); | |
288 } | |
289 | |
290 int64_t LowerBound(RangeSize size) const { | |
291 return LowerBound().Clamp(size).ConstantValue(); | |
292 } | |
293 | |
248 int64_t SmiUpperBound() const { | 294 int64_t SmiUpperBound() const { |
249 return UpperBound().Clamp(kRangeBoundarySmi).ConstantValue(); | 295 return UpperBound(kRangeBoundarySmi); |
250 } | 296 } |
251 | 297 |
252 int64_t SmiLowerBound() const { | 298 int64_t SmiLowerBound() const { |
253 return LowerBound().Clamp(kRangeBoundarySmi).ConstantValue(); | 299 return LowerBound(kRangeBoundarySmi); |
254 } | 300 } |
255 | 301 |
256 private: | 302 private: |
257 RangeBoundary(Kind kind, int64_t value, int64_t offset) | 303 RangeBoundary(Kind kind, int64_t value, int64_t offset) |
258 : kind_(kind), value_(value), offset_(offset) { } | 304 : kind_(kind), value_(value), offset_(offset) { } |
259 | 305 |
260 Kind kind_; | 306 Kind kind_; |
261 int64_t value_; | 307 int64_t value_; |
262 int64_t offset_; | 308 int64_t offset_; |
263 }; | 309 }; |
(...skipping 19 matching lines...) Expand all Loading... | |
283 } | 329 } |
284 | 330 |
285 static bool IsUnknown(const Range* other) { | 331 static bool IsUnknown(const Range* other) { |
286 if (other == NULL) { | 332 if (other == NULL) { |
287 return true; | 333 return true; |
288 } | 334 } |
289 return other->min().IsUnknown(); | 335 return other->min().IsUnknown(); |
290 } | 336 } |
291 | 337 |
292 static Range Full(RangeBoundary::RangeSize size) { | 338 static Range Full(RangeBoundary::RangeSize size) { |
293 if (size == RangeBoundary::kRangeBoundarySmi) { | 339 return Range(RangeBoundary::MinConstant(size), |
294 return Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); | 340 RangeBoundary::MaxConstant(size)); |
295 } else { | |
296 ASSERT(size == RangeBoundary::kRangeBoundaryInt64); | |
297 return Range(RangeBoundary::MinConstant(), RangeBoundary::MaxConstant()); | |
298 } | |
299 } | 341 } |
300 | 342 |
301 void PrintTo(BufferFormatter* f) const; | 343 void PrintTo(BufferFormatter* f) const; |
302 static const char* ToCString(const Range* range); | 344 static const char* ToCString(const Range* range); |
303 | 345 |
304 bool Equals(const Range* other) { | 346 bool Equals(const Range* other) { |
305 ASSERT(min_.IsUnknown() == max_.IsUnknown()); | 347 ASSERT(min_.IsUnknown() == max_.IsUnknown()); |
306 if (other == NULL) { | 348 if (other == NULL) { |
307 return min_.IsUnknown(); | 349 return min_.IsUnknown(); |
308 } | 350 } |
309 return min_.Equals(other->min_) && | 351 return min_.Equals(other->min_) && |
310 max_.Equals(other->max_); | 352 max_.Equals(other->max_); |
311 } | 353 } |
312 | 354 |
313 const RangeBoundary& min() const { return min_; } | 355 const RangeBoundary& min() const { return min_; } |
314 const RangeBoundary& max() const { return max_; } | 356 const RangeBoundary& max() const { return max_; } |
315 void set_min(const RangeBoundary& value) { | 357 void set_min(const RangeBoundary& value) { |
316 min_ = value; | 358 min_ = value; |
317 } | 359 } |
318 void set_max(const RangeBoundary& value) { | 360 void set_max(const RangeBoundary& value) { |
319 max_ = value; | 361 max_ = value; |
320 } | 362 } |
321 | 363 |
322 static RangeBoundary ConstantMinSmi(const Range* range) { | 364 static RangeBoundary ConstantMinSmi(const Range* range) { |
323 if (range == NULL) { | 365 return ConstantMin(range, RangeBoundary::kRangeBoundarySmi); |
324 return RangeBoundary::MinSmi(); | |
325 } | |
326 return range->min().LowerBound().Clamp(RangeBoundary::kRangeBoundarySmi); | |
327 } | 366 } |
328 | 367 |
329 static RangeBoundary ConstantMaxSmi(const Range* range) { | 368 static RangeBoundary ConstantMaxSmi(const Range* range) { |
330 if (range == NULL) { | 369 return ConstantMax(range, RangeBoundary::kRangeBoundarySmi); |
331 return RangeBoundary::MaxSmi(); | |
332 } | |
333 return range->max().UpperBound().Clamp(RangeBoundary::kRangeBoundarySmi); | |
334 } | 370 } |
335 | 371 |
336 static RangeBoundary ConstantMin(const Range* range) { | 372 static RangeBoundary ConstantMin(const Range* range) { |
337 if (range == NULL) { | 373 return ConstantMin(range, RangeBoundary::kRangeBoundaryInt64); |
338 return RangeBoundary::MinConstant(); | |
339 } | |
340 return range->min().LowerBound().Clamp(RangeBoundary::kRangeBoundaryInt64); | |
341 } | 374 } |
342 | 375 |
343 static RangeBoundary ConstantMax(const Range* range) { | 376 static RangeBoundary ConstantMax(const Range* range) { |
377 return ConstantMax(range, RangeBoundary::kRangeBoundaryInt64); | |
378 } | |
379 | |
380 static RangeBoundary ConstantMin(const Range* range, | |
381 RangeBoundary::RangeSize size) { | |
344 if (range == NULL) { | 382 if (range == NULL) { |
345 return RangeBoundary::MaxConstant(); | 383 return RangeBoundary::MinConstant(size); |
346 } | 384 } |
347 return range->max().UpperBound().Clamp(RangeBoundary::kRangeBoundaryInt64); | 385 return range->min().LowerBound().Clamp(size); |
348 } | 386 } |
349 | 387 |
388 static RangeBoundary ConstantMax(const Range* range, | |
389 RangeBoundary::RangeSize size) { | |
390 if (range == NULL) { | |
391 return RangeBoundary::MaxConstant(size); | |
392 } | |
393 return range->max().UpperBound().Clamp(size); | |
394 } | |
395 | |
396 | |
350 // [0, +inf] | 397 // [0, +inf] |
351 bool IsPositive() const; | 398 bool IsPositive() const; |
352 | 399 |
353 // [-inf, val]. | 400 // [-inf, val]. |
354 bool OnlyLessThanOrEqualTo(int64_t val) const; | 401 bool OnlyLessThanOrEqualTo(int64_t val) const; |
355 | 402 |
356 // [val, +inf]. | 403 // [val, +inf]. |
357 bool OnlyGreaterThanOrEqualTo(int64_t val) const; | 404 bool OnlyGreaterThanOrEqualTo(int64_t val) const; |
358 | 405 |
359 // Inclusive. | 406 // Inclusive. |
360 bool IsWithin(int64_t min_int, int64_t max_int) const; | 407 bool IsWithin(int64_t min_int, int64_t max_int) const; |
361 | 408 |
362 // Inclusive. | 409 // Inclusive. |
363 bool Overlaps(int64_t min_int, int64_t max_int) const; | 410 bool Overlaps(int64_t min_int, int64_t max_int) const; |
364 | 411 |
365 bool IsUnsatisfiable() const; | 412 bool IsUnsatisfiable() const; |
366 | 413 |
367 bool IsFinite() const { | 414 bool IsFinite() const { |
368 return !min_.IsInfinity() && !max_.IsInfinity(); | 415 return !min_.IsInfinity() && !max_.IsInfinity(); |
369 } | 416 } |
370 | 417 |
371 Range Intersect(const Range* other) const { | 418 Range Intersect(const Range* other) const { |
372 return Range(RangeBoundary::IntersectionMin(min(), other->min()), | 419 return Range(RangeBoundary::IntersectionMin(min(), other->min()), |
373 RangeBoundary::IntersectionMax(max(), other->max())); | 420 RangeBoundary::IntersectionMax(max(), other->max())); |
374 } | 421 } |
375 | 422 |
423 bool Fits(RangeBoundary::RangeSize size) const { | |
424 return !min().LowerBound().Overflowed(size) && | |
425 !max().UpperBound().Overflowed(size); | |
426 } | |
427 | |
428 static bool Fits(Range* range, RangeBoundary::RangeSize size) { | |
429 return !IsUnknown(range) && range->Fits(size); | |
430 } | |
srdjan
2014/08/27 16:17:13
I think it is confusing to have a non-static and s
Vyacheslav Egorov (Google)
2014/08/28 20:48:37
Agreed. Moved into a separate AllStatic helper cla
| |
431 | |
376 // Clamp this to be within size. | 432 // Clamp this to be within size. |
377 void Clamp(RangeBoundary::RangeSize size); | 433 void Clamp(RangeBoundary::RangeSize size); |
378 | 434 |
379 static void Add(const Range* left_range, | 435 static void Add(const Range* left_range, |
380 const Range* right_range, | 436 const Range* right_range, |
381 RangeBoundary* min, | 437 RangeBoundary* min, |
382 RangeBoundary* max, | 438 RangeBoundary* max, |
383 Definition* left_defn); | 439 Definition* left_defn); |
384 | 440 |
385 static void Sub(const Range* left_range, | 441 static void Sub(const Range* left_range, |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 void Iterate(JoinOperator op, intptr_t max_iterations); | 552 void Iterate(JoinOperator op, intptr_t max_iterations); |
497 bool InferRange(JoinOperator op, Definition* defn, intptr_t iteration); | 553 bool InferRange(JoinOperator op, Definition* defn, intptr_t iteration); |
498 | 554 |
499 // Based on computed ranges find and eliminate redundant CheckArrayBound | 555 // Based on computed ranges find and eliminate redundant CheckArrayBound |
500 // instructions. | 556 // instructions. |
501 void EliminateRedundantBoundsChecks(); | 557 void EliminateRedundantBoundsChecks(); |
502 | 558 |
503 // Find unsatisfiable constraints and mark corresponding blocks unreachable. | 559 // Find unsatisfiable constraints and mark corresponding blocks unreachable. |
504 void MarkUnreachableBlocks(); | 560 void MarkUnreachableBlocks(); |
505 | 561 |
562 // Convert mint operations that stay within int32 range into Int32 operations. | |
563 void NarrowMintToInt32(); | |
564 | |
506 // Remove artificial Constraint instructions and replace them with actual | 565 // Remove artificial Constraint instructions and replace them with actual |
507 // unconstrained definitions. | 566 // unconstrained definitions. |
508 void RemoveConstraints(); | 567 void RemoveConstraints(); |
509 | 568 |
510 Range* ConstraintSmiRange(Token::Kind op, Definition* boundary); | 569 Range* ConstraintSmiRange(Token::Kind op, Definition* boundary); |
511 | 570 |
512 Isolate* isolate() const { return flow_graph_->isolate(); } | 571 Isolate* isolate() const { return flow_graph_->isolate(); } |
513 | 572 |
514 FlowGraph* flow_graph_; | 573 FlowGraph* flow_graph_; |
515 | 574 |
516 // Range object representing full Smi range. | 575 // Range object representing full Smi range. |
517 Range smi_range_; | 576 Range smi_range_; |
518 | 577 |
519 // Value that are known to be smi or mint. | 578 // Value that are known to be smi or mint. |
520 GrowableArray<Definition*> values_; | 579 GrowableArray<Definition*> values_; |
521 | 580 |
581 GrowableArray<BinaryMintOpInstr*> binary_mint_ops_; | |
582 | |
583 GrowableArray<ShiftMintOpInstr*> shift_mint_ops_; | |
584 | |
522 // All CheckArrayBound instructions. | 585 // All CheckArrayBound instructions. |
523 GrowableArray<CheckArrayBoundInstr*> bounds_checks_; | 586 GrowableArray<CheckArrayBoundInstr*> bounds_checks_; |
524 | 587 |
525 // All Constraints inserted during InsertConstraints phase. They are treated | 588 // All Constraints inserted during InsertConstraints phase. They are treated |
526 // as smi values. | 589 // as smi values. |
527 GrowableArray<ConstraintInstr*> constraints_; | 590 GrowableArray<ConstraintInstr*> constraints_; |
528 | 591 |
529 // List of integer (smi or mint) definitions including constraints sorted | 592 // List of integer (smi or mint) definitions including constraints sorted |
530 // in the reverse postorder. | 593 // in the reverse postorder. |
531 GrowableArray<Definition*> definitions_; | 594 GrowableArray<Definition*> definitions_; |
(...skipping 27 matching lines...) Expand all Loading... | |
559 BitVector* selected_uint32_defs_; | 622 BitVector* selected_uint32_defs_; |
560 | 623 |
561 FlowGraph* flow_graph_; | 624 FlowGraph* flow_graph_; |
562 Isolate* isolate_; | 625 Isolate* isolate_; |
563 }; | 626 }; |
564 | 627 |
565 | 628 |
566 } // namespace dart | 629 } // namespace dart |
567 | 630 |
568 #endif // VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ | 631 #endif // VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ |
OLD | NEW |