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/dart_entry.h" | 9 #include "vm/dart_entry.h" |
10 #include "vm/flow_graph_allocator.h" | 10 #include "vm/flow_graph_allocator.h" |
(...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1448 value()->Type()->IsAssignableTo(dst_type())) { | 1448 value()->Type()->IsAssignableTo(dst_type())) { |
1449 return value()->definition(); | 1449 return value()->definition(); |
1450 } | 1450 } |
1451 ConstantInstr* null_constant = flow_graph->constant_null(); | 1451 ConstantInstr* null_constant = flow_graph->constant_null(); |
1452 instantiator_type_arguments()->BindTo(null_constant); | 1452 instantiator_type_arguments()->BindTo(null_constant); |
1453 } | 1453 } |
1454 return this; | 1454 return this; |
1455 } | 1455 } |
1456 | 1456 |
1457 | 1457 |
| 1458 LocationSummary* DebugStepCheckInstr::MakeLocationSummary(bool opt) const { |
| 1459 const intptr_t kNumInputs = 0; |
| 1460 const intptr_t kNumTemps = 0; |
| 1461 LocationSummary* locs = |
| 1462 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1463 return locs; |
| 1464 } |
| 1465 |
| 1466 |
| 1467 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1468 ASSERT(!compiler->is_optimizing()); |
| 1469 const ExternalLabel label("debug_step_check", |
| 1470 StubCode::DebugStepCheckEntryPoint()); |
| 1471 compiler->GenerateCall(token_pos(), |
| 1472 &label, |
| 1473 PcDescriptors::kReturn, |
| 1474 locs()); |
| 1475 } |
| 1476 |
| 1477 |
| 1478 Instruction* DebugStepCheckInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1479 return NULL; |
| 1480 } |
| 1481 |
| 1482 |
1458 Definition* BoxDoubleInstr::Canonicalize(FlowGraph* flow_graph) { | 1483 Definition* BoxDoubleInstr::Canonicalize(FlowGraph* flow_graph) { |
1459 if (input_use_list() == NULL) { | 1484 if (input_use_list() == NULL) { |
1460 // Environments can accomodate any representation. No need to box. | 1485 // Environments can accomodate any representation. No need to box. |
1461 return value()->definition(); | 1486 return value()->definition(); |
1462 } | 1487 } |
1463 | 1488 |
1464 // Fold away BoxDouble(UnboxDouble(v)) if value is known to be double. | 1489 // Fold away BoxDouble(UnboxDouble(v)) if value is known to be double. |
1465 UnboxDoubleInstr* defn = value()->definition()->AsUnboxDouble(); | 1490 UnboxDoubleInstr* defn = value()->definition()->AsUnboxDouble(); |
1466 if ((defn != NULL) && (defn->value()->Type()->ToCid() == kDoubleCid)) { | 1491 if ((defn != NULL) && (defn->value()->Type()->ToCid() == kDoubleCid)) { |
1467 return defn->value()->definition(); | 1492 return defn->value()->definition(); |
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2611 return false; | 2636 return false; |
2612 } | 2637 } |
2613 | 2638 |
2614 | 2639 |
2615 static bool IsArrayLength(Definition* defn) { | 2640 static bool IsArrayLength(Definition* defn) { |
2616 LoadFieldInstr* load = defn->AsLoadField(); | 2641 LoadFieldInstr* load = defn->AsLoadField(); |
2617 return (load != NULL) && load->IsImmutableLengthLoad(); | 2642 return (load != NULL) && load->IsImmutableLengthLoad(); |
2618 } | 2643 } |
2619 | 2644 |
2620 | 2645 |
| 2646 static int64_t ConstantAbsMax(const Range* range) { |
| 2647 if (range == NULL) return Smi::kMaxValue; |
| 2648 const int64_t abs_min = Utils::Abs(Range::ConstantMin(range).value()); |
| 2649 const int64_t abs_max = Utils::Abs(Range::ConstantMax(range).value()); |
| 2650 return abs_min > abs_max ? abs_min : abs_max; |
| 2651 } |
| 2652 |
| 2653 |
| 2654 static bool OnlyPositiveOrZero(const Range* a, const Range* b) { |
| 2655 if ((a == NULL) || (b == NULL)) return false; |
| 2656 if (Range::ConstantMin(a).value() < 0) return false; |
| 2657 if (Range::ConstantMin(b).value() < 0) return false; |
| 2658 return true; |
| 2659 } |
| 2660 |
| 2661 |
| 2662 static bool OnlyNegativeOrZero(const Range* a, const Range* b) { |
| 2663 if ((a == NULL) || (b == NULL)) return false; |
| 2664 if (Range::ConstantMax(a).value() > 0) return false; |
| 2665 if (Range::ConstantMax(b).value() > 0) return false; |
| 2666 return true; |
| 2667 } |
| 2668 |
| 2669 |
2621 void BinarySmiOpInstr::InferRange() { | 2670 void BinarySmiOpInstr::InferRange() { |
2622 // TODO(vegorov): canonicalize BinarySmiOp to always have constant on the | 2671 // TODO(vegorov): canonicalize BinarySmiOp to always have constant on the |
2623 // right and a non-constant on the left. | 2672 // right and a non-constant on the left. |
2624 Definition* left_defn = left()->definition(); | 2673 Definition* left_defn = left()->definition(); |
2625 | 2674 |
2626 Range* left_range = left_defn->range(); | 2675 Range* left_range = left_defn->range(); |
2627 Range* right_range = right()->definition()->range(); | 2676 Range* right_range = right()->definition()->range(); |
2628 | 2677 |
2629 if ((left_range == NULL) || (right_range == NULL)) { | 2678 if ((left_range == NULL) || (right_range == NULL)) { |
2630 range_ = new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); | 2679 range_ = new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2667 } | 2716 } |
2668 | 2717 |
2669 if (!SymbolicSub(left_max, right_range->min(), &max)) { | 2718 if (!SymbolicSub(left_max, right_range->min(), &max)) { |
2670 max = | 2719 max = |
2671 RangeBoundary::Sub(Range::ConstantMax(left_range), | 2720 RangeBoundary::Sub(Range::ConstantMax(left_range), |
2672 Range::ConstantMin(right_range), | 2721 Range::ConstantMin(right_range), |
2673 RangeBoundary::OverflowedMaxSmi()); | 2722 RangeBoundary::OverflowedMaxSmi()); |
2674 } | 2723 } |
2675 break; | 2724 break; |
2676 | 2725 |
| 2726 case Token::kMUL: { |
| 2727 const int64_t left_max = ConstantAbsMax(left_range); |
| 2728 const int64_t right_max = ConstantAbsMax(right_range); |
| 2729 if ((left_max < 0x7FFFFFFF) && (right_max < 0x7FFFFFFF)) { |
| 2730 // Product of left and right max values stays in 64 bit range. |
| 2731 const int64_t result_max = left_max * right_max; |
| 2732 if (Smi::IsValid64(result_max) && Smi::IsValid64(-result_max)) { |
| 2733 const intptr_t r_min = |
| 2734 OnlyPositiveOrZero(left_range, right_range) ? 0 : -result_max; |
| 2735 min = RangeBoundary::FromConstant(r_min); |
| 2736 const intptr_t r_max = |
| 2737 OnlyNegativeOrZero(left_range, right_range) ? 0 : result_max; |
| 2738 max = RangeBoundary::FromConstant(r_max); |
| 2739 break; |
| 2740 } |
| 2741 } |
| 2742 if (range_ == NULL) { |
| 2743 range_ = Range::Unknown(); |
| 2744 } |
| 2745 return; |
| 2746 } |
2677 case Token::kBIT_AND: | 2747 case Token::kBIT_AND: |
2678 if (Range::ConstantMin(right_range).value() >= 0) { | 2748 if (Range::ConstantMin(right_range).value() >= 0) { |
2679 min = RangeBoundary::FromConstant(0); | 2749 min = RangeBoundary::FromConstant(0); |
2680 max = Range::ConstantMax(right_range); | 2750 max = Range::ConstantMax(right_range); |
2681 break; | 2751 break; |
2682 } | 2752 } |
2683 if (Range::ConstantMin(left_range).value() >= 0) { | 2753 if (Range::ConstantMin(left_range).value() >= 0) { |
2684 min = RangeBoundary::FromConstant(0); | 2754 min = RangeBoundary::FromConstant(0); |
2685 max = Range::ConstantMax(left_range); | 2755 max = Range::ConstantMax(left_range); |
2686 break; | 2756 break; |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3028 case Token::kTRUNCDIV: return 0; | 3098 case Token::kTRUNCDIV: return 0; |
3029 case Token::kMOD: return 1; | 3099 case Token::kMOD: return 1; |
3030 default: UNIMPLEMENTED(); return -1; | 3100 default: UNIMPLEMENTED(); return -1; |
3031 } | 3101 } |
3032 } | 3102 } |
3033 | 3103 |
3034 | 3104 |
3035 #undef __ | 3105 #undef __ |
3036 | 3106 |
3037 } // namespace dart | 3107 } // namespace dart |
OLD | NEW |