| 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 #include "vm/flow_graph_range_analysis.h" | 5 #include "vm/flow_graph_range_analysis.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/il_printer.h" | 8 #include "vm/il_printer.h" |
| 9 | 9 |
| 10 namespace dart { | 10 namespace dart { |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 | 614 |
| 615 // Given the current range of a phi and a newly computed range check | 615 // Given the current range of a phi and a newly computed range check |
| 616 // if we can perform narrowing: use newly computed minimum to improve precision | 616 // if we can perform narrowing: use newly computed minimum to improve precision |
| 617 // of the computed range. We do it only if current minimum was widened and is | 617 // of the computed range. We do it only if current minimum was widened and is |
| 618 // equal to MinSmi. | 618 // equal to MinSmi. |
| 619 // Newly computed minimum is expected to be greater or equal than old one as | 619 // Newly computed minimum is expected to be greater or equal than old one as |
| 620 // we are running after widening phase. | 620 // we are running after widening phase. |
| 621 static RangeBoundary NarrowMin(const Range* range, | 621 static RangeBoundary NarrowMin(const Range* range, |
| 622 const Range* new_range, | 622 const Range* new_range, |
| 623 RangeBoundary::RangeSize size) { | 623 RangeBoundary::RangeSize size) { |
| 624 #ifdef DEBUG | |
| 625 const RangeBoundary min = Range::ConstantMin(range, size); | 624 const RangeBoundary min = Range::ConstantMin(range, size); |
| 626 const RangeBoundary new_min = Range::ConstantMin(new_range, size); | 625 const RangeBoundary new_min = Range::ConstantMin(new_range, size); |
| 627 ASSERT(min.ConstantValue() <= new_min.ConstantValue()); | 626 if (min.ConstantValue() > new_min.ConstantValue()) return range->min(); |
| 628 #endif | 627 |
| 629 // TODO(vegorov): consider using negative infinity to indicate widened bound. | 628 // TODO(vegorov): consider using negative infinity to indicate widened bound. |
| 630 return range->min().IsMinimumOrBelow(size) ? new_range->min() : range->min(); | 629 return range->min().IsMinimumOrBelow(size) ? new_range->min() : range->min(); |
| 631 } | 630 } |
| 632 | 631 |
| 633 | 632 |
| 634 // Given the current range of a phi and a newly computed range check | 633 // Given the current range of a phi and a newly computed range check |
| 635 // if we can perform narrowing: use newly computed maximum to improve precision | 634 // if we can perform narrowing: use newly computed maximum to improve precision |
| 636 // of the computed range. We do it only if current maximum was widened and is | 635 // of the computed range. We do it only if current maximum was widened and is |
| 637 // equal to MaxSmi. | 636 // equal to MaxSmi. |
| 638 // Newly computed maximum is expected to be less or equal than old one as | 637 // Newly computed maximum is expected to be less or equal than old one as |
| 639 // we are running after widening phase. | 638 // we are running after widening phase. |
| 640 static RangeBoundary NarrowMax(const Range* range, | 639 static RangeBoundary NarrowMax(const Range* range, |
| 641 const Range* new_range, | 640 const Range* new_range, |
| 642 RangeBoundary::RangeSize size) { | 641 RangeBoundary::RangeSize size) { |
| 643 #ifdef DEBUG | |
| 644 const RangeBoundary max = Range::ConstantMax(range, size); | 642 const RangeBoundary max = Range::ConstantMax(range, size); |
| 645 const RangeBoundary new_max = Range::ConstantMax(new_range, size); | 643 const RangeBoundary new_max = Range::ConstantMax(new_range, size); |
| 646 ASSERT(max.ConstantValue() >= new_max.ConstantValue()); | 644 if (max.ConstantValue() < new_max.ConstantValue()) return range->max(); |
| 647 #endif | 645 |
| 648 // TODO(vegorov): consider using positive infinity to indicate widened bound. | 646 // TODO(vegorov): consider using positive infinity to indicate widened bound. |
| 649 return range->max().IsMaximumOrAbove(size) ? new_range->max() : range->max(); | 647 return range->max().IsMaximumOrAbove(size) ? new_range->max() : range->max(); |
| 650 } | 648 } |
| 651 | 649 |
| 652 | 650 |
| 653 char RangeAnalysis::OpPrefix(JoinOperator op) { | 651 char RangeAnalysis::OpPrefix(JoinOperator op) { |
| 654 switch (op) { | 652 switch (op) { |
| 655 case WIDEN: return 'W'; | 653 case WIDEN: return 'W'; |
| 656 case NARROW: return 'N'; | 654 case NARROW: return 'N'; |
| 657 case NONE: return 'I'; | 655 case NONE: return 'I'; |
| (...skipping 2504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3162 } | 3160 } |
| 3163 } while (CanonicalizeMaxBoundary(&max) || | 3161 } while (CanonicalizeMaxBoundary(&max) || |
| 3164 CanonicalizeMinBoundary(&canonical_length)); | 3162 CanonicalizeMinBoundary(&canonical_length)); |
| 3165 | 3163 |
| 3166 // Failed to prove that maximum is bounded with array length. | 3164 // Failed to prove that maximum is bounded with array length. |
| 3167 return false; | 3165 return false; |
| 3168 } | 3166 } |
| 3169 | 3167 |
| 3170 | 3168 |
| 3171 } // namespace dart | 3169 } // namespace dart |
| OLD | NEW |