Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: runtime/vm/flow_graph_range_analysis.cc

Issue 2891113002: Use same range info when emitting code and computing if instruction can deopt. (Closed)
Patch Set: Add a comment to the test Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/flow_graph_range_analysis.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_range_analysis.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698