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 |