Chromium Code Reviews| 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 |