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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 constant_address_ = | 336 constant_address_ = |
337 FlowGraphBuilder::FindDoubleConstant(Double::Cast(value).value()); | 337 FlowGraphBuilder::FindDoubleConstant(Double::Cast(value).value()); |
338 } | 338 } |
339 | 339 |
340 // Returns true if the value represents a constant. | 340 // Returns true if the value represents a constant. |
341 bool Value::BindsToConstant() const { | 341 bool Value::BindsToConstant() const { |
342 return definition()->IsConstant(); | 342 return definition()->IsConstant(); |
343 } | 343 } |
344 | 344 |
345 | 345 |
| 346 bool Value::BindsTo32BitMint() const { |
| 347 if (!definition()->IsMintDefinition()) { |
| 348 return false; |
| 349 } |
| 350 if (definition()->IsBinaryMintOp()) { |
| 351 BinaryMintOpInstr* instr = definition()->AsBinaryMintOp(); |
| 352 return instr->is_32_bit(); |
| 353 } else if (definition()->IsShiftMintOp()) { |
| 354 ShiftMintOpInstr* instr = definition()->AsShiftMintOp(); |
| 355 return instr->is_32_bit(); |
| 356 } else if (definition()->IsUnboxInteger()) { |
| 357 UnboxIntegerInstr* instr = definition()->AsUnboxInteger(); |
| 358 return instr->is_32_bit(); |
| 359 } else if (definition()->IsUnaryMintOp()) { |
| 360 UnaryMintOpInstr* instr = definition()->AsUnaryMintOp(); |
| 361 return instr->is_32_bit(); |
| 362 } |
| 363 return false; |
| 364 } |
| 365 |
| 366 |
| 367 bool Value::BindsTo32BitMaskConstant() const { |
| 368 if (!definition()->IsUnboxInteger()) { |
| 369 return false; |
| 370 } |
| 371 UnboxIntegerInstr* instr = definition()->AsUnboxInteger(); |
| 372 if (!instr->value()->BindsToConstant()) { |
| 373 return false; |
| 374 } |
| 375 const Object& obj = instr->value()->BoundConstant(); |
| 376 if (!obj.IsMint()) { |
| 377 return false; |
| 378 } |
| 379 Mint& mint = Mint::Handle(); |
| 380 mint ^= obj.raw(); |
| 381 return mint.value() == kMaxUint32; |
| 382 } |
| 383 |
| 384 |
346 // Returns true if the value represents constant null. | 385 // Returns true if the value represents constant null. |
347 bool Value::BindsToConstantNull() const { | 386 bool Value::BindsToConstantNull() const { |
348 ConstantInstr* constant = definition()->AsConstant(); | 387 ConstantInstr* constant = definition()->AsConstant(); |
349 return (constant != NULL) && constant->value().IsNull(); | 388 return (constant != NULL) && constant->value().IsNull(); |
350 } | 389 } |
351 | 390 |
352 | 391 |
353 const Object& Value::BoundConstant() const { | 392 const Object& Value::BoundConstant() const { |
354 ASSERT(BindsToConstant()); | 393 ASSERT(BindsToConstant()); |
355 ConstantInstr* constant = definition()->AsConstant(); | 394 ConstantInstr* constant = definition()->AsConstant(); |
(...skipping 2854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3210 // Calculate overflowed status before clamping. | 3249 // Calculate overflowed status before clamping. |
3211 const bool overflowed = range_->min().LowerBound().OverflowedSmi() || | 3250 const bool overflowed = range_->min().LowerBound().OverflowedSmi() || |
3212 range_->max().UpperBound().OverflowedSmi(); | 3251 range_->max().UpperBound().OverflowedSmi(); |
3213 // Clamp value to be within smi range. | 3252 // Clamp value to be within smi range. |
3214 range_->Clamp(RangeBoundary::kRangeBoundarySmi); | 3253 range_->Clamp(RangeBoundary::kRangeBoundarySmi); |
3215 | 3254 |
3216 set_overflow(overflowed); | 3255 set_overflow(overflowed); |
3217 } | 3256 } |
3218 | 3257 |
3219 | 3258 |
| 3259 Representation BinaryMintOpInstr::RequiredInputRepresentation( |
| 3260 intptr_t idx) const { |
| 3261 ASSERT((idx == 0) || (idx == 1)); |
| 3262 return InputAt(idx)->BindsTo32BitMint() ? kUnboxedMint32 : kUnboxedMint; |
| 3263 } |
| 3264 |
| 3265 |
3220 void BinaryMintOpInstr::InferRange() { | 3266 void BinaryMintOpInstr::InferRange() { |
3221 // TODO(vegorov): canonicalize BinaryMintOpInstr to always have constant on | 3267 // TODO(vegorov): canonicalize BinaryMintOpInstr to always have constant on |
3222 // the right and a non-constant on the left. | 3268 // the right and a non-constant on the left. |
3223 Definition* left_defn = left()->definition(); | 3269 Definition* left_defn = left()->definition(); |
3224 | 3270 |
3225 Range* left_range = left_defn->range(); | 3271 Range* left_range = left_defn->range(); |
3226 Range* right_range = right()->definition()->range(); | 3272 Range* right_range = right()->definition()->range(); |
3227 | 3273 |
3228 if ((left_range == NULL) || (right_range == NULL)) { | 3274 if ((left_range == NULL) || (right_range == NULL)) { |
3229 range_ = Range::Unknown(); | 3275 range_ = Range::Unknown(); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3451 | 3497 |
3452 bool Range::And(const Range* left_range, | 3498 bool Range::And(const Range* left_range, |
3453 const Range* right_range, | 3499 const Range* right_range, |
3454 RangeBoundary* result_min, | 3500 RangeBoundary* result_min, |
3455 RangeBoundary* result_max) { | 3501 RangeBoundary* result_max) { |
3456 ASSERT(left_range != NULL); | 3502 ASSERT(left_range != NULL); |
3457 ASSERT(right_range != NULL); | 3503 ASSERT(right_range != NULL); |
3458 ASSERT(result_min != NULL); | 3504 ASSERT(result_min != NULL); |
3459 ASSERT(result_max != NULL); | 3505 ASSERT(result_max != NULL); |
3460 | 3506 |
| 3507 // Both ranges are >= 0. |
| 3508 if ((Range::ConstantMin(left_range).ConstantValue() >= 0) && |
| 3509 (Range::ConstantMin(right_range).ConstantValue() >= 0)) { |
| 3510 *result_min = RangeBoundary::FromConstant(0); |
| 3511 // Take minimum value as new range. |
| 3512 *result_max = RangeBoundary::Min(Range::ConstantMax(left_range), |
| 3513 Range::ConstantMax(right_range), |
| 3514 RangeBoundary::kRangeBoundaryInt64); |
| 3515 return true; |
| 3516 } |
| 3517 |
| 3518 // Right range is >= 0. |
3461 if (Range::ConstantMin(right_range).ConstantValue() >= 0) { | 3519 if (Range::ConstantMin(right_range).ConstantValue() >= 0) { |
3462 *result_min = RangeBoundary::FromConstant(0); | 3520 *result_min = RangeBoundary::FromConstant(0); |
3463 *result_max = Range::ConstantMax(right_range); | 3521 *result_max = Range::ConstantMax(right_range); |
3464 return true; | 3522 return true; |
3465 } | 3523 } |
3466 | 3524 |
| 3525 // Left range is >= 0. |
3467 if (Range::ConstantMin(left_range).ConstantValue() >= 0) { | 3526 if (Range::ConstantMin(left_range).ConstantValue() >= 0) { |
3468 *result_min = RangeBoundary::FromConstant(0); | 3527 *result_min = RangeBoundary::FromConstant(0); |
3469 *result_max = Range::ConstantMax(left_range); | 3528 *result_max = Range::ConstantMax(left_range); |
3470 return true; | 3529 return true; |
3471 } | 3530 } |
3472 | 3531 |
3473 return false; | 3532 return false; |
3474 } | 3533 } |
3475 | 3534 |
3476 | 3535 |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3965 case Token::kTRUNCDIV: return 0; | 4024 case Token::kTRUNCDIV: return 0; |
3966 case Token::kMOD: return 1; | 4025 case Token::kMOD: return 1; |
3967 default: UNIMPLEMENTED(); return -1; | 4026 default: UNIMPLEMENTED(); return -1; |
3968 } | 4027 } |
3969 } | 4028 } |
3970 | 4029 |
3971 | 4030 |
3972 #undef __ | 4031 #undef __ |
3973 | 4032 |
3974 } // namespace dart | 4033 } // namespace dart |
OLD | NEW |