| 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/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 current_iterator_ = NULL; | 619 current_iterator_ = NULL; |
| 620 } | 620 } |
| 621 } | 621 } |
| 622 | 622 |
| 623 | 623 |
| 624 static void EnsureSSATempIndex(FlowGraph* graph, | 624 static void EnsureSSATempIndex(FlowGraph* graph, |
| 625 Definition* defn, | 625 Definition* defn, |
| 626 Definition* replacement) { | 626 Definition* replacement) { |
| 627 if ((replacement->ssa_temp_index() == -1) && | 627 if ((replacement->ssa_temp_index() == -1) && |
| 628 (defn->ssa_temp_index() != -1)) { | 628 (defn->ssa_temp_index() != -1)) { |
| 629 replacement->set_ssa_temp_index(graph->alloc_ssa_temp_index()); | 629 graph->AllocateSSAIndexes(replacement); |
| 630 } | 630 } |
| 631 } | 631 } |
| 632 | 632 |
| 633 | 633 |
| 634 static void ReplaceCurrentInstruction(ForwardInstructionIterator* iterator, | 634 static void ReplaceCurrentInstruction(ForwardInstructionIterator* iterator, |
| 635 Instruction* current, | 635 Instruction* current, |
| 636 Instruction* replacement, | 636 Instruction* replacement, |
| 637 FlowGraph* graph) { | 637 FlowGraph* graph) { |
| 638 Definition* current_defn = current->AsDefinition(); | 638 Definition* current_defn = current->AsDefinition(); |
| 639 if ((replacement != NULL) && (current_defn != NULL)) { | 639 if ((replacement != NULL) && (current_defn != NULL)) { |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 case kFloat64x2Cid: | 831 case kFloat64x2Cid: |
| 832 if (ShouldInlineSimd()) { | 832 if (ShouldInlineSimd()) { |
| 833 unboxed = kUnboxedFloat64x2; | 833 unboxed = kUnboxedFloat64x2; |
| 834 } | 834 } |
| 835 break; | 835 break; |
| 836 } | 836 } |
| 837 | 837 |
| 838 if ((kSmiBits < 32) && | 838 if ((kSmiBits < 32) && |
| 839 (unboxed == kTagged) && | 839 (unboxed == kTagged) && |
| 840 phi->Type()->IsInt() && | 840 phi->Type()->IsInt() && |
| 841 RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt32)) { | 841 RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt64)) { |
| 842 // On 32-bit platforms conservatively unbox phis that: | 842 // On 32-bit platforms conservatively unbox phis that: |
| 843 // - are proven to be of type Int; | 843 // - are proven to be of type Int; |
| 844 // - fit into 32bits range; | 844 // - fit into 64bits range; |
| 845 // - have either constants or Box() operations as inputs; | 845 // - have either constants or Box() operations as inputs; |
| 846 // - have at least one Box() operation as an input; | 846 // - have at least one Box() operation as an input; |
| 847 // - are used in at least 1 Unbox() operation. | 847 // - are used in at least 1 Unbox() operation. |
| 848 bool should_unbox = false; | 848 bool should_unbox = false; |
| 849 for (intptr_t i = 0; i < phi->InputCount(); i++) { | 849 for (intptr_t i = 0; i < phi->InputCount(); i++) { |
| 850 Definition* input = phi->InputAt(i)->definition(); | 850 Definition* input = phi->InputAt(i)->definition(); |
| 851 if (input->IsBox() && | 851 if (input->IsBox() && |
| 852 RangeUtils::Fits(input->range(), | 852 RangeUtils::Fits(input->range(), |
| 853 RangeBoundary::kRangeBoundaryInt32)) { | 853 RangeBoundary::kRangeBoundaryInt64)) { |
| 854 should_unbox = true; | 854 should_unbox = true; |
| 855 } else if (!input->IsConstant()) { | 855 } else if (!input->IsConstant()) { |
| 856 should_unbox = false; | 856 should_unbox = false; |
| 857 break; | 857 break; |
| 858 } | 858 } |
| 859 } | 859 } |
| 860 | 860 |
| 861 if (should_unbox) { | 861 if (should_unbox) { |
| 862 // We checked inputs. Check if phi is used in at least one unbox | 862 // We checked inputs. Check if phi is used in at least one unbox |
| 863 // operation. | 863 // operation. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 875 break; | 875 break; |
| 876 } | 876 } |
| 877 } | 877 } |
| 878 | 878 |
| 879 if (!has_unboxed_use) { | 879 if (!has_unboxed_use) { |
| 880 should_unbox = false; | 880 should_unbox = false; |
| 881 } | 881 } |
| 882 } | 882 } |
| 883 | 883 |
| 884 if (should_unbox) { | 884 if (should_unbox) { |
| 885 unboxed = kUnboxedInt32; | 885 unboxed = |
| 886 RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt32) |
| 887 ? kUnboxedInt32 : kUnboxedMint; |
| 886 } | 888 } |
| 887 } | 889 } |
| 888 | 890 |
| 889 phi->set_representation(unboxed); | 891 phi->set_representation(unboxed); |
| 890 } | 892 } |
| 891 | 893 |
| 892 | 894 |
| 893 void FlowGraphOptimizer::SelectRepresentations() { | 895 void FlowGraphOptimizer::SelectRepresentations() { |
| 894 // Conservatively unbox all phis that were proven to be of Double, | 896 // Conservatively unbox all phis that were proven to be of Double, |
| 895 // Float32x4, or Int32x4 type. | 897 // Float32x4, or Int32x4 type. |
| (...skipping 6170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7066 // they might contain values that were replaced and removed | 7068 // they might contain values that were replaced and removed |
| 7067 // from the graph by this iteration. | 7069 // from the graph by this iteration. |
| 7068 // To prevent using them we additionally mark definitions themselves | 7070 // To prevent using them we additionally mark definitions themselves |
| 7069 // as replaced and store a pointer to the replacement. | 7071 // as replaced and store a pointer to the replacement. |
| 7070 Definition* replacement = (*pred_out_values)[place_id]->Replacement(); | 7072 Definition* replacement = (*pred_out_values)[place_id]->Replacement(); |
| 7071 Value* input = new(Z) Value(replacement); | 7073 Value* input = new(Z) Value(replacement); |
| 7072 phi->SetInputAt(i, input); | 7074 phi->SetInputAt(i, input); |
| 7073 replacement->AddInputUse(input); | 7075 replacement->AddInputUse(input); |
| 7074 } | 7076 } |
| 7075 | 7077 |
| 7076 phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index()); | 7078 graph_->AllocateSSAIndexes(phi); |
| 7077 phis_.Add(phi); // Postpone phi insertion until after load forwarding. | 7079 phis_.Add(phi); // Postpone phi insertion until after load forwarding. |
| 7078 | 7080 |
| 7079 if (FLAG_trace_load_optimization) { | 7081 if (FLAG_trace_load_optimization) { |
| 7080 THR_Print("created pending phi %s for %s at B%" Pd "\n", | 7082 THR_Print("created pending phi %s for %s at B%" Pd "\n", |
| 7081 phi->ToCString(), | 7083 phi->ToCString(), |
| 7082 aliased_set_->places()[place_id]->ToCString(), | 7084 aliased_set_->places()[place_id]->ToCString(), |
| 7083 block->block_id()); | 7085 block->block_id()); |
| 7084 } | 7086 } |
| 7085 } | 7087 } |
| 7086 | 7088 |
| (...skipping 1703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8790 | 8792 |
| 8791 // Insert materializations at environment uses. | 8793 // Insert materializations at environment uses. |
| 8792 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 8794 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 8793 CreateMaterializationAt( | 8795 CreateMaterializationAt( |
| 8794 exits_collector_.exits()[i], alloc, *slots); | 8796 exits_collector_.exits()[i], alloc, *slots); |
| 8795 } | 8797 } |
| 8796 } | 8798 } |
| 8797 | 8799 |
| 8798 | 8800 |
| 8799 } // namespace dart | 8801 } // namespace dart |
| OLD | NEW |