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 2238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2249 return DependOnSameSymbol(min(), max()) && min().offset() > max().offset(); | 2249 return DependOnSameSymbol(min(), max()) && min().offset() > max().offset(); |
2250 } | 2250 } |
2251 | 2251 |
2252 | 2252 |
2253 void Range::Clamp(RangeBoundary::RangeSize size) { | 2253 void Range::Clamp(RangeBoundary::RangeSize size) { |
2254 min_ = min_.Clamp(size); | 2254 min_ = min_.Clamp(size); |
2255 max_ = max_.Clamp(size); | 2255 max_ = max_.Clamp(size); |
2256 } | 2256 } |
2257 | 2257 |
2258 | 2258 |
| 2259 void Range::ClampToConstant(RangeBoundary::RangeSize size) { |
| 2260 min_ = min_.LowerBound().Clamp(size); |
| 2261 max_ = max_.UpperBound().Clamp(size); |
| 2262 } |
| 2263 |
| 2264 |
2259 void Range::Shl(const Range* left, | 2265 void Range::Shl(const Range* left, |
2260 const Range* right, | 2266 const Range* right, |
2261 RangeBoundary* result_min, | 2267 RangeBoundary* result_min, |
2262 RangeBoundary* result_max) { | 2268 RangeBoundary* result_max) { |
2263 ASSERT(left != NULL); | 2269 ASSERT(left != NULL); |
2264 ASSERT(right != NULL); | 2270 ASSERT(right != NULL); |
2265 ASSERT(result_min != NULL); | 2271 ASSERT(result_min != NULL); |
2266 ASSERT(result_max != NULL); | 2272 ASSERT(result_max != NULL); |
2267 RangeBoundary left_max = Range::ConstantMax(left); | 2273 RangeBoundary left_max = Range::ConstantMax(left); |
2268 RangeBoundary left_min = Range::ConstantMin(left); | 2274 RangeBoundary left_min = Range::ConstantMin(left); |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2879 // Calculate overflowed status before clamping if operation is | 2885 // Calculate overflowed status before clamping if operation is |
2880 // not truncating. | 2886 // not truncating. |
2881 if (!is_truncating()) { | 2887 if (!is_truncating()) { |
2882 set_can_overflow(!range->Fits(range_size)); | 2888 set_can_overflow(!range->Fits(range_size)); |
2883 } | 2889 } |
2884 | 2890 |
2885 range->Clamp(range_size); | 2891 range->Clamp(range_size); |
2886 } | 2892 } |
2887 | 2893 |
2888 | 2894 |
| 2895 static void CacheRange(Range** slot, |
| 2896 const Range* range, |
| 2897 RangeBoundary::RangeSize size) { |
| 2898 if (range != NULL) { |
| 2899 if (*slot == NULL) { |
| 2900 *slot = new Range(); |
| 2901 } |
| 2902 **slot = *range; |
| 2903 |
| 2904 // Eliminate any symbolic dependencies from the range information. |
| 2905 (*slot)->ClampToConstant(size); |
| 2906 } else if (*slot != NULL) { |
| 2907 **slot = Range(); // Clear cached range information. |
| 2908 } |
| 2909 } |
| 2910 |
| 2911 |
2889 void BinarySmiOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2912 void BinarySmiOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| 2913 const Range* right_smi_range = analysis->GetSmiRange(right()); |
2890 // TODO(vegorov) completely remove this once GetSmiRange is eliminated. | 2914 // TODO(vegorov) completely remove this once GetSmiRange is eliminated. |
2891 InferRangeHelper(analysis->GetSmiRange(left()), | 2915 if (op_kind() == Token::kSHR || op_kind() == Token::kSHL || |
2892 analysis->GetSmiRange(right()), range); | 2916 op_kind() == Token::kMOD || op_kind() == Token::kTRUNCDIV) { |
| 2917 CacheRange(&right_range_, right_smi_range, |
| 2918 RangeBoundary::kRangeBoundarySmi); |
| 2919 } |
| 2920 InferRangeHelper(analysis->GetSmiRange(left()), right_smi_range, range); |
2893 } | 2921 } |
2894 | 2922 |
2895 | 2923 |
2896 void BinaryInt32OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2924 void BinaryInt32OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
2897 InferRangeHelper(analysis->GetSmiRange(left()), | 2925 InferRangeHelper(analysis->GetSmiRange(left()), |
2898 analysis->GetSmiRange(right()), range); | 2926 analysis->GetSmiRange(right()), range); |
2899 } | 2927 } |
2900 | 2928 |
2901 | 2929 |
2902 void BinaryMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2930 void BinaryMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
2903 InferRangeHelper(left()->definition()->range(), | 2931 InferRangeHelper(left()->definition()->range(), |
2904 right()->definition()->range(), range); | 2932 right()->definition()->range(), range); |
2905 } | 2933 } |
2906 | 2934 |
2907 | 2935 |
2908 void ShiftMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2936 void ShiftMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| 2937 CacheRange(&shift_range_, right()->definition()->range(), |
| 2938 RangeBoundary::kRangeBoundaryInt64); |
2909 InferRangeHelper(left()->definition()->range(), | 2939 InferRangeHelper(left()->definition()->range(), |
2910 right()->definition()->range(), range); | 2940 right()->definition()->range(), range); |
2911 } | 2941 } |
2912 | 2942 |
2913 | 2943 |
2914 void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2944 void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
2915 const Range* value_range = value()->definition()->range(); | 2945 const Range* value_range = value()->definition()->range(); |
2916 if (!Range::IsUnknown(value_range)) { | 2946 if (!Range::IsUnknown(value_range)) { |
2917 *range = *value_range; | 2947 *range = *value_range; |
2918 } | 2948 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3046 } | 3076 } |
3047 } while (CanonicalizeMaxBoundary(&max) || | 3077 } while (CanonicalizeMaxBoundary(&max) || |
3048 CanonicalizeMinBoundary(&canonical_length)); | 3078 CanonicalizeMinBoundary(&canonical_length)); |
3049 | 3079 |
3050 // Failed to prove that maximum is bounded with array length. | 3080 // Failed to prove that maximum is bounded with array length. |
3051 return false; | 3081 return false; |
3052 } | 3082 } |
3053 | 3083 |
3054 | 3084 |
3055 } // namespace dart | 3085 } // namespace dart |
OLD | NEW |