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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3403 | 3449 |
3404 bool Range::And(const Range* left_range, | 3450 bool Range::And(const Range* left_range, |
3405 const Range* right_range, | 3451 const Range* right_range, |
3406 RangeBoundary* result_min, | 3452 RangeBoundary* result_min, |
3407 RangeBoundary* result_max) { | 3453 RangeBoundary* result_max) { |
3408 ASSERT(left_range != NULL); | 3454 ASSERT(left_range != NULL); |
3409 ASSERT(right_range != NULL); | 3455 ASSERT(right_range != NULL); |
3410 ASSERT(result_min != NULL); | 3456 ASSERT(result_min != NULL); |
3411 ASSERT(result_max != NULL); | 3457 ASSERT(result_max != NULL); |
3412 | 3458 |
| 3459 // Both ranges are >= 0. |
| 3460 if ((Range::ConstantMin(left_range).ConstantValue() >= 0) && |
| 3461 (Range::ConstantMin(right_range).ConstantValue() >= 0)) { |
| 3462 *result_min = RangeBoundary::FromConstant(0); |
| 3463 // Take minimum value as new range. |
| 3464 *result_max = RangeBoundary::Min(Range::ConstantMax(left_range), |
| 3465 Range::ConstantMax(right_range), |
| 3466 RangeBoundary::kRangeBoundaryInt64); |
| 3467 return true; |
| 3468 } |
| 3469 |
| 3470 // Right range is >= 0. |
3413 if (Range::ConstantMin(right_range).ConstantValue() >= 0) { | 3471 if (Range::ConstantMin(right_range).ConstantValue() >= 0) { |
3414 *result_min = RangeBoundary::FromConstant(0); | 3472 *result_min = RangeBoundary::FromConstant(0); |
3415 *result_max = Range::ConstantMax(right_range); | 3473 *result_max = Range::ConstantMax(right_range); |
3416 return true; | 3474 return true; |
3417 } | 3475 } |
3418 | 3476 |
| 3477 // Left range is >= 0. |
3419 if (Range::ConstantMin(left_range).ConstantValue() >= 0) { | 3478 if (Range::ConstantMin(left_range).ConstantValue() >= 0) { |
3420 *result_min = RangeBoundary::FromConstant(0); | 3479 *result_min = RangeBoundary::FromConstant(0); |
3421 *result_max = Range::ConstantMax(left_range); | 3480 *result_max = Range::ConstantMax(left_range); |
3422 return true; | 3481 return true; |
3423 } | 3482 } |
3424 | 3483 |
3425 return false; | 3484 return false; |
3426 } | 3485 } |
3427 | 3486 |
3428 | 3487 |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3917 case Token::kTRUNCDIV: return 0; | 3976 case Token::kTRUNCDIV: return 0; |
3918 case Token::kMOD: return 1; | 3977 case Token::kMOD: return 1; |
3919 default: UNIMPLEMENTED(); return -1; | 3978 default: UNIMPLEMENTED(); return -1; |
3920 } | 3979 } |
3921 } | 3980 } |
3922 | 3981 |
3923 | 3982 |
3924 #undef __ | 3983 #undef __ |
3925 | 3984 |
3926 } // namespace dart | 3985 } // namespace dart |
OLD | NEW |