| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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/flow_graph_range_analysis.h" | 5 #include "vm/flow_graph_range_analysis.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/il_printer.h" | 8 #include "vm/il_printer.h" |
| 9 | 9 |
| 10 namespace dart { | 10 namespace dart { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 } | 243 } |
| 244 } | 244 } |
| 245 | 245 |
| 246 for (ForwardInstructionIterator instr_it(block); !instr_it.Done(); | 246 for (ForwardInstructionIterator instr_it(block); !instr_it.Done(); |
| 247 instr_it.Advance()) { | 247 instr_it.Advance()) { |
| 248 Instruction* current = instr_it.Current(); | 248 Instruction* current = instr_it.Current(); |
| 249 Definition* defn = current->AsDefinition(); | 249 Definition* defn = current->AsDefinition(); |
| 250 if (defn != NULL) { | 250 if (defn != NULL) { |
| 251 if (defn->HasSSATemp() && IsIntegerDefinition(defn)) { | 251 if (defn->HasSSATemp() && IsIntegerDefinition(defn)) { |
| 252 values_.Add(defn); | 252 values_.Add(defn); |
| 253 if (defn->IsBinaryMintOp()) { | 253 if (defn->IsBinaryInt64Op()) { |
| 254 binary_mint_ops_.Add(defn->AsBinaryMintOp()); | 254 binary_int64_ops_.Add(defn->AsBinaryInt64Op()); |
| 255 } else if (defn->IsShiftMintOp()) { | 255 } else if (defn->IsShiftInt64Op()) { |
| 256 shift_mint_ops_.Add(defn->AsShiftMintOp()); | 256 shift_int64_ops_.Add(defn->AsShiftInt64Op()); |
| 257 } | 257 } |
| 258 } | 258 } |
| 259 } else if (current->IsCheckArrayBound()) { | 259 } else if (current->IsCheckArrayBound()) { |
| 260 bounds_checks_.Add(current->AsCheckArrayBound()); | 260 bounds_checks_.Add(current->AsCheckArrayBound()); |
| 261 } | 261 } |
| 262 } | 262 } |
| 263 } | 263 } |
| 264 } | 264 } |
| 265 | 265 |
| 266 // For a comparison operation return an operation for the equivalent flipped | 266 // For a comparison operation return an operation for the equivalent flipped |
| (...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1493 // Some constraints might be constraining constraints. Unwind the chain of | 1493 // Some constraints might be constraining constraints. Unwind the chain of |
| 1494 // constraints until we reach the actual definition. | 1494 // constraints until we reach the actual definition. |
| 1495 while (def->IsConstraint()) { | 1495 while (def->IsConstraint()) { |
| 1496 def = def->AsConstraint()->value()->definition(); | 1496 def = def->AsConstraint()->value()->definition(); |
| 1497 } | 1497 } |
| 1498 constraints_[i]->ReplaceUsesWith(def); | 1498 constraints_[i]->ReplaceUsesWith(def); |
| 1499 constraints_[i]->RemoveFromGraph(); | 1499 constraints_[i]->RemoveFromGraph(); |
| 1500 } | 1500 } |
| 1501 } | 1501 } |
| 1502 | 1502 |
| 1503 static void NarrowBinaryMintOp(BinaryMintOpInstr* mint_op) { | 1503 static void NarrowBinaryInt64Op(BinaryInt64OpInstr* int64_op) { |
| 1504 if (RangeUtils::Fits(mint_op->range(), RangeBoundary::kRangeBoundaryInt32) && | 1504 if (RangeUtils::Fits(int64_op->range(), RangeBoundary::kRangeBoundaryInt32) && |
| 1505 RangeUtils::Fits(mint_op->left()->definition()->range(), | 1505 RangeUtils::Fits(int64_op->left()->definition()->range(), |
| 1506 RangeBoundary::kRangeBoundaryInt32) && | 1506 RangeBoundary::kRangeBoundaryInt32) && |
| 1507 RangeUtils::Fits(mint_op->right()->definition()->range(), | 1507 RangeUtils::Fits(int64_op->right()->definition()->range(), |
| 1508 RangeBoundary::kRangeBoundaryInt32) && | 1508 RangeBoundary::kRangeBoundaryInt32) && |
| 1509 BinaryInt32OpInstr::IsSupported(mint_op->op_kind(), mint_op->left(), | 1509 BinaryInt32OpInstr::IsSupported(int64_op->op_kind(), int64_op->left(), |
| 1510 mint_op->right())) { | 1510 int64_op->right())) { |
| 1511 BinaryInt32OpInstr* int32_op = new BinaryInt32OpInstr( | 1511 BinaryInt32OpInstr* int32_op = new BinaryInt32OpInstr( |
| 1512 mint_op->op_kind(), mint_op->left()->CopyWithType(), | 1512 int64_op->op_kind(), int64_op->left()->CopyWithType(), |
| 1513 mint_op->right()->CopyWithType(), mint_op->DeoptimizationTarget()); | 1513 int64_op->right()->CopyWithType(), int64_op->DeoptimizationTarget()); |
| 1514 int32_op->set_range(*mint_op->range()); | 1514 int32_op->set_range(*int64_op->range()); |
| 1515 int32_op->set_can_overflow(false); | 1515 int32_op->set_can_overflow(false); |
| 1516 mint_op->ReplaceWith(int32_op, NULL); | 1516 int64_op->ReplaceWith(int32_op, NULL); |
| 1517 } | 1517 } |
| 1518 } | 1518 } |
| 1519 | 1519 |
| 1520 static void NarrowShiftMintOp(ShiftMintOpInstr* mint_op) { | 1520 static void NarrowShiftInt64Op(ShiftInt64OpInstr* int64_op) { |
| 1521 if (RangeUtils::Fits(mint_op->range(), RangeBoundary::kRangeBoundaryInt32) && | 1521 if (RangeUtils::Fits(int64_op->range(), RangeBoundary::kRangeBoundaryInt32) && |
| 1522 RangeUtils::Fits(mint_op->left()->definition()->range(), | 1522 RangeUtils::Fits(int64_op->left()->definition()->range(), |
| 1523 RangeBoundary::kRangeBoundaryInt32) && | 1523 RangeBoundary::kRangeBoundaryInt32) && |
| 1524 RangeUtils::Fits(mint_op->right()->definition()->range(), | 1524 RangeUtils::Fits(int64_op->right()->definition()->range(), |
| 1525 RangeBoundary::kRangeBoundaryInt32) && | 1525 RangeBoundary::kRangeBoundaryInt32) && |
| 1526 BinaryInt32OpInstr::IsSupported(mint_op->op_kind(), mint_op->left(), | 1526 BinaryInt32OpInstr::IsSupported(int64_op->op_kind(), int64_op->left(), |
| 1527 mint_op->right())) { | 1527 int64_op->right())) { |
| 1528 BinaryInt32OpInstr* int32_op = new BinaryInt32OpInstr( | 1528 BinaryInt32OpInstr* int32_op = new BinaryInt32OpInstr( |
| 1529 mint_op->op_kind(), mint_op->left()->CopyWithType(), | 1529 int64_op->op_kind(), int64_op->left()->CopyWithType(), |
| 1530 mint_op->right()->CopyWithType(), mint_op->DeoptimizationTarget()); | 1530 int64_op->right()->CopyWithType(), int64_op->DeoptimizationTarget()); |
| 1531 int32_op->set_range(*mint_op->range()); | 1531 int32_op->set_range(*int64_op->range()); |
| 1532 int32_op->set_can_overflow(false); | 1532 int32_op->set_can_overflow(false); |
| 1533 mint_op->ReplaceWith(int32_op, NULL); | 1533 int64_op->ReplaceWith(int32_op, NULL); |
| 1534 } | 1534 } |
| 1535 } | 1535 } |
| 1536 | 1536 |
| 1537 void RangeAnalysis::NarrowMintToInt32() { | 1537 void RangeAnalysis::NarrowMintToInt32() { |
| 1538 for (intptr_t i = 0; i < binary_mint_ops_.length(); i++) { | 1538 for (intptr_t i = 0; i < binary_int64_ops_.length(); i++) { |
| 1539 NarrowBinaryMintOp(binary_mint_ops_[i]); | 1539 NarrowBinaryInt64Op(binary_int64_ops_[i]); |
| 1540 } | 1540 } |
| 1541 | 1541 |
| 1542 for (intptr_t i = 0; i < shift_mint_ops_.length(); i++) { | 1542 for (intptr_t i = 0; i < shift_int64_ops_.length(); i++) { |
| 1543 NarrowShiftMintOp(shift_mint_ops_[i]); | 1543 NarrowShiftInt64Op(shift_int64_ops_[i]); |
| 1544 } | 1544 } |
| 1545 } | 1545 } |
| 1546 | 1546 |
| 1547 IntegerInstructionSelector::IntegerInstructionSelector(FlowGraph* flow_graph) | 1547 IntegerInstructionSelector::IntegerInstructionSelector(FlowGraph* flow_graph) |
| 1548 : flow_graph_(flow_graph) { | 1548 : flow_graph_(flow_graph) { |
| 1549 ASSERT(flow_graph_ != NULL); | 1549 ASSERT(flow_graph_ != NULL); |
| 1550 zone_ = flow_graph_->zone(); | 1550 zone_ = flow_graph_->zone(); |
| 1551 selected_uint32_defs_ = | 1551 selected_uint32_defs_ = |
| 1552 new (zone_) BitVector(zone_, flow_graph_->current_ssa_temp_index()); | 1552 new (zone_) BitVector(zone_, flow_graph_->current_ssa_temp_index()); |
| 1553 } | 1553 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1564 THR_Print("---- after integer ir selection -------\n"); | 1564 THR_Print("---- after integer ir selection -------\n"); |
| 1565 FlowGraphPrinter printer(*flow_graph_); | 1565 FlowGraphPrinter printer(*flow_graph_); |
| 1566 printer.PrintBlocks(); | 1566 printer.PrintBlocks(); |
| 1567 } | 1567 } |
| 1568 } | 1568 } |
| 1569 | 1569 |
| 1570 bool IntegerInstructionSelector::IsPotentialUint32Definition(Definition* def) { | 1570 bool IntegerInstructionSelector::IsPotentialUint32Definition(Definition* def) { |
| 1571 // TODO(johnmccutchan): Consider Smi operations, to avoid unnecessary tagging | 1571 // TODO(johnmccutchan): Consider Smi operations, to avoid unnecessary tagging |
| 1572 // & untagged of intermediate results. | 1572 // & untagged of intermediate results. |
| 1573 // TODO(johnmccutchan): Consider phis. | 1573 // TODO(johnmccutchan): Consider phis. |
| 1574 return def->IsBoxInt64() || def->IsUnboxInt64() || def->IsBinaryMintOp() || | 1574 return def->IsBoxInt64() || def->IsUnboxInt64() || def->IsBinaryInt64Op() || |
| 1575 def->IsShiftMintOp() || def->IsUnaryMintOp(); | 1575 def->IsShiftInt64Op() || def->IsUnaryInt64Op(); |
| 1576 } | 1576 } |
| 1577 | 1577 |
| 1578 void IntegerInstructionSelector::FindPotentialUint32Definitions() { | 1578 void IntegerInstructionSelector::FindPotentialUint32Definitions() { |
| 1579 if (FLAG_trace_integer_ir_selection) { | 1579 if (FLAG_trace_integer_ir_selection) { |
| 1580 THR_Print("++++ Finding potential Uint32 definitions:\n"); | 1580 THR_Print("++++ Finding potential Uint32 definitions:\n"); |
| 1581 } | 1581 } |
| 1582 | 1582 |
| 1583 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator(); | 1583 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator(); |
| 1584 !block_it.Done(); block_it.Advance()) { | 1584 !block_it.Done(); block_it.Advance()) { |
| 1585 BlockEntryInstr* block = block_it.Current(); | 1585 BlockEntryInstr* block = block_it.Current(); |
| 1586 | 1586 |
| 1587 for (ForwardInstructionIterator instr_it(block); !instr_it.Done(); | 1587 for (ForwardInstructionIterator instr_it(block); !instr_it.Done(); |
| 1588 instr_it.Advance()) { | 1588 instr_it.Advance()) { |
| 1589 Instruction* current = instr_it.Current(); | 1589 Instruction* current = instr_it.Current(); |
| 1590 Definition* defn = current->AsDefinition(); | 1590 Definition* defn = current->AsDefinition(); |
| 1591 if ((defn != NULL) && defn->HasSSATemp()) { | 1591 if ((defn != NULL) && defn->HasSSATemp()) { |
| 1592 if (IsPotentialUint32Definition(defn)) { | 1592 if (IsPotentialUint32Definition(defn)) { |
| 1593 if (FLAG_support_il_printer && FLAG_trace_integer_ir_selection) { | 1593 if (FLAG_support_il_printer && FLAG_trace_integer_ir_selection) { |
| 1594 THR_Print("Adding %s\n", current->ToCString()); | 1594 THR_Print("Adding %s\n", current->ToCString()); |
| 1595 } | 1595 } |
| 1596 potential_uint32_defs_.Add(defn); | 1596 potential_uint32_defs_.Add(defn); |
| 1597 } | 1597 } |
| 1598 } | 1598 } |
| 1599 } | 1599 } |
| 1600 } | 1600 } |
| 1601 } | 1601 } |
| 1602 | 1602 |
| 1603 // BinaryMintOp masks and stores into unsigned typed arrays that truncate the | 1603 // BinaryInt64Op masks and stores into unsigned typed arrays that truncate the |
| 1604 // value into a Uint32 range. | 1604 // value into a Uint32 range. |
| 1605 bool IntegerInstructionSelector::IsUint32NarrowingDefinition(Definition* def) { | 1605 bool IntegerInstructionSelector::IsUint32NarrowingDefinition(Definition* def) { |
| 1606 if (def->IsBinaryMintOp()) { | 1606 if (def->IsBinaryInt64Op()) { |
| 1607 BinaryMintOpInstr* op = def->AsBinaryMintOp(); | 1607 BinaryInt64OpInstr* op = def->AsBinaryInt64Op(); |
| 1608 // Must be a mask operation. | 1608 // Must be a mask operation. |
| 1609 if (op->op_kind() != Token::kBIT_AND) { | 1609 if (op->op_kind() != Token::kBIT_AND) { |
| 1610 return false; | 1610 return false; |
| 1611 } | 1611 } |
| 1612 Range* range = op->range(); | 1612 Range* range = op->range(); |
| 1613 if ((range == NULL) || | 1613 if ((range == NULL) || |
| 1614 !range->IsWithin(0, static_cast<int64_t>(kMaxUint32))) { | 1614 !range->IsWithin(0, static_cast<int64_t>(kMaxUint32))) { |
| 1615 return false; | 1615 return false; |
| 1616 } | 1616 } |
| 1617 return true; | 1617 return true; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1651 | 1651 |
| 1652 bool IntegerInstructionSelector::CanBecomeUint32(Definition* def) { | 1652 bool IntegerInstructionSelector::CanBecomeUint32(Definition* def) { |
| 1653 ASSERT(IsPotentialUint32Definition(def)); | 1653 ASSERT(IsPotentialUint32Definition(def)); |
| 1654 if (def->IsBoxInt64()) { | 1654 if (def->IsBoxInt64()) { |
| 1655 // If a BoxInt64's input is a candidate, the box is a candidate. | 1655 // If a BoxInt64's input is a candidate, the box is a candidate. |
| 1656 Definition* box_input = def->AsBoxInt64()->value()->definition(); | 1656 Definition* box_input = def->AsBoxInt64()->value()->definition(); |
| 1657 return selected_uint32_defs_->Contains(box_input->ssa_temp_index()); | 1657 return selected_uint32_defs_->Contains(box_input->ssa_temp_index()); |
| 1658 } | 1658 } |
| 1659 // A right shift with an input outside of Uint32 range cannot be converted | 1659 // A right shift with an input outside of Uint32 range cannot be converted |
| 1660 // because we need the high bits. | 1660 // because we need the high bits. |
| 1661 if (def->IsShiftMintOp()) { | 1661 if (def->IsShiftInt64Op()) { |
| 1662 ShiftMintOpInstr* op = def->AsShiftMintOp(); | 1662 ShiftInt64OpInstr* op = def->AsShiftInt64Op(); |
| 1663 if (op->op_kind() == Token::kSHR) { | 1663 if (op->op_kind() == Token::kSHR) { |
| 1664 Definition* shift_input = op->left()->definition(); | 1664 Definition* shift_input = op->left()->definition(); |
| 1665 ASSERT(shift_input != NULL); | 1665 ASSERT(shift_input != NULL); |
| 1666 Range* range = shift_input->range(); | 1666 Range* range = shift_input->range(); |
| 1667 if ((range == NULL) || | 1667 if ((range == NULL) || |
| 1668 !range->IsWithin(0, static_cast<int64_t>(kMaxUint32))) { | 1668 !range->IsWithin(0, static_cast<int64_t>(kMaxUint32))) { |
| 1669 return false; | 1669 return false; |
| 1670 } | 1670 } |
| 1671 } | 1671 } |
| 1672 } | 1672 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1712 THR_Print("Reached fixed point\n"); | 1712 THR_Print("Reached fixed point\n"); |
| 1713 } | 1713 } |
| 1714 } | 1714 } |
| 1715 | 1715 |
| 1716 Definition* IntegerInstructionSelector::ConstructReplacementFor( | 1716 Definition* IntegerInstructionSelector::ConstructReplacementFor( |
| 1717 Definition* def) { | 1717 Definition* def) { |
| 1718 // Should only see mint definitions. | 1718 // Should only see mint definitions. |
| 1719 ASSERT(IsPotentialUint32Definition(def)); | 1719 ASSERT(IsPotentialUint32Definition(def)); |
| 1720 // Should not see constant instructions. | 1720 // Should not see constant instructions. |
| 1721 ASSERT(!def->IsConstant()); | 1721 ASSERT(!def->IsConstant()); |
| 1722 if (def->IsBinaryMintOp()) { | 1722 if (def->IsBinaryInt64Op()) { |
| 1723 BinaryMintOpInstr* op = def->AsBinaryMintOp(); | 1723 BinaryInt64OpInstr* op = def->AsBinaryInt64Op(); |
| 1724 Token::Kind op_kind = op->op_kind(); | 1724 Token::Kind op_kind = op->op_kind(); |
| 1725 Value* left = op->left()->CopyWithType(); | 1725 Value* left = op->left()->CopyWithType(); |
| 1726 Value* right = op->right()->CopyWithType(); | 1726 Value* right = op->right()->CopyWithType(); |
| 1727 intptr_t deopt_id = op->DeoptimizationTarget(); | 1727 intptr_t deopt_id = op->DeoptimizationTarget(); |
| 1728 return new (Z) BinaryUint32OpInstr(op_kind, left, right, deopt_id); | 1728 return new (Z) BinaryUint32OpInstr(op_kind, left, right, deopt_id); |
| 1729 } else if (def->IsBoxInt64()) { | 1729 } else if (def->IsBoxInt64()) { |
| 1730 Value* value = def->AsBoxInt64()->value()->CopyWithType(); | 1730 Value* value = def->AsBoxInt64()->value()->CopyWithType(); |
| 1731 return new (Z) BoxUint32Instr(value); | 1731 return new (Z) BoxUint32Instr(value); |
| 1732 } else if (def->IsUnboxInt64()) { | 1732 } else if (def->IsUnboxInt64()) { |
| 1733 UnboxInstr* unbox = def->AsUnboxInt64(); | 1733 UnboxInstr* unbox = def->AsUnboxInt64(); |
| 1734 Value* value = unbox->value()->CopyWithType(); | 1734 Value* value = unbox->value()->CopyWithType(); |
| 1735 intptr_t deopt_id = unbox->DeoptimizationTarget(); | 1735 intptr_t deopt_id = unbox->DeoptimizationTarget(); |
| 1736 return new (Z) UnboxUint32Instr(value, deopt_id); | 1736 return new (Z) UnboxUint32Instr(value, deopt_id); |
| 1737 } else if (def->IsUnaryMintOp()) { | 1737 } else if (def->IsUnaryInt64Op()) { |
| 1738 UnaryMintOpInstr* op = def->AsUnaryMintOp(); | 1738 UnaryInt64OpInstr* op = def->AsUnaryInt64Op(); |
| 1739 Token::Kind op_kind = op->op_kind(); | 1739 Token::Kind op_kind = op->op_kind(); |
| 1740 Value* value = op->value()->CopyWithType(); | 1740 Value* value = op->value()->CopyWithType(); |
| 1741 intptr_t deopt_id = op->DeoptimizationTarget(); | 1741 intptr_t deopt_id = op->DeoptimizationTarget(); |
| 1742 return new (Z) UnaryUint32OpInstr(op_kind, value, deopt_id); | 1742 return new (Z) UnaryUint32OpInstr(op_kind, value, deopt_id); |
| 1743 } else if (def->IsShiftMintOp()) { | 1743 } else if (def->IsShiftInt64Op()) { |
| 1744 ShiftMintOpInstr* op = def->AsShiftMintOp(); | 1744 ShiftInt64OpInstr* op = def->AsShiftInt64Op(); |
| 1745 Token::Kind op_kind = op->op_kind(); | 1745 Token::Kind op_kind = op->op_kind(); |
| 1746 Value* left = op->left()->CopyWithType(); | 1746 Value* left = op->left()->CopyWithType(); |
| 1747 Value* right = op->right()->CopyWithType(); | 1747 Value* right = op->right()->CopyWithType(); |
| 1748 intptr_t deopt_id = op->DeoptimizationTarget(); | 1748 intptr_t deopt_id = op->DeoptimizationTarget(); |
| 1749 return new (Z) ShiftUint32OpInstr(op_kind, left, right, deopt_id); | 1749 return new (Z) ShiftUint32OpInstr(op_kind, left, right, deopt_id); |
| 1750 } | 1750 } |
| 1751 UNREACHABLE(); | 1751 UNREACHABLE(); |
| 1752 return NULL; | 1752 return NULL; |
| 1753 } | 1753 } |
| 1754 | 1754 |
| (...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2746 *range = | 2746 *range = |
| 2747 Range(RangeBoundary::FromConstant(min), RangeBoundary::FromConstant(max)); | 2747 Range(RangeBoundary::FromConstant(min), RangeBoundary::FromConstant(max)); |
| 2748 } | 2748 } |
| 2749 | 2749 |
| 2750 static RangeBoundary::RangeSize RepresentationToRangeSize(Representation r) { | 2750 static RangeBoundary::RangeSize RepresentationToRangeSize(Representation r) { |
| 2751 switch (r) { | 2751 switch (r) { |
| 2752 case kTagged: | 2752 case kTagged: |
| 2753 return RangeBoundary::kRangeBoundarySmi; | 2753 return RangeBoundary::kRangeBoundarySmi; |
| 2754 case kUnboxedInt32: | 2754 case kUnboxedInt32: |
| 2755 return RangeBoundary::kRangeBoundaryInt32; | 2755 return RangeBoundary::kRangeBoundaryInt32; |
| 2756 case kUnboxedMint: | 2756 case kUnboxedInt64: |
| 2757 return RangeBoundary::kRangeBoundaryInt64; | 2757 return RangeBoundary::kRangeBoundaryInt64; |
| 2758 default: | 2758 default: |
| 2759 UNREACHABLE(); | 2759 UNREACHABLE(); |
| 2760 return RangeBoundary::kRangeBoundarySmi; | 2760 return RangeBoundary::kRangeBoundarySmi; |
| 2761 } | 2761 } |
| 2762 } | 2762 } |
| 2763 | 2763 |
| 2764 void BinaryIntegerOpInstr::InferRangeHelper(const Range* left_range, | 2764 void BinaryIntegerOpInstr::InferRangeHelper(const Range* left_range, |
| 2765 const Range* right_range, | 2765 const Range* right_range, |
| 2766 Range* range) { | 2766 Range* range) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2811 RangeBoundary::kRangeBoundarySmi); | 2811 RangeBoundary::kRangeBoundarySmi); |
| 2812 } | 2812 } |
| 2813 InferRangeHelper(analysis->GetSmiRange(left()), right_smi_range, range); | 2813 InferRangeHelper(analysis->GetSmiRange(left()), right_smi_range, range); |
| 2814 } | 2814 } |
| 2815 | 2815 |
| 2816 void BinaryInt32OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2816 void BinaryInt32OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| 2817 InferRangeHelper(analysis->GetSmiRange(left()), | 2817 InferRangeHelper(analysis->GetSmiRange(left()), |
| 2818 analysis->GetSmiRange(right()), range); | 2818 analysis->GetSmiRange(right()), range); |
| 2819 } | 2819 } |
| 2820 | 2820 |
| 2821 void BinaryMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2821 void BinaryInt64OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| 2822 InferRangeHelper(left()->definition()->range(), | 2822 InferRangeHelper(left()->definition()->range(), |
| 2823 right()->definition()->range(), range); | 2823 right()->definition()->range(), range); |
| 2824 } | 2824 } |
| 2825 | 2825 |
| 2826 void ShiftMintOpInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2826 void ShiftInt64OpInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| 2827 CacheRange(&shift_range_, right()->definition()->range(), | 2827 CacheRange(&shift_range_, right()->definition()->range(), |
| 2828 RangeBoundary::kRangeBoundaryInt64); | 2828 RangeBoundary::kRangeBoundaryInt64); |
| 2829 InferRangeHelper(left()->definition()->range(), | 2829 InferRangeHelper(left()->definition()->range(), |
| 2830 right()->definition()->range(), range); | 2830 right()->definition()->range(), range); |
| 2831 } | 2831 } |
| 2832 | 2832 |
| 2833 void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) { | 2833 void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) { |
| 2834 const Range* value_range = value()->definition()->range(); | 2834 const Range* value_range = value()->definition()->range(); |
| 2835 if (!Range::IsUnknown(value_range)) { | 2835 if (!Range::IsUnknown(value_range)) { |
| 2836 *range = *value_range; | 2836 *range = *value_range; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2883 if (value_range != NULL) { | 2883 if (value_range != NULL) { |
| 2884 *range = *value_range; | 2884 *range = *value_range; |
| 2885 } else if (!value()->definition()->IsMintDefinition() && | 2885 } else if (!value()->definition()->IsMintDefinition() && |
| 2886 (value()->definition()->Type()->ToCid() != kSmiCid)) { | 2886 (value()->definition()->Type()->ToCid() != kSmiCid)) { |
| 2887 *range = Range::Full(RangeBoundary::kRangeBoundaryInt64); | 2887 *range = Range::Full(RangeBoundary::kRangeBoundaryInt64); |
| 2888 } | 2888 } |
| 2889 } | 2889 } |
| 2890 | 2890 |
| 2891 void UnboxedIntConverterInstr::InferRange(RangeAnalysis* analysis, | 2891 void UnboxedIntConverterInstr::InferRange(RangeAnalysis* analysis, |
| 2892 Range* range) { | 2892 Range* range) { |
| 2893 ASSERT((from() == kUnboxedInt32) || (from() == kUnboxedMint) || | 2893 ASSERT((from() == kUnboxedInt32) || (from() == kUnboxedInt64) || |
| 2894 (from() == kUnboxedUint32)); | 2894 (from() == kUnboxedUint32)); |
| 2895 ASSERT((to() == kUnboxedInt32) || (to() == kUnboxedMint) || | 2895 ASSERT((to() == kUnboxedInt32) || (to() == kUnboxedInt64) || |
| 2896 (to() == kUnboxedUint32)); | 2896 (to() == kUnboxedUint32)); |
| 2897 const Range* value_range = value()->definition()->range(); | 2897 const Range* value_range = value()->definition()->range(); |
| 2898 if (Range::IsUnknown(value_range)) { | 2898 if (Range::IsUnknown(value_range)) { |
| 2899 return; | 2899 return; |
| 2900 } | 2900 } |
| 2901 | 2901 |
| 2902 if (to() == kUnboxedUint32) { | 2902 if (to() == kUnboxedUint32) { |
| 2903 // TODO(vegorov): improve range information for unboxing to Uint32. | 2903 // TODO(vegorov): improve range information for unboxing to Uint32. |
| 2904 *range = | 2904 *range = |
| 2905 Range(RangeBoundary::FromConstant(0), | 2905 Range(RangeBoundary::FromConstant(0), |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2959 return max.offset() < canonical_length.offset(); | 2959 return max.offset() < canonical_length.offset(); |
| 2960 } | 2960 } |
| 2961 } while (CanonicalizeMaxBoundary(&max) || | 2961 } while (CanonicalizeMaxBoundary(&max) || |
| 2962 CanonicalizeMinBoundary(&canonical_length)); | 2962 CanonicalizeMinBoundary(&canonical_length)); |
| 2963 | 2963 |
| 2964 // Failed to prove that maximum is bounded with array length. | 2964 // Failed to prove that maximum is bounded with array length. |
| 2965 return false; | 2965 return false; |
| 2966 } | 2966 } |
| 2967 | 2967 |
| 2968 } // namespace dart | 2968 } // namespace dart |
| OLD | NEW |