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

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

Issue 353513002: Use range information for optimizing integer boxing and fix bug in range analysis. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 return class_id() == other_load->class_id(); 311 return class_id() == other_load->class_id();
312 } 312 }
313 313
314 314
315 ConstantInstr::ConstantInstr(const Object& value) : value_(value) { 315 ConstantInstr::ConstantInstr(const Object& value) : value_(value) {
316 // Check that the value is not an incorrect Integer representation. 316 // Check that the value is not an incorrect Integer representation.
317 ASSERT(!value.IsBigint() || 317 ASSERT(!value.IsBigint() ||
318 !BigintOperations::FitsIntoSmi(Bigint::Cast(value))); 318 !BigintOperations::FitsIntoSmi(Bigint::Cast(value)));
319 ASSERT(!value.IsBigint() || 319 ASSERT(!value.IsBigint() ||
320 !BigintOperations::FitsIntoInt64(Bigint::Cast(value))); 320 !BigintOperations::FitsIntoInt64(Bigint::Cast(value)));
321 ASSERT(!value.IsMint() || !Smi::IsValid64(Mint::Cast(value).AsInt64Value())); 321 ASSERT(!value.IsMint() || !Smi::IsValid(Mint::Cast(value).AsInt64Value()));
322 } 322 }
323 323
324 324
325 bool ConstantInstr::AttributesEqual(Instruction* other) const { 325 bool ConstantInstr::AttributesEqual(Instruction* other) const {
326 ConstantInstr* other_constant = other->AsConstant(); 326 ConstantInstr* other_constant = other->AsConstant();
327 ASSERT(other_constant != NULL); 327 ASSERT(other_constant != NULL);
328 return (value().raw() == other_constant->value().raw()); 328 return (value().raw() == other_constant->value().raw());
329 } 329 }
330 330
331 331
(...skipping 2263 matching lines...) Expand 10 before | Expand all | Expand 10 after
2595 ASSERT(value_boundary.IsConstant()); 2595 ASSERT(value_boundary.IsConstant());
2596 ASSERT(shift_count >= 0); 2596 ASSERT(shift_count >= 0);
2597 int64_t limit = 64 - shift_count; 2597 int64_t limit = 64 - shift_count;
2598 int64_t value = static_cast<int64_t>(value_boundary.ConstantValue()); 2598 int64_t value = static_cast<int64_t>(value_boundary.ConstantValue());
2599 2599
2600 if ((value == 0) || 2600 if ((value == 0) ||
2601 (shift_count == 0) || 2601 (shift_count == 0) ||
2602 ((limit > 0) && (Utils::IsInt(limit, value)))) { 2602 ((limit > 0) && (Utils::IsInt(limit, value)))) {
2603 // Result stays in 64 bit range. 2603 // Result stays in 64 bit range.
2604 int64_t result = value << shift_count; 2604 int64_t result = value << shift_count;
2605 return Smi::IsValid64(result) ? RangeBoundary(result) : overflow; 2605 return Smi::IsValid(result) ? RangeBoundary(result) : overflow;
2606 } 2606 }
2607 2607
2608 return overflow; 2608 return overflow;
2609 } 2609 }
2610 2610
2611 2611
2612 static RangeBoundary CanonicalizeBoundary(const RangeBoundary& a, 2612 static RangeBoundary CanonicalizeBoundary(const RangeBoundary& a,
2613 const RangeBoundary& overflow) { 2613 const RangeBoundary& overflow) {
2614 if (a.IsConstant() || a.IsInfinity()) { 2614 if (a.IsConstant() || a.IsInfinity()) {
2615 return a; 2615 return a;
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after
3248 3248
3249 range_ = possible_range; 3249 range_ = possible_range;
3250 3250
3251 ASSERT(!range_->min().IsUnknown() && !range_->max().IsUnknown()); 3251 ASSERT(!range_->min().IsUnknown() && !range_->max().IsUnknown());
3252 3252
3253 // Clamp value to be within mint range. 3253 // Clamp value to be within mint range.
3254 range_->Clamp(RangeBoundary::kRangeBoundaryInt64); 3254 range_->Clamp(RangeBoundary::kRangeBoundaryInt64);
3255 } 3255 }
3256 3256
3257 3257
3258 void ShiftMintOpInstr::InferRange() {
3259 Definition* left_defn = left()->definition();
3260
3261 Range* left_range = left_defn->range();
3262 Range* right_range = right()->definition()->range();
3263
3264 if ((left_range == NULL) || (right_range == NULL)) {
3265 range_ = Range::Unknown();
3266 return;
3267 }
3268
3269 Range* possible_range = Range::BinaryOp(op_kind(),
3270 left_range,
3271 right_range,
3272 left_defn);
3273
3274 if ((range_ == NULL) && (possible_range == NULL)) {
3275 // Initialize.
3276 range_ = Range::Unknown();
3277 return;
3278 }
3279
3280 if (possible_range == NULL) {
3281 // Nothing new.
3282 return;
3283 }
3284
3285 range_ = possible_range;
3286
3287 ASSERT(!range_->min().IsUnknown() && !range_->max().IsUnknown());
3288
3289 // Clamp value to be within mint range.
3290 range_->Clamp(RangeBoundary::kRangeBoundaryInt64);
3291 }
3292
Vyacheslav Egorov (Google) 2014/06/24 12:18:12 one more empty line
Florian Schneider 2014/06/24 12:35:06 Done.
3293 void BoxIntegerInstr::InferRange() {
3294 Range* input_range = value()->definition()->range();
3295 if (input_range != NULL) {
3296 bool is_smi = !input_range->min().LowerBound().OverflowedSmi() &&
3297 !input_range->max().UpperBound().OverflowedSmi();
3298 set_is_smi(is_smi);
3299 // The output range is the same as the input range.
3300 range_ = input_range;
3301 }
3302 }
3303
3304
3258 bool Range::IsPositive() const { 3305 bool Range::IsPositive() const {
3259 if (min().IsNegativeInfinity()) { 3306 if (min().IsNegativeInfinity()) {
3260 return false; 3307 return false;
3261 } 3308 }
3262 if (min().LowerBound().ConstantValue() < 0) { 3309 if (min().LowerBound().ConstantValue() < 0) {
3263 return false; 3310 return false;
3264 } 3311 }
3265 if (max().IsPositiveInfinity()) { 3312 if (max().IsPositiveInfinity()) {
3266 return true; 3313 return true;
3267 } 3314 }
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
3496 ASSERT(right_range != NULL); 3543 ASSERT(right_range != NULL);
3497 ASSERT(result_min != NULL); 3544 ASSERT(result_min != NULL);
3498 ASSERT(result_max != NULL); 3545 ASSERT(result_max != NULL);
3499 3546
3500 const int64_t left_max = ConstantAbsMax(left_range); 3547 const int64_t left_max = ConstantAbsMax(left_range);
3501 const int64_t right_max = ConstantAbsMax(right_range); 3548 const int64_t right_max = ConstantAbsMax(right_range);
3502 if ((left_max <= -kSmiMin) && (right_max <= -kSmiMin) && 3549 if ((left_max <= -kSmiMin) && (right_max <= -kSmiMin) &&
3503 ((left_max == 0) || (right_max <= kMaxInt64 / left_max))) { 3550 ((left_max == 0) || (right_max <= kMaxInt64 / left_max))) {
3504 // Product of left and right max values stays in 64 bit range. 3551 // Product of left and right max values stays in 64 bit range.
3505 const int64_t mul_max = left_max * right_max; 3552 const int64_t mul_max = left_max * right_max;
3506 if (Smi::IsValid64(mul_max) && Smi::IsValid64(-mul_max)) { 3553 if (Smi::IsValid(mul_max) && Smi::IsValid(-mul_max)) {
3507 const intptr_t r_min = 3554 const intptr_t r_min =
3508 OnlyPositiveOrZero(*left_range, *right_range) ? 0 : -mul_max; 3555 OnlyPositiveOrZero(*left_range, *right_range) ? 0 : -mul_max;
3509 *result_min = RangeBoundary::FromConstant(r_min); 3556 *result_min = RangeBoundary::FromConstant(r_min);
3510 const intptr_t r_max = 3557 const intptr_t r_max =
3511 OnlyNegativeOrZero(*left_range, *right_range) ? 0 : mul_max; 3558 OnlyNegativeOrZero(*left_range, *right_range) ? 0 : mul_max;
3512 *result_max = RangeBoundary::FromConstant(r_max); 3559 *result_max = RangeBoundary::FromConstant(r_max);
3513 return true; 3560 return true;
3514 } 3561 }
3515 } 3562 }
3516 return false; 3563 return false;
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
3917 case Token::kTRUNCDIV: return 0; 3964 case Token::kTRUNCDIV: return 0;
3918 case Token::kMOD: return 1; 3965 case Token::kMOD: return 1;
3919 default: UNIMPLEMENTED(); return -1; 3966 default: UNIMPLEMENTED(); return -1;
3920 } 3967 }
3921 } 3968 }
3922 3969
3923 3970
3924 #undef __ 3971 #undef __
3925 3972
3926 } // namespace dart 3973 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698