Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |