| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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.h" | 5 #include "vm/flow_graph.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 } | 53 } |
| 54 | 54 |
| 55 void FlowGraph::AddToInitialDefinitions(Definition* defn) { | 55 void FlowGraph::AddToInitialDefinitions(Definition* defn) { |
| 56 // TODO(zerny): Set previous to the graph entry so it is accessible by | 56 // TODO(zerny): Set previous to the graph entry so it is accessible by |
| 57 // GetBlock. Remove this once there is a direct pointer to the block. | 57 // GetBlock. Remove this once there is a direct pointer to the block. |
| 58 defn->set_previous(graph_entry_); | 58 defn->set_previous(graph_entry_); |
| 59 graph_entry_->initial_definitions()->Add(defn); | 59 graph_entry_->initial_definitions()->Add(defn); |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 void FlowGraph::InsertBefore(Instruction* next, |
| 64 Instruction* instr, |
| 65 Environment* env, |
| 66 Definition::UseKind use_kind) { |
| 67 InsertAfter(next->previous(), instr, env, use_kind); |
| 68 } |
| 69 |
| 70 |
| 71 void FlowGraph::InsertAfter(Instruction* prev, |
| 72 Instruction* instr, |
| 73 Environment* env, |
| 74 Definition::UseKind use_kind) { |
| 75 for (intptr_t i = instr->InputCount() - 1; i >= 0; --i) { |
| 76 Value* input = instr->InputAt(i); |
| 77 input->definition()->AddInputUse(input); |
| 78 input->set_instruction(instr); |
| 79 input->set_use_index(i); |
| 80 } |
| 81 ASSERT(instr->env() == NULL); |
| 82 if (env != NULL) env->DeepCopyTo(instr); |
| 83 if (use_kind == Definition::kValue) { |
| 84 ASSERT(instr->IsDefinition()); |
| 85 instr->AsDefinition()->set_ssa_temp_index(alloc_ssa_temp_index()); |
| 86 } |
| 87 instr->InsertAfter(prev); |
| 88 } |
| 89 |
| 90 |
| 63 void FlowGraph::DiscoverBlocks() { | 91 void FlowGraph::DiscoverBlocks() { |
| 64 // Initialize state. | 92 // Initialize state. |
| 65 preorder_.Clear(); | 93 preorder_.Clear(); |
| 66 postorder_.Clear(); | 94 postorder_.Clear(); |
| 67 reverse_postorder_.Clear(); | 95 reverse_postorder_.Clear(); |
| 68 parent_.Clear(); | 96 parent_.Clear(); |
| 69 assigned_vars_.Clear(); | 97 assigned_vars_.Clear(); |
| 70 // Perform a depth-first traversal of the graph to build preorder and | 98 // Perform a depth-first traversal of the graph to build preorder and |
| 71 // postorder block orders. | 99 // postorder block orders. |
| 72 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. | 100 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 170 } |
| 143 return true; // Return true so we can ASSERT the reset code. | 171 return true; // Return true so we can ASSERT the reset code. |
| 144 } | 172 } |
| 145 | 173 |
| 146 | 174 |
| 147 static void ValidateUseListsInInstruction(Instruction* instr) { | 175 static void ValidateUseListsInInstruction(Instruction* instr) { |
| 148 ASSERT(instr != NULL); | 176 ASSERT(instr != NULL); |
| 149 ASSERT(!instr->IsJoinEntry()); | 177 ASSERT(!instr->IsJoinEntry()); |
| 150 for (intptr_t i = 0; i < instr->InputCount(); ++i) { | 178 for (intptr_t i = 0; i < instr->InputCount(); ++i) { |
| 151 Value* use = instr->InputAt(i); | 179 Value* use = instr->InputAt(i); |
| 180 ASSERT(use->definition() != NULL); |
| 181 ASSERT(use->definition() != instr); |
| 182 ASSERT(use->instruction() == instr); |
| 152 ASSERT(use->use_index() == i); | 183 ASSERT(use->use_index() == i); |
| 153 ASSERT(!FLAG_verify_compiler || | 184 ASSERT(!FLAG_verify_compiler || |
| 154 (1 == MembershipCount(use, use->definition()->input_use_list()))); | 185 (1 == MembershipCount(use, use->definition()->input_use_list()))); |
| 155 } | 186 } |
| 156 if (instr->env() != NULL) { | 187 if (instr->env() != NULL) { |
| 157 intptr_t use_index = 0; | 188 intptr_t use_index = 0; |
| 158 for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) { | 189 for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) { |
| 159 Value* use = it.CurrentValue(); | 190 Value* use = it.CurrentValue(); |
| 191 ASSERT(use->definition() != NULL); |
| 192 ASSERT(use->definition() != instr); |
| 193 ASSERT(use->instruction() == instr); |
| 160 ASSERT(use->use_index() == use_index++); | 194 ASSERT(use->use_index() == use_index++); |
| 161 ASSERT(!FLAG_verify_compiler || | 195 ASSERT(!FLAG_verify_compiler || |
| 162 (1 == MembershipCount(use, use->definition()->env_use_list()))); | 196 (1 == MembershipCount(use, use->definition()->env_use_list()))); |
| 163 } | 197 } |
| 164 } | 198 } |
| 165 Definition* defn = instr->AsDefinition(); | 199 Definition* defn = instr->AsDefinition(); |
| 166 if (defn != NULL) { | 200 if (defn != NULL) { |
| 167 Value* prev = NULL; | 201 Value* prev = NULL; |
| 168 Value* curr = defn->input_use_list(); | 202 Value* curr = defn->input_use_list(); |
| 169 while (curr != NULL) { | 203 while (curr != NULL) { |
| 170 ASSERT(prev == curr->previous_use()); | 204 ASSERT(prev == curr->previous_use()); |
| 171 ASSERT(defn == curr->definition()); | 205 ASSERT(defn == curr->definition()); |
| 172 Instruction* instr = curr->instruction(); | 206 Instruction* instr = curr->instruction(); |
| 173 // The instruction should not be removed from the graph (phis are not | 207 // The instruction should not be removed from the graph. Removed |
| 174 // removed until register allocation.) | 208 // instructions have a NULL previous link. Phis are not removed until |
| 175 ASSERT(instr->IsPhi() || (instr->previous() != NULL)); | 209 // register allocation. Comparisons used only in a branch will have a |
| 210 // NULL previous link though they are still in the graph. |
| 211 ASSERT(instr->IsPhi() || |
| 212 (instr->IsDefinition() && instr->AsDefinition()->IsComparison()) || |
| 213 (instr->previous() != NULL)); |
| 176 ASSERT(curr == instr->InputAt(curr->use_index())); | 214 ASSERT(curr == instr->InputAt(curr->use_index())); |
| 177 prev = curr; | 215 prev = curr; |
| 178 curr = curr->next_use(); | 216 curr = curr->next_use(); |
| 179 } | 217 } |
| 180 | 218 |
| 181 prev = NULL; | 219 prev = NULL; |
| 182 curr = defn->env_use_list(); | 220 curr = defn->env_use_list(); |
| 183 while (curr != NULL) { | 221 while (curr != NULL) { |
| 184 ASSERT(prev == curr->previous_use()); | 222 ASSERT(prev == curr->previous_use()); |
| 185 ASSERT(defn == curr->definition()); | 223 ASSERT(defn == curr->definition()); |
| 186 Instruction* instr = curr->instruction(); | 224 Instruction* instr = curr->instruction(); |
| 187 ASSERT(curr == instr->env()->ValueAtUseIndex(curr->use_index())); | 225 ASSERT(curr == instr->env()->ValueAtUseIndex(curr->use_index())); |
| 188 // The instruction should not be removed from the graph (phis are not | 226 ASSERT(instr->IsPhi() || |
| 189 // removed until register allocation.) | 227 (instr->IsDefinition() && instr->AsDefinition()->IsComparison()) || |
| 190 ASSERT(instr->IsPhi() || (instr->previous() != NULL)); | 228 (instr->previous() != NULL)); |
| 191 prev = curr; | 229 prev = curr; |
| 192 curr = curr->next_use(); | 230 curr = curr->next_use(); |
| 193 } | 231 } |
| 194 } | 232 } |
| 195 } | 233 } |
| 196 | 234 |
| 197 | 235 |
| 198 bool FlowGraph::ValidateUseLists() { | 236 bool FlowGraph::ValidateUseLists() { |
| 199 // Validate initial definitions. | 237 // Validate initial definitions. |
| 200 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { | 238 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 !it.Done(); | 830 !it.Done(); |
| 793 it.Advance()) { | 831 it.Advance()) { |
| 794 ++size; | 832 ++size; |
| 795 } | 833 } |
| 796 } | 834 } |
| 797 return size; | 835 return size; |
| 798 } | 836 } |
| 799 | 837 |
| 800 | 838 |
| 801 } // namespace dart | 839 } // namespace dart |
| OLD | NEW |