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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 JoinEntryInstr* join = block->AsJoinEntry(); | 177 JoinEntryInstr* join = block->AsJoinEntry(); |
178 if (join != NULL && join->loop_info() != NULL) { | 178 if (join != NULL && join->loop_info() != NULL) { |
179 loop_variables.Clear(); | 179 loop_variables.Clear(); |
180 | 180 |
181 for (PhiIterator phi_it(join); !phi_it.Done(); phi_it.Advance()) { | 181 for (PhiIterator phi_it(join); !phi_it.Done(); phi_it.Advance()) { |
182 PhiInstr* current = phi_it.Current(); | 182 PhiInstr* current = phi_it.Current(); |
183 | 183 |
184 InductionVariableInfo* info = DetectSimpleInductionVariable(current); | 184 InductionVariableInfo* info = DetectSimpleInductionVariable(current); |
185 if (info != NULL) { | 185 if (info != NULL) { |
186 if (FLAG_trace_range_analysis) { | 186 if (FLAG_trace_range_analysis) { |
187 ISL_Print("Simple loop variable: %s bound <%s>\n", | 187 THR_Print("Simple loop variable: %s bound <%s>\n", |
188 current->ToCString(), | 188 current->ToCString(), |
189 info->limit() != NULL ? | 189 info->limit() != NULL ? |
190 info->limit()->ToCString() : "?"); | 190 info->limit()->ToCString() : "?"); |
191 } | 191 } |
192 | 192 |
193 loop_variables.Add(info); | 193 loop_variables.Add(info); |
194 } | 194 } |
195 } | 195 } |
196 } | 196 } |
197 | 197 |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 range = Range(WidenMin(defn->range(), &range, size), | 687 range = Range(WidenMin(defn->range(), &range, size), |
688 WidenMax(defn->range(), &range, size)); | 688 WidenMax(defn->range(), &range, size)); |
689 } else if (op == NARROW) { | 689 } else if (op == NARROW) { |
690 range = Range(NarrowMin(defn->range(), &range, size), | 690 range = Range(NarrowMin(defn->range(), &range, size), |
691 NarrowMax(defn->range(), &range, size)); | 691 NarrowMax(defn->range(), &range, size)); |
692 } | 692 } |
693 } | 693 } |
694 | 694 |
695 if (!range.Equals(defn->range())) { | 695 if (!range.Equals(defn->range())) { |
696 if (FLAG_trace_range_analysis) { | 696 if (FLAG_trace_range_analysis) { |
697 ISL_Print("%c [%" Pd "] %s: %s => %s\n", | 697 THR_Print("%c [%" Pd "] %s: %s => %s\n", |
698 OpPrefix(op), | 698 OpPrefix(op), |
699 iteration, | 699 iteration, |
700 defn->ToCString(), | 700 defn->ToCString(), |
701 Range::ToCString(defn->range()), | 701 Range::ToCString(defn->range()), |
702 Range::ToCString(&range)); | 702 Range::ToCString(&range)); |
703 } | 703 } |
704 defn->set_range(range); | 704 defn->set_range(range); |
705 return true; | 705 return true; |
706 } | 706 } |
707 } | 707 } |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 flow_graph_(flow_graph), | 990 flow_graph_(flow_graph), |
991 scheduler_(flow_graph) { } | 991 scheduler_(flow_graph) { } |
992 | 992 |
993 void TryGeneralize(CheckArrayBoundInstr* check, | 993 void TryGeneralize(CheckArrayBoundInstr* check, |
994 const RangeBoundary& array_length) { | 994 const RangeBoundary& array_length) { |
995 Definition* upper_bound = | 995 Definition* upper_bound = |
996 ConstructUpperBound(check->index()->definition(), check); | 996 ConstructUpperBound(check->index()->definition(), check); |
997 if (upper_bound == UnwrapConstraint(check->index()->definition())) { | 997 if (upper_bound == UnwrapConstraint(check->index()->definition())) { |
998 // Unable to construct upper bound for the index. | 998 // Unable to construct upper bound for the index. |
999 if (FLAG_trace_range_analysis) { | 999 if (FLAG_trace_range_analysis) { |
1000 ISL_Print("Failed to construct upper bound for %s index\n", | 1000 THR_Print("Failed to construct upper bound for %s index\n", |
1001 check->ToCString()); | 1001 check->ToCString()); |
1002 } | 1002 } |
1003 return; | 1003 return; |
1004 } | 1004 } |
1005 | 1005 |
1006 // Re-associate subexpressions inside upper_bound to collect all constants | 1006 // Re-associate subexpressions inside upper_bound to collect all constants |
1007 // together. This will expose more redundancies when we are going to emit | 1007 // together. This will expose more redundancies when we are going to emit |
1008 // upper bound through scheduler. | 1008 // upper bound through scheduler. |
1009 if (!Simplify(&upper_bound, NULL)) { | 1009 if (!Simplify(&upper_bound, NULL)) { |
1010 if (FLAG_trace_range_analysis) { | 1010 if (FLAG_trace_range_analysis) { |
1011 ISL_Print("Failed to simplify upper bound for %s index\n", | 1011 THR_Print("Failed to simplify upper bound for %s index\n", |
1012 check->ToCString()); | 1012 check->ToCString()); |
1013 } | 1013 } |
1014 return; | 1014 return; |
1015 } | 1015 } |
1016 upper_bound = ApplyConstraints(upper_bound, check); | 1016 upper_bound = ApplyConstraints(upper_bound, check); |
1017 range_analysis_->AssignRangesRecursively(upper_bound); | 1017 range_analysis_->AssignRangesRecursively(upper_bound); |
1018 | 1018 |
1019 // We are going to constrain any symbols participating in + and * operations | 1019 // We are going to constrain any symbols participating in + and * operations |
1020 // to guarantee that they are positive. Find all symbols that need | 1020 // to guarantee that they are positive. Find all symbols that need |
1021 // constraining. If there is a subtraction subexpression with non-positive | 1021 // constraining. If there is a subtraction subexpression with non-positive |
1022 // range give up on generalization for simplicity. | 1022 // range give up on generalization for simplicity. |
1023 GrowableArray<Definition*> non_positive_symbols; | 1023 GrowableArray<Definition*> non_positive_symbols; |
1024 if (!FindNonPositiveSymbols(&non_positive_symbols, upper_bound)) { | 1024 if (!FindNonPositiveSymbols(&non_positive_symbols, upper_bound)) { |
1025 if (FLAG_trace_range_analysis) { | 1025 if (FLAG_trace_range_analysis) { |
1026 ISL_Print("Failed to generalize %s index to %s" | 1026 THR_Print("Failed to generalize %s index to %s" |
1027 " (can't ensure positivity)\n", | 1027 " (can't ensure positivity)\n", |
1028 check->ToCString(), | 1028 check->ToCString(), |
1029 IndexBoundToCString(upper_bound)); | 1029 IndexBoundToCString(upper_bound)); |
1030 } | 1030 } |
1031 return; | 1031 return; |
1032 } | 1032 } |
1033 | 1033 |
1034 // Check that we can statically prove that lower bound of the index is | 1034 // Check that we can statically prove that lower bound of the index is |
1035 // non-negative under the assumption that all potentially non-positive | 1035 // non-negative under the assumption that all potentially non-positive |
1036 // symbols are positive. | 1036 // symbols are positive. |
(...skipping 13 matching lines...) Expand all Loading... |
1050 ConstructLowerBound(check->index()->definition(), check); | 1050 ConstructLowerBound(check->index()->definition(), check); |
1051 // No need to simplify lower bound before applying constraints as | 1051 // No need to simplify lower bound before applying constraints as |
1052 // we are not going to emit it. | 1052 // we are not going to emit it. |
1053 lower_bound = ApplyConstraints(lower_bound, check, &positive_constraints); | 1053 lower_bound = ApplyConstraints(lower_bound, check, &positive_constraints); |
1054 range_analysis_->AssignRangesRecursively(lower_bound); | 1054 range_analysis_->AssignRangesRecursively(lower_bound); |
1055 | 1055 |
1056 if (!RangeUtils::IsPositive(lower_bound->range())) { | 1056 if (!RangeUtils::IsPositive(lower_bound->range())) { |
1057 // Can't prove that lower bound is positive even with additional checks | 1057 // Can't prove that lower bound is positive even with additional checks |
1058 // against potentially non-positive symbols. Give up. | 1058 // against potentially non-positive symbols. Give up. |
1059 if (FLAG_trace_range_analysis) { | 1059 if (FLAG_trace_range_analysis) { |
1060 ISL_Print("Failed to generalize %s index to %s" | 1060 THR_Print("Failed to generalize %s index to %s" |
1061 " (lower bound is not positive)\n", | 1061 " (lower bound is not positive)\n", |
1062 check->ToCString(), | 1062 check->ToCString(), |
1063 IndexBoundToCString(upper_bound)); | 1063 IndexBoundToCString(upper_bound)); |
1064 } | 1064 } |
1065 return; | 1065 return; |
1066 } | 1066 } |
1067 | 1067 |
1068 if (FLAG_trace_range_analysis) { | 1068 if (FLAG_trace_range_analysis) { |
1069 ISL_Print("For %s computed index bounds [%s, %s]\n", | 1069 THR_Print("For %s computed index bounds [%s, %s]\n", |
1070 check->ToCString(), | 1070 check->ToCString(), |
1071 IndexBoundToCString(lower_bound), | 1071 IndexBoundToCString(lower_bound), |
1072 IndexBoundToCString(upper_bound)); | 1072 IndexBoundToCString(upper_bound)); |
1073 } | 1073 } |
1074 | 1074 |
1075 // At this point we know that 0 <= index < UpperBound(index) under | 1075 // At this point we know that 0 <= index < UpperBound(index) under |
1076 // certain preconditions. Start by emitting this preconditions. | 1076 // certain preconditions. Start by emitting this preconditions. |
1077 scheduler_.Start(); | 1077 scheduler_.Start(); |
1078 | 1078 |
1079 ConstantInstr* max_smi = | 1079 ConstantInstr* max_smi = |
1080 flow_graph_->GetConstant(Smi::Handle(Smi::New(Smi::kMaxValue))); | 1080 flow_graph_->GetConstant(Smi::Handle(Smi::New(Smi::kMaxValue))); |
1081 for (intptr_t i = 0; i < non_positive_symbols.length(); i++) { | 1081 for (intptr_t i = 0; i < non_positive_symbols.length(); i++) { |
1082 CheckArrayBoundInstr* precondition = new CheckArrayBoundInstr( | 1082 CheckArrayBoundInstr* precondition = new CheckArrayBoundInstr( |
1083 new Value(max_smi), | 1083 new Value(max_smi), |
1084 new Value(non_positive_symbols[i]), | 1084 new Value(non_positive_symbols[i]), |
1085 Isolate::kNoDeoptId); | 1085 Isolate::kNoDeoptId); |
1086 precondition->mark_generalized(); | 1086 precondition->mark_generalized(); |
1087 precondition = scheduler_.Emit(precondition, check); | 1087 precondition = scheduler_.Emit(precondition, check); |
1088 if (precondition == NULL) { | 1088 if (precondition == NULL) { |
1089 if (FLAG_trace_range_analysis) { | 1089 if (FLAG_trace_range_analysis) { |
1090 ISL_Print(" => failed to insert positivity constraint\n"); | 1090 THR_Print(" => failed to insert positivity constraint\n"); |
1091 } | 1091 } |
1092 scheduler_.Rollback(); | 1092 scheduler_.Rollback(); |
1093 return; | 1093 return; |
1094 } | 1094 } |
1095 } | 1095 } |
1096 | 1096 |
1097 CheckArrayBoundInstr* new_check = new CheckArrayBoundInstr( | 1097 CheckArrayBoundInstr* new_check = new CheckArrayBoundInstr( |
1098 new Value(UnwrapConstraint(check->length()->definition())), | 1098 new Value(UnwrapConstraint(check->length()->definition())), |
1099 new Value(upper_bound), | 1099 new Value(upper_bound), |
1100 Isolate::kNoDeoptId); | 1100 Isolate::kNoDeoptId); |
1101 new_check->mark_generalized(); | 1101 new_check->mark_generalized(); |
1102 if (new_check->IsRedundant(array_length)) { | 1102 if (new_check->IsRedundant(array_length)) { |
1103 if (FLAG_trace_range_analysis) { | 1103 if (FLAG_trace_range_analysis) { |
1104 ISL_Print(" => generalized check is redundant\n"); | 1104 THR_Print(" => generalized check is redundant\n"); |
1105 } | 1105 } |
1106 RemoveGeneralizedCheck(check); | 1106 RemoveGeneralizedCheck(check); |
1107 return; | 1107 return; |
1108 } | 1108 } |
1109 | 1109 |
1110 new_check = scheduler_.Emit(new_check, check); | 1110 new_check = scheduler_.Emit(new_check, check); |
1111 if (new_check != NULL) { | 1111 if (new_check != NULL) { |
1112 if (FLAG_trace_range_analysis) { | 1112 if (FLAG_trace_range_analysis) { |
1113 ISL_Print(" => generalized check was hoisted into B%" Pd "\n", | 1113 THR_Print(" => generalized check was hoisted into B%" Pd "\n", |
1114 new_check->GetBlock()->block_id()); | 1114 new_check->GetBlock()->block_id()); |
1115 } | 1115 } |
1116 RemoveGeneralizedCheck(check); | 1116 RemoveGeneralizedCheck(check); |
1117 } else { | 1117 } else { |
1118 if (FLAG_trace_range_analysis) { | 1118 if (FLAG_trace_range_analysis) { |
1119 ISL_Print(" => generalized check can't be hoisted\n"); | 1119 THR_Print(" => generalized check can't be hoisted\n"); |
1120 } | 1120 } |
1121 scheduler_.Rollback(); | 1121 scheduler_.Rollback(); |
1122 } | 1122 } |
1123 } | 1123 } |
1124 | 1124 |
1125 static void RemoveGeneralizedCheck(CheckArrayBoundInstr* check) { | 1125 static void RemoveGeneralizedCheck(CheckArrayBoundInstr* check) { |
1126 BinarySmiOpInstr* binary_op = | 1126 BinarySmiOpInstr* binary_op = |
1127 check->index()->definition()->AsBinarySmiOp(); | 1127 check->index()->definition()->AsBinarySmiOp(); |
1128 if (binary_op != NULL) { | 1128 if (binary_op != NULL) { |
1129 binary_op->set_can_overflow(false); | 1129 binary_op->set_can_overflow(false); |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 // TODO(vegorov): replace Constraint with an uncoditional | 1559 // TODO(vegorov): replace Constraint with an uncoditional |
1560 // deoptimization and kill all dominated dead code. | 1560 // deoptimization and kill all dominated dead code. |
1561 continue; | 1561 continue; |
1562 } | 1562 } |
1563 | 1563 |
1564 BranchInstr* branch = | 1564 BranchInstr* branch = |
1565 target->PredecessorAt(0)->last_instruction()->AsBranch(); | 1565 target->PredecessorAt(0)->last_instruction()->AsBranch(); |
1566 if (target == branch->true_successor()) { | 1566 if (target == branch->true_successor()) { |
1567 // True unreachable. | 1567 // True unreachable. |
1568 if (FLAG_trace_constant_propagation) { | 1568 if (FLAG_trace_constant_propagation) { |
1569 ISL_Print("Range analysis: True unreachable (B%" Pd ")\n", | 1569 THR_Print("Range analysis: True unreachable (B%" Pd ")\n", |
1570 branch->true_successor()->block_id()); | 1570 branch->true_successor()->block_id()); |
1571 } | 1571 } |
1572 branch->set_constant_target(branch->false_successor()); | 1572 branch->set_constant_target(branch->false_successor()); |
1573 } else { | 1573 } else { |
1574 ASSERT(target == branch->false_successor()); | 1574 ASSERT(target == branch->false_successor()); |
1575 // False unreachable. | 1575 // False unreachable. |
1576 if (FLAG_trace_constant_propagation) { | 1576 if (FLAG_trace_constant_propagation) { |
1577 ISL_Print("Range analysis: False unreachable (B%" Pd ")\n", | 1577 THR_Print("Range analysis: False unreachable (B%" Pd ")\n", |
1578 branch->false_successor()->block_id()); | 1578 branch->false_successor()->block_id()); |
1579 } | 1579 } |
1580 branch->set_constant_target(branch->true_successor()); | 1580 branch->set_constant_target(branch->true_successor()); |
1581 } | 1581 } |
1582 } | 1582 } |
1583 } | 1583 } |
1584 } | 1584 } |
1585 | 1585 |
1586 | 1586 |
1587 void RangeAnalysis::RemoveConstraints() { | 1587 void RangeAnalysis::RemoveConstraints() { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1655 : flow_graph_(flow_graph) { | 1655 : flow_graph_(flow_graph) { |
1656 ASSERT(flow_graph_ != NULL); | 1656 ASSERT(flow_graph_ != NULL); |
1657 zone_ = flow_graph_->zone(); | 1657 zone_ = flow_graph_->zone(); |
1658 selected_uint32_defs_ = | 1658 selected_uint32_defs_ = |
1659 new(zone_) BitVector(zone_, flow_graph_->current_ssa_temp_index()); | 1659 new(zone_) BitVector(zone_, flow_graph_->current_ssa_temp_index()); |
1660 } | 1660 } |
1661 | 1661 |
1662 | 1662 |
1663 void IntegerInstructionSelector::Select() { | 1663 void IntegerInstructionSelector::Select() { |
1664 if (FLAG_trace_integer_ir_selection) { | 1664 if (FLAG_trace_integer_ir_selection) { |
1665 ISL_Print("---- starting integer ir selection -------\n"); | 1665 THR_Print("---- starting integer ir selection -------\n"); |
1666 } | 1666 } |
1667 FindPotentialUint32Definitions(); | 1667 FindPotentialUint32Definitions(); |
1668 FindUint32NarrowingDefinitions(); | 1668 FindUint32NarrowingDefinitions(); |
1669 Propagate(); | 1669 Propagate(); |
1670 ReplaceInstructions(); | 1670 ReplaceInstructions(); |
1671 if (FLAG_trace_integer_ir_selection) { | 1671 if (FLAG_trace_integer_ir_selection) { |
1672 ISL_Print("---- after integer ir selection -------\n"); | 1672 THR_Print("---- after integer ir selection -------\n"); |
1673 FlowGraphPrinter printer(*flow_graph_); | 1673 FlowGraphPrinter printer(*flow_graph_); |
1674 printer.PrintBlocks(); | 1674 printer.PrintBlocks(); |
1675 } | 1675 } |
1676 } | 1676 } |
1677 | 1677 |
1678 | 1678 |
1679 bool IntegerInstructionSelector::IsPotentialUint32Definition(Definition* def) { | 1679 bool IntegerInstructionSelector::IsPotentialUint32Definition(Definition* def) { |
1680 // TODO(johnmccutchan): Consider Smi operations, to avoid unnecessary tagging | 1680 // TODO(johnmccutchan): Consider Smi operations, to avoid unnecessary tagging |
1681 // & untagged of intermediate results. | 1681 // & untagged of intermediate results. |
1682 // TODO(johnmccutchan): Consider phis. | 1682 // TODO(johnmccutchan): Consider phis. |
1683 return def->IsBoxInt64() || | 1683 return def->IsBoxInt64() || |
1684 def->IsUnboxInt64() || | 1684 def->IsUnboxInt64() || |
1685 def->IsBinaryMintOp() || | 1685 def->IsBinaryMintOp() || |
1686 def->IsShiftMintOp() || | 1686 def->IsShiftMintOp() || |
1687 def->IsUnaryMintOp(); | 1687 def->IsUnaryMintOp(); |
1688 } | 1688 } |
1689 | 1689 |
1690 | 1690 |
1691 void IntegerInstructionSelector::FindPotentialUint32Definitions() { | 1691 void IntegerInstructionSelector::FindPotentialUint32Definitions() { |
1692 if (FLAG_trace_integer_ir_selection) { | 1692 if (FLAG_trace_integer_ir_selection) { |
1693 ISL_Print("++++ Finding potential Uint32 definitions:\n"); | 1693 THR_Print("++++ Finding potential Uint32 definitions:\n"); |
1694 } | 1694 } |
1695 | 1695 |
1696 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator(); | 1696 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator(); |
1697 !block_it.Done(); | 1697 !block_it.Done(); |
1698 block_it.Advance()) { | 1698 block_it.Advance()) { |
1699 BlockEntryInstr* block = block_it.Current(); | 1699 BlockEntryInstr* block = block_it.Current(); |
1700 | 1700 |
1701 for (ForwardInstructionIterator instr_it(block); | 1701 for (ForwardInstructionIterator instr_it(block); |
1702 !instr_it.Done(); | 1702 !instr_it.Done(); |
1703 instr_it.Advance()) { | 1703 instr_it.Advance()) { |
1704 Instruction* current = instr_it.Current(); | 1704 Instruction* current = instr_it.Current(); |
1705 Definition* defn = current->AsDefinition(); | 1705 Definition* defn = current->AsDefinition(); |
1706 if ((defn != NULL) && defn->HasSSATemp()) { | 1706 if ((defn != NULL) && defn->HasSSATemp()) { |
1707 if (IsPotentialUint32Definition(defn)) { | 1707 if (IsPotentialUint32Definition(defn)) { |
1708 if (FLAG_trace_integer_ir_selection) { | 1708 if (FLAG_trace_integer_ir_selection) { |
1709 ISL_Print("Adding %s\n", current->ToCString()); | 1709 THR_Print("Adding %s\n", current->ToCString()); |
1710 } | 1710 } |
1711 potential_uint32_defs_.Add(defn); | 1711 potential_uint32_defs_.Add(defn); |
1712 } | 1712 } |
1713 } | 1713 } |
1714 } | 1714 } |
1715 } | 1715 } |
1716 } | 1716 } |
1717 | 1717 |
1718 | 1718 |
1719 // BinaryMintOp masks and stores into unsigned typed arrays that truncate the | 1719 // BinaryMintOp masks and stores into unsigned typed arrays that truncate the |
(...skipping 13 matching lines...) Expand all Loading... |
1733 return true; | 1733 return true; |
1734 } | 1734 } |
1735 // TODO(johnmccutchan): Add typed array stores. | 1735 // TODO(johnmccutchan): Add typed array stores. |
1736 return false; | 1736 return false; |
1737 } | 1737 } |
1738 | 1738 |
1739 | 1739 |
1740 void IntegerInstructionSelector::FindUint32NarrowingDefinitions() { | 1740 void IntegerInstructionSelector::FindUint32NarrowingDefinitions() { |
1741 ASSERT(selected_uint32_defs_ != NULL); | 1741 ASSERT(selected_uint32_defs_ != NULL); |
1742 if (FLAG_trace_integer_ir_selection) { | 1742 if (FLAG_trace_integer_ir_selection) { |
1743 ISL_Print("++++ Selecting Uint32 definitions:\n"); | 1743 THR_Print("++++ Selecting Uint32 definitions:\n"); |
1744 ISL_Print("++++ Initial set:\n"); | 1744 THR_Print("++++ Initial set:\n"); |
1745 } | 1745 } |
1746 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) { | 1746 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) { |
1747 Definition* defn = potential_uint32_defs_[i]; | 1747 Definition* defn = potential_uint32_defs_[i]; |
1748 if (IsUint32NarrowingDefinition(defn)) { | 1748 if (IsUint32NarrowingDefinition(defn)) { |
1749 if (FLAG_trace_integer_ir_selection) { | 1749 if (FLAG_trace_integer_ir_selection) { |
1750 ISL_Print("Adding %s\n", defn->ToCString()); | 1750 THR_Print("Adding %s\n", defn->ToCString()); |
1751 } | 1751 } |
1752 selected_uint32_defs_->Add(defn->ssa_temp_index()); | 1752 selected_uint32_defs_->Add(defn->ssa_temp_index()); |
1753 } | 1753 } |
1754 } | 1754 } |
1755 } | 1755 } |
1756 | 1756 |
1757 | 1757 |
1758 bool IntegerInstructionSelector::AllUsesAreUint32Narrowing(Value* list_head) { | 1758 bool IntegerInstructionSelector::AllUsesAreUint32Narrowing(Value* list_head) { |
1759 for (Value::Iterator it(list_head); | 1759 for (Value::Iterator it(list_head); |
1760 !it.Done(); | 1760 !it.Done(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1800 AllUsesAreUint32Narrowing(def->env_use_list()); | 1800 AllUsesAreUint32Narrowing(def->env_use_list()); |
1801 } | 1801 } |
1802 | 1802 |
1803 | 1803 |
1804 void IntegerInstructionSelector::Propagate() { | 1804 void IntegerInstructionSelector::Propagate() { |
1805 ASSERT(selected_uint32_defs_ != NULL); | 1805 ASSERT(selected_uint32_defs_ != NULL); |
1806 bool changed = true; | 1806 bool changed = true; |
1807 intptr_t iteration = 0; | 1807 intptr_t iteration = 0; |
1808 while (changed) { | 1808 while (changed) { |
1809 if (FLAG_trace_integer_ir_selection) { | 1809 if (FLAG_trace_integer_ir_selection) { |
1810 ISL_Print("+++ Iteration: %" Pd "\n", iteration++); | 1810 THR_Print("+++ Iteration: %" Pd "\n", iteration++); |
1811 } | 1811 } |
1812 changed = false; | 1812 changed = false; |
1813 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) { | 1813 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) { |
1814 Definition* defn = potential_uint32_defs_[i]; | 1814 Definition* defn = potential_uint32_defs_[i]; |
1815 if (selected_uint32_defs_->Contains(defn->ssa_temp_index())) { | 1815 if (selected_uint32_defs_->Contains(defn->ssa_temp_index())) { |
1816 // Already marked as a candidate, skip. | 1816 // Already marked as a candidate, skip. |
1817 continue; | 1817 continue; |
1818 } | 1818 } |
1819 if (defn->IsConstant()) { | 1819 if (defn->IsConstant()) { |
1820 // Skip constants. | 1820 // Skip constants. |
1821 continue; | 1821 continue; |
1822 } | 1822 } |
1823 if (CanBecomeUint32(defn)) { | 1823 if (CanBecomeUint32(defn)) { |
1824 if (FLAG_trace_integer_ir_selection) { | 1824 if (FLAG_trace_integer_ir_selection) { |
1825 ISL_Print("Adding %s\n", defn->ToCString()); | 1825 THR_Print("Adding %s\n", defn->ToCString()); |
1826 } | 1826 } |
1827 // Found a new candidate. | 1827 // Found a new candidate. |
1828 selected_uint32_defs_->Add(defn->ssa_temp_index()); | 1828 selected_uint32_defs_->Add(defn->ssa_temp_index()); |
1829 // Haven't reached fixed point yet. | 1829 // Haven't reached fixed point yet. |
1830 changed = true; | 1830 changed = true; |
1831 } | 1831 } |
1832 } | 1832 } |
1833 } | 1833 } |
1834 if (FLAG_trace_integer_ir_selection) { | 1834 if (FLAG_trace_integer_ir_selection) { |
1835 ISL_Print("Reached fixed point\n"); | 1835 THR_Print("Reached fixed point\n"); |
1836 } | 1836 } |
1837 } | 1837 } |
1838 | 1838 |
1839 | 1839 |
1840 Definition* IntegerInstructionSelector::ConstructReplacementFor( | 1840 Definition* IntegerInstructionSelector::ConstructReplacementFor( |
1841 Definition* def) { | 1841 Definition* def) { |
1842 // Should only see mint definitions. | 1842 // Should only see mint definitions. |
1843 ASSERT(IsPotentialUint32Definition(def)); | 1843 ASSERT(IsPotentialUint32Definition(def)); |
1844 // Should not see constant instructions. | 1844 // Should not see constant instructions. |
1845 ASSERT(!def->IsConstant()); | 1845 ASSERT(!def->IsConstant()); |
(...skipping 26 matching lines...) Expand all Loading... |
1872 intptr_t deopt_id = op->DeoptimizationTarget(); | 1872 intptr_t deopt_id = op->DeoptimizationTarget(); |
1873 return new(Z) ShiftUint32OpInstr(op_kind, left, right, deopt_id); | 1873 return new(Z) ShiftUint32OpInstr(op_kind, left, right, deopt_id); |
1874 } | 1874 } |
1875 UNREACHABLE(); | 1875 UNREACHABLE(); |
1876 return NULL; | 1876 return NULL; |
1877 } | 1877 } |
1878 | 1878 |
1879 | 1879 |
1880 void IntegerInstructionSelector::ReplaceInstructions() { | 1880 void IntegerInstructionSelector::ReplaceInstructions() { |
1881 if (FLAG_trace_integer_ir_selection) { | 1881 if (FLAG_trace_integer_ir_selection) { |
1882 ISL_Print("++++ Replacing instructions:\n"); | 1882 THR_Print("++++ Replacing instructions:\n"); |
1883 } | 1883 } |
1884 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) { | 1884 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) { |
1885 Definition* defn = potential_uint32_defs_[i]; | 1885 Definition* defn = potential_uint32_defs_[i]; |
1886 if (!selected_uint32_defs_->Contains(defn->ssa_temp_index())) { | 1886 if (!selected_uint32_defs_->Contains(defn->ssa_temp_index())) { |
1887 // Not a candidate. | 1887 // Not a candidate. |
1888 continue; | 1888 continue; |
1889 } | 1889 } |
1890 Definition* replacement = ConstructReplacementFor(defn); | 1890 Definition* replacement = ConstructReplacementFor(defn); |
1891 ASSERT(replacement != NULL); | 1891 ASSERT(replacement != NULL); |
1892 if (FLAG_trace_integer_ir_selection) { | 1892 if (FLAG_trace_integer_ir_selection) { |
1893 ISL_Print("Replacing %s with %s\n", defn->ToCString(), | 1893 THR_Print("Replacing %s with %s\n", defn->ToCString(), |
1894 replacement->ToCString()); | 1894 replacement->ToCString()); |
1895 } | 1895 } |
1896 if (!Range::IsUnknown(defn->range())) { | 1896 if (!Range::IsUnknown(defn->range())) { |
1897 replacement->set_range(*defn->range()); | 1897 replacement->set_range(*defn->range()); |
1898 } | 1898 } |
1899 defn->ReplaceWith(replacement, NULL); | 1899 defn->ReplaceWith(replacement, NULL); |
1900 ASSERT(flow_graph_->VerifyUseLists()); | 1900 ASSERT(flow_graph_->VerifyUseLists()); |
1901 } | 1901 } |
1902 } | 1902 } |
1903 | 1903 |
(...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3160 } | 3160 } |
3161 } while (CanonicalizeMaxBoundary(&max) || | 3161 } while (CanonicalizeMaxBoundary(&max) || |
3162 CanonicalizeMinBoundary(&canonical_length)); | 3162 CanonicalizeMinBoundary(&canonical_length)); |
3163 | 3163 |
3164 // Failed to prove that maximum is bounded with array length. | 3164 // Failed to prove that maximum is bounded with array length. |
3165 return false; | 3165 return false; |
3166 } | 3166 } |
3167 | 3167 |
3168 | 3168 |
3169 } // namespace dart | 3169 } // namespace dart |
OLD | NEW |