| 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 |