| 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_allocator.h" | 5 #include "vm/flow_graph_allocator.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 #include "vm/il_printer.h" | 9 #include "vm/il_printer.h" |
| 10 #include "vm/flow_graph.h" | 10 #include "vm/flow_graph.h" |
| (...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 BitVector* interference_set) { | 851 BitVector* interference_set) { |
| 852 LocationSummary* locs = current->locs(); | 852 LocationSummary* locs = current->locs(); |
| 853 | 853 |
| 854 Definition* def = current->AsDefinition(); | 854 Definition* def = current->AsDefinition(); |
| 855 if ((def != NULL) && (def->AsConstant() != NULL)) { | 855 if ((def != NULL) && (def->AsConstant() != NULL)) { |
| 856 LiveRange* range = (def->ssa_temp_index() != -1) ? | 856 LiveRange* range = (def->ssa_temp_index() != -1) ? |
| 857 GetLiveRange(def->ssa_temp_index()) : NULL; | 857 GetLiveRange(def->ssa_temp_index()) : NULL; |
| 858 | 858 |
| 859 // Drop definitions of constants that have no uses. | 859 // Drop definitions of constants that have no uses. |
| 860 if ((range == NULL) || (range->first_use() == NULL)) { | 860 if ((range == NULL) || (range->first_use() == NULL)) { |
| 861 locs->set_out(Location::NoLocation()); | 861 locs->set_out(0, Location::NoLocation()); |
| 862 return; | 862 return; |
| 863 } | 863 } |
| 864 | 864 |
| 865 // If this constant has only unconstrained uses convert them all | 865 // If this constant has only unconstrained uses convert them all |
| 866 // to use the constant directly and drop this definition. | 866 // to use the constant directly and drop this definition. |
| 867 // TODO(vegorov): improve allocation when we have enough registers to keep | 867 // TODO(vegorov): improve allocation when we have enough registers to keep |
| 868 // constants used in the loop in them. | 868 // constants used in the loop in them. |
| 869 if (HasOnlyUnconstrainedUses(range)) { | 869 if (HasOnlyUnconstrainedUses(range)) { |
| 870 const Object& value = def->AsConstant()->value(); | 870 const Object& value = def->AsConstant()->value(); |
| 871 range->set_assigned_location(Location::Constant(value)); | 871 range->set_assigned_location(Location::Constant(value)); |
| 872 range->set_spill_slot(Location::Constant(value)); | 872 range->set_spill_slot(Location::Constant(value)); |
| 873 range->finger()->Initialize(range); | 873 range->finger()->Initialize(range); |
| 874 ConvertAllUses(range); | 874 ConvertAllUses(range); |
| 875 | 875 |
| 876 locs->set_out(Location::NoLocation()); | 876 locs->set_out(0, Location::NoLocation()); |
| 877 return; | 877 return; |
| 878 } | 878 } |
| 879 } | 879 } |
| 880 | 880 |
| 881 const intptr_t pos = current->lifetime_position(); | 881 const intptr_t pos = current->lifetime_position(); |
| 882 ASSERT(IsInstructionStartPosition(pos)); | 882 ASSERT(IsInstructionStartPosition(pos)); |
| 883 | 883 |
| 884 // Number of input locations and number of input operands have to agree. | 884 // Number of input locations and number of input operands have to agree. |
| 885 ASSERT(locs->input_count() == current->InputCount()); | 885 ASSERT(locs->input_count() == current->InputCount()); |
| 886 | 886 |
| 887 // Normalize same-as-first-input output if input is specified as | 887 // Normalize same-as-first-input output if input is specified as |
| 888 // fixed register. | 888 // fixed register. |
| 889 if (locs->out().IsUnallocated() && | 889 if (locs->out(0).IsUnallocated() && |
| 890 (locs->out().policy() == Location::kSameAsFirstInput) && | 890 (locs->out(0).policy() == Location::kSameAsFirstInput) && |
| 891 (locs->in(0).IsMachineRegister())) { | 891 (locs->in(0).IsMachineRegister())) { |
| 892 locs->set_out(locs->in(0)); | 892 locs->set_out(0, locs->in(0)); |
| 893 } | 893 } |
| 894 | 894 |
| 895 const bool output_same_as_first_input = | 895 const bool output_same_as_first_input = |
| 896 locs->out().IsUnallocated() && | 896 locs->out(0).IsUnallocated() && |
| 897 (locs->out().policy() == Location::kSameAsFirstInput); | 897 (locs->out(0).policy() == Location::kSameAsFirstInput); |
| 898 | 898 |
| 899 // Add uses from the deoptimization environment. | 899 // Add uses from the deoptimization environment. |
| 900 if (current->env() != NULL) ProcessEnvironmentUses(block, current); | 900 if (current->env() != NULL) ProcessEnvironmentUses(block, current); |
| 901 | 901 |
| 902 // Process inputs. | 902 // Process inputs. |
| 903 // Skip the first input if output is specified with kSameAsFirstInput policy, | 903 // Skip the first input if output is specified with kSameAsFirstInput policy, |
| 904 // they will be processed together at the very end. | 904 // they will be processed together at the very end. |
| 905 for (intptr_t j = output_same_as_first_input ? 1 : 0; | 905 for (intptr_t j = output_same_as_first_input ? 1 : 0; |
| 906 j < current->InputCount(); | 906 j < current->InputCount(); |
| 907 j++) { | 907 j++) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 // locations. Every register is blocked now so attempt to | 1010 // locations. Every register is blocked now so attempt to |
| 1011 // allocate will not succeed. | 1011 // allocate will not succeed. |
| 1012 for (intptr_t j = 0; j < locs->temp_count(); j++) { | 1012 for (intptr_t j = 0; j < locs->temp_count(); j++) { |
| 1013 ASSERT(!locs->temp(j).IsUnallocated()); | 1013 ASSERT(!locs->temp(j).IsUnallocated()); |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 for (intptr_t j = 0; j < locs->input_count(); j++) { | 1016 for (intptr_t j = 0; j < locs->input_count(); j++) { |
| 1017 ASSERT(!locs->in(j).IsUnallocated()); | 1017 ASSERT(!locs->in(j).IsUnallocated()); |
| 1018 } | 1018 } |
| 1019 | 1019 |
| 1020 ASSERT(!locs->out().IsUnallocated()); | 1020 ASSERT(!locs->out(0).IsUnallocated()); |
| 1021 #endif | 1021 #endif |
| 1022 } | 1022 } |
| 1023 | 1023 |
| 1024 if (locs->can_call()) { | 1024 if (locs->can_call()) { |
| 1025 safepoints_.Add(current); | 1025 safepoints_.Add(current); |
| 1026 } | 1026 } |
| 1027 | 1027 |
| 1028 if (def == NULL) { | 1028 if (def == NULL) { |
| 1029 ASSERT(locs->out().IsInvalid()); | 1029 ASSERT(locs->out(0).IsInvalid()); |
| 1030 return; | 1030 return; |
| 1031 } | 1031 } |
| 1032 | 1032 |
| 1033 if (locs->out().IsInvalid()) { | 1033 if (locs->out(0).IsInvalid()) { |
| 1034 ASSERT(def->ssa_temp_index() < 0); | 1034 ASSERT(def->ssa_temp_index() < 0); |
| 1035 return; | 1035 return; |
| 1036 } | 1036 } |
| 1037 | 1037 |
| 1038 // We might have a definition without use. We do not assign SSA index to | 1038 // We might have a definition without use. We do not assign SSA index to |
| 1039 // such definitions. | 1039 // such definitions. |
| 1040 LiveRange* range = (def->ssa_temp_index() >= 0) ? | 1040 LiveRange* range = (def->ssa_temp_index() >= 0) ? |
| 1041 GetLiveRange(def->ssa_temp_index()) : | 1041 GetLiveRange(def->ssa_temp_index()) : |
| 1042 MakeLiveRangeForTemporary(); | 1042 MakeLiveRangeForTemporary(); |
| 1043 Location* out = locs->out_slot(); | 1043 Location* out = locs->out_slot(0); |
| 1044 | 1044 |
| 1045 // Process output and finalize its liverange. | 1045 // Process output and finalize its liverange. |
| 1046 if (out->IsMachineRegister()) { | 1046 if (out->IsMachineRegister()) { |
| 1047 // Fixed output location. Expected shape of live range: | 1047 // Fixed output location. Expected shape of live range: |
| 1048 // | 1048 // |
| 1049 // i i' j j' | 1049 // i i' j j' |
| 1050 // register [--) | 1050 // register [--) |
| 1051 // output [------- | 1051 // output [------- |
| 1052 // | 1052 // |
| 1053 BlockLocation(*out, pos, pos + 1); | 1053 BlockLocation(*out, pos, pos + 1); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1083 // start. Expected shape of live ranges: | 1083 // start. Expected shape of live ranges: |
| 1084 // | 1084 // |
| 1085 // i i' | 1085 // i i' |
| 1086 // input #0 --* | 1086 // input #0 --* |
| 1087 // output [---- | 1087 // output [---- |
| 1088 // | 1088 // |
| 1089 ASSERT(locs->in(0).Equals(Location::RequiresRegister()) || | 1089 ASSERT(locs->in(0).Equals(Location::RequiresRegister()) || |
| 1090 locs->in(0).Equals(Location::RequiresFpuRegister())); | 1090 locs->in(0).Equals(Location::RequiresFpuRegister())); |
| 1091 | 1091 |
| 1092 // Create move that will copy value between input and output. | 1092 // Create move that will copy value between input and output. |
| 1093 locs->set_out(Location::RequiresRegister()); | 1093 locs->set_out(0, Location::RequiresRegister()); |
| 1094 MoveOperands* move = AddMoveAt(pos, | 1094 MoveOperands* move = AddMoveAt(pos, |
| 1095 Location::RequiresRegister(), | 1095 Location::RequiresRegister(), |
| 1096 Location::Any()); | 1096 Location::Any()); |
| 1097 | 1097 |
| 1098 // Add uses to the live range of the input. | 1098 // Add uses to the live range of the input. |
| 1099 Definition* input = current->InputAt(0)->definition(); | 1099 Definition* input = current->InputAt(0)->definition(); |
| 1100 LiveRange* input_range = | 1100 LiveRange* input_range = |
| 1101 GetLiveRange(input->ssa_temp_index()); | 1101 GetLiveRange(input->ssa_temp_index()); |
| 1102 input_range->AddUseInterval(block->start_pos(), pos); | 1102 input_range->AddUseInterval(block->start_pos(), pos); |
| 1103 input_range->AddUse(pos, move->src_slot()); | 1103 input_range->AddUse(pos, move->src_slot()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1114 interference_set->Contains(range->vreg())) { | 1114 interference_set->Contains(range->vreg())) { |
| 1115 interference_set->Add(input->ssa_temp_index()); | 1115 interference_set->Add(input->ssa_temp_index()); |
| 1116 } | 1116 } |
| 1117 } else { | 1117 } else { |
| 1118 // Normal unallocated location that requires a register. Expected shape of | 1118 // Normal unallocated location that requires a register. Expected shape of |
| 1119 // live range: | 1119 // live range: |
| 1120 // | 1120 // |
| 1121 // i i' | 1121 // i i' |
| 1122 // output [------- | 1122 // output [------- |
| 1123 // | 1123 // |
| 1124 ASSERT(locs->out().Equals(Location::RequiresRegister()) || | 1124 ASSERT(locs->out(0).Equals(Location::RequiresRegister()) || |
| 1125 locs->out().Equals(Location::RequiresFpuRegister())); | 1125 locs->out(0).Equals(Location::RequiresFpuRegister())); |
| 1126 | 1126 |
| 1127 // Shorten live range to the point of definition and add use to be filled by | 1127 // Shorten live range to the point of definition and add use to be filled by |
| 1128 // allocator. | 1128 // allocator. |
| 1129 range->DefineAt(pos); | 1129 range->DefineAt(pos); |
| 1130 range->AddUse(pos, out); | 1130 range->AddUse(pos, out); |
| 1131 } | 1131 } |
| 1132 | 1132 |
| 1133 AssignSafepoints(range); | 1133 AssignSafepoints(range); |
| 1134 CompleteRange(range, RegisterKindForResult(current)); | 1134 CompleteRange(range, RegisterKindForResult(current)); |
| 1135 } | 1135 } |
| (...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2605 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2605 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
| 2606 function.ToFullyQualifiedCString()); | 2606 function.ToFullyQualifiedCString()); |
| 2607 FlowGraphPrinter printer(flow_graph_, true); | 2607 FlowGraphPrinter printer(flow_graph_, true); |
| 2608 printer.PrintBlocks(); | 2608 printer.PrintBlocks(); |
| 2609 OS::Print("----------------------------------------------\n"); | 2609 OS::Print("----------------------------------------------\n"); |
| 2610 } | 2610 } |
| 2611 } | 2611 } |
| 2612 | 2612 |
| 2613 | 2613 |
| 2614 } // namespace dart | 2614 } // namespace dart |
| OLD | NEW |