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 |