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, | |
rmacnak
2017/05/18 20:02:45
I see crashes in some tests because range may be n
Vyacheslav Egorov (Google)
2017/05/19 08:07:08
Ooops. Should have rerun tests after refactoring.
| |
2897 RangeBoundary::RangeSize size) { | |
2898 if (*slot == NULL) { | |
2899 *slot = new Range(); | |
2900 } | |
2901 **slot = *range; | |
2902 | |
2903 // Eliminate any symbolic dependencies from the range information. | |
2904 (*slot)->ClampToConstant(size); | |
2905 } | |
2906 | |
2907 | |
2889 void BinarySmiOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2908 void BinarySmiOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
2909 const Range* right_smi_range = analysis->GetSmiRange(right()); | |
2890 // TODO(vegorov) completely remove this once GetSmiRange is eliminated. | 2910 // TODO(vegorov) completely remove this once GetSmiRange is eliminated. |
2891 InferRangeHelper(analysis->GetSmiRange(left()), | 2911 if (op_kind() == Token::kSHR || op_kind() == Token::kSHL || |
2892 analysis->GetSmiRange(right()), range); | 2912 op_kind() == Token::kMOD || op_kind() == Token::kTRUNCDIV) { |
2913 CacheRange(&right_range_, right_smi_range, | |
2914 RangeBoundary::kRangeBoundarySmi); | |
2915 } | |
2916 InferRangeHelper(analysis->GetSmiRange(left()), right_smi_range, range); | |
2893 } | 2917 } |
2894 | 2918 |
2895 | 2919 |
2896 void BinaryInt32OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2920 void BinaryInt32OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
2897 InferRangeHelper(analysis->GetSmiRange(left()), | 2921 InferRangeHelper(analysis->GetSmiRange(left()), |
2898 analysis->GetSmiRange(right()), range); | 2922 analysis->GetSmiRange(right()), range); |
2899 } | 2923 } |
2900 | 2924 |
2901 | 2925 |
2902 void BinaryMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2926 void BinaryMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
2903 InferRangeHelper(left()->definition()->range(), | 2927 InferRangeHelper(left()->definition()->range(), |
2904 right()->definition()->range(), range); | 2928 right()->definition()->range(), range); |
2905 } | 2929 } |
2906 | 2930 |
2907 | 2931 |
2908 void ShiftMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2932 void ShiftMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
2933 CacheRange(&shift_range_, right()->definition()->range(), | |
2934 RangeBoundary::kRangeBoundaryInt64); | |
2909 InferRangeHelper(left()->definition()->range(), | 2935 InferRangeHelper(left()->definition()->range(), |
2910 right()->definition()->range(), range); | 2936 right()->definition()->range(), range); |
2911 } | 2937 } |
2912 | 2938 |
2913 | 2939 |
2914 void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2940 void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
2915 const Range* value_range = value()->definition()->range(); | 2941 const Range* value_range = value()->definition()->range(); |
2916 if (!Range::IsUnknown(value_range)) { | 2942 if (!Range::IsUnknown(value_range)) { |
2917 *range = *value_range; | 2943 *range = *value_range; |
2918 } | 2944 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3046 } | 3072 } |
3047 } while (CanonicalizeMaxBoundary(&max) || | 3073 } while (CanonicalizeMaxBoundary(&max) || |
3048 CanonicalizeMinBoundary(&canonical_length)); | 3074 CanonicalizeMinBoundary(&canonical_length)); |
3049 | 3075 |
3050 // Failed to prove that maximum is bounded with array length. | 3076 // Failed to prove that maximum is bounded with array length. |
3051 return false; | 3077 return false; |
3052 } | 3078 } |
3053 | 3079 |
3054 | 3080 |
3055 } // namespace dart | 3081 } // namespace dart |
OLD | NEW |