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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 blocked_cpu_registers_[PP] = true; | 115 blocked_cpu_registers_[PP] = true; |
116 } | 116 } |
117 blocked_cpu_registers_[SPREG] = true; | 117 blocked_cpu_registers_[SPREG] = true; |
118 blocked_cpu_registers_[FPREG] = true; | 118 blocked_cpu_registers_[FPREG] = true; |
119 | 119 |
120 // FpuTMP is used as scratch by optimized code and parallel move resolver. | 120 // FpuTMP is used as scratch by optimized code and parallel move resolver. |
121 blocked_fpu_registers_[FpuTMP] = true; | 121 blocked_fpu_registers_[FpuTMP] = true; |
122 } | 122 } |
123 | 123 |
124 | 124 |
| 125 static void DeepLiveness(MaterializeObjectInstr* mat, BitVector* live_in) { |
| 126 if (mat->was_visited_for_liveness()) { |
| 127 return; |
| 128 } |
| 129 mat->mark_visited_for_liveness(); |
| 130 |
| 131 for (intptr_t i = 0; i < mat->InputCount(); i++) { |
| 132 if (!mat->InputAt(i)->BindsToConstant()) { |
| 133 Definition* defn = mat->InputAt(i)->definition(); |
| 134 MaterializeObjectInstr* inner_mat = defn->AsMaterializeObject(); |
| 135 if (inner_mat != NULL) { |
| 136 DeepLiveness(inner_mat, live_in); |
| 137 } else { |
| 138 intptr_t idx = defn->ssa_temp_index(); |
| 139 live_in->Add(idx); |
| 140 } |
| 141 } |
| 142 } |
| 143 } |
| 144 |
| 145 |
125 void SSALivenessAnalysis::ComputeInitialSets() { | 146 void SSALivenessAnalysis::ComputeInitialSets() { |
126 const intptr_t block_count = postorder_.length(); | 147 const intptr_t block_count = postorder_.length(); |
127 for (intptr_t i = 0; i < block_count; i++) { | 148 for (intptr_t i = 0; i < block_count; i++) { |
128 BlockEntryInstr* block = postorder_[i]; | 149 BlockEntryInstr* block = postorder_[i]; |
129 | 150 |
130 BitVector* kill = kill_[i]; | 151 BitVector* kill = kill_[i]; |
131 BitVector* live_in = live_in_[i]; | 152 BitVector* live_in = live_in_[i]; |
132 | 153 |
133 // Iterate backwards starting at the last instruction. | 154 // Iterate backwards starting at the last instruction. |
134 for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 155 for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 // Add non-argument uses from the deoptimization environment (pushed | 187 // Add non-argument uses from the deoptimization environment (pushed |
167 // arguments are not allocated by the register allocator). | 188 // arguments are not allocated by the register allocator). |
168 if (current->env() != NULL) { | 189 if (current->env() != NULL) { |
169 for (Environment::DeepIterator env_it(current->env()); | 190 for (Environment::DeepIterator env_it(current->env()); |
170 !env_it.Done(); | 191 !env_it.Done(); |
171 env_it.Advance()) { | 192 env_it.Advance()) { |
172 Definition* defn = env_it.CurrentValue()->definition(); | 193 Definition* defn = env_it.CurrentValue()->definition(); |
173 if (defn->IsMaterializeObject()) { | 194 if (defn->IsMaterializeObject()) { |
174 // MaterializeObject instruction is not in the graph. | 195 // MaterializeObject instruction is not in the graph. |
175 // Treat its inputs as part of the environment. | 196 // Treat its inputs as part of the environment. |
176 for (intptr_t i = 0; i < defn->InputCount(); i++) { | 197 DeepLiveness(defn->AsMaterializeObject(), live_in); |
177 if (!defn->InputAt(i)->BindsToConstant()) { | |
178 intptr_t idx = defn->InputAt(i)->definition()->ssa_temp_index(); | |
179 live_in->Add(idx); | |
180 } | |
181 } | |
182 } else if (!defn->IsPushArgument() && !defn->IsConstant()) { | 198 } else if (!defn->IsPushArgument() && !defn->IsConstant()) { |
183 live_in->Add(defn->ssa_temp_index()); | 199 live_in->Add(defn->ssa_temp_index()); |
184 if (defn->HasPairRepresentation()) { | 200 if (defn->HasPairRepresentation()) { |
185 live_in->Add(ToSecondPairVreg(defn->ssa_temp_index())); | 201 live_in->Add(ToSecondPairVreg(defn->ssa_temp_index())); |
186 } | 202 } |
187 } | 203 } |
188 } | 204 } |
189 } | 205 } |
190 } | 206 } |
191 | 207 |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
882 MaterializeObjectInstr* mat) { | 898 MaterializeObjectInstr* mat) { |
883 // Materialization can occur several times in the same environment. | 899 // Materialization can occur several times in the same environment. |
884 // Check if we already processed this one. | 900 // Check if we already processed this one. |
885 if (mat->locations() != NULL) { | 901 if (mat->locations() != NULL) { |
886 return; // Already processed. | 902 return; // Already processed. |
887 } | 903 } |
888 | 904 |
889 // Initialize location for every input of the MaterializeObject instruction. | 905 // Initialize location for every input of the MaterializeObject instruction. |
890 Location* locations = | 906 Location* locations = |
891 Isolate::Current()->current_zone()->Alloc<Location>(mat->InputCount()); | 907 Isolate::Current()->current_zone()->Alloc<Location>(mat->InputCount()); |
| 908 mat->set_locations(locations); |
892 | 909 |
893 for (intptr_t i = 0; i < mat->InputCount(); ++i) { | 910 for (intptr_t i = 0; i < mat->InputCount(); ++i) { |
894 Definition* def = mat->InputAt(i)->definition(); | 911 Definition* def = mat->InputAt(i)->definition(); |
895 | 912 |
896 ConstantInstr* constant = def->AsConstant(); | 913 ConstantInstr* constant = def->AsConstant(); |
897 if (constant != NULL) { | 914 if (constant != NULL) { |
898 locations[i] = Location::Constant(constant->value()); | 915 locations[i] = Location::Constant(constant->value()); |
899 continue; | 916 continue; |
900 } | 917 } |
901 | 918 |
902 if (def->HasPairRepresentation()) { | 919 if (def->HasPairRepresentation()) { |
903 locations[i] = Location::Pair(Location::Any(), Location::Any()); | 920 locations[i] = Location::Pair(Location::Any(), Location::Any()); |
904 PairLocation* location_pair = locations[i].AsPairLocation(); | 921 PairLocation* location_pair = locations[i].AsPairLocation(); |
905 { | 922 { |
906 // First live range. | 923 // First live range. |
907 LiveRange* range = GetLiveRange(def->ssa_temp_index()); | 924 LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
908 range->AddUseInterval(block_start_pos, use_pos); | 925 range->AddUseInterval(block_start_pos, use_pos); |
909 range->AddUse(use_pos, location_pair->SlotAt(0)); | 926 range->AddUse(use_pos, location_pair->SlotAt(0)); |
910 } | 927 } |
911 { | 928 { |
912 // Second live range. | 929 // Second live range. |
913 LiveRange* range = | 930 LiveRange* range = |
914 GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); | 931 GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); |
915 range->AddUseInterval(block_start_pos, use_pos); | 932 range->AddUseInterval(block_start_pos, use_pos); |
916 range->AddUse(use_pos, location_pair->SlotAt(1)); | 933 range->AddUse(use_pos, location_pair->SlotAt(1)); |
917 } | 934 } |
| 935 } else if (def->IsMaterializeObject()) { |
| 936 locations[i] = Location::NoLocation(); |
| 937 ProcessMaterializationUses( |
| 938 block, block_start_pos, use_pos, def->AsMaterializeObject()); |
918 } else { | 939 } else { |
919 locations[i] = Location::Any(); | 940 locations[i] = Location::Any(); |
920 LiveRange* range = GetLiveRange(def->ssa_temp_index()); | 941 LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
921 range->AddUseInterval(block_start_pos, use_pos); | 942 range->AddUseInterval(block_start_pos, use_pos); |
922 range->AddUse(use_pos, &locations[i]); | 943 range->AddUse(use_pos, &locations[i]); |
923 } | 944 } |
924 } | 945 } |
925 | |
926 mat->set_locations(locations); | |
927 } | 946 } |
928 | 947 |
929 | 948 |
930 void FlowGraphAllocator::ProcessOneInput(BlockEntryInstr* block, | 949 void FlowGraphAllocator::ProcessOneInput(BlockEntryInstr* block, |
931 intptr_t pos, | 950 intptr_t pos, |
932 Location* in_ref, | 951 Location* in_ref, |
933 Value* input, | 952 Value* input, |
934 intptr_t vreg, | 953 intptr_t vreg, |
935 RegisterSet* live_registers) { | 954 RegisterSet* live_registers) { |
936 ASSERT(in_ref != NULL); | 955 ASSERT(in_ref != NULL); |
(...skipping 1950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2887 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2906 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
2888 function.ToFullyQualifiedCString()); | 2907 function.ToFullyQualifiedCString()); |
2889 FlowGraphPrinter printer(flow_graph_, true); | 2908 FlowGraphPrinter printer(flow_graph_, true); |
2890 printer.PrintBlocks(); | 2909 printer.PrintBlocks(); |
2891 OS::Print("----------------------------------------------\n"); | 2910 OS::Print("----------------------------------------------\n"); |
2892 } | 2911 } |
2893 } | 2912 } |
2894 | 2913 |
2895 | 2914 |
2896 } // namespace dart | 2915 } // namespace dart |
OLD | NEW |