Chromium Code Reviews| 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/growable_array.h" | 10 #include "vm/growable_array.h" |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 if (use_kind == kValue) { | 142 if (use_kind == kValue) { |
| 143 ASSERT(instr->IsDefinition()); | 143 ASSERT(instr->IsDefinition()); |
| 144 AllocateSSAIndexes(instr->AsDefinition()); | 144 AllocateSSAIndexes(instr->AsDefinition()); |
| 145 } | 145 } |
| 146 ASSERT(instr->env() == NULL); | 146 ASSERT(instr->env() == NULL); |
| 147 if (env != NULL) env->DeepCopyTo(isolate(), instr); | 147 if (env != NULL) env->DeepCopyTo(isolate(), instr); |
| 148 return prev->AppendInstruction(instr); | 148 return prev->AppendInstruction(instr); |
| 149 } | 149 } |
| 150 | 150 |
| 151 | 151 |
| 152 // A block entry wrapper including an index of the next successor to be read. | |
| 153 class PostorderBlockEntryWrapper { | |
| 154 public: | |
| 155 explicit PostorderBlockEntryWrapper(BlockEntryInstr* block) | |
| 156 : block_(block), | |
| 157 next_successor_ix_(block->last_instruction()->SuccessorCount() - 1) { } | |
| 158 | |
| 159 bool HasNextSuccessor() const { return next_successor_ix_ >= 0; } | |
| 160 BlockEntryInstr* NextSuccessor() { | |
| 161 return block_->last_instruction()->SuccessorAt(next_successor_ix_--); | |
| 162 } | |
| 163 | |
| 164 BlockEntryInstr* block() const { return block_; } | |
| 165 | |
| 166 private: | |
| 167 BlockEntryInstr* block_; | |
| 168 intptr_t next_successor_ix_; | |
| 169 | |
| 170 DISALLOW_ALLOCATION(); | |
| 171 }; | |
| 172 | |
| 173 | |
| 174 // Iterative graph postorder traversal. DiscoverBlocks() must have been called | |
| 175 // before this in order to set up BlockEntryInstr::last_instruction(). | |
| 176 static void BuildPostorder(Isolate* isolate, | |
| 177 BlockEntryInstr* graph_entry, | |
| 178 GrowableArray<BlockEntryInstr*>* postorder, | |
| 179 intptr_t num_blocks) { | |
| 180 GrowableArray<PostorderBlockEntryWrapper> block_stack; | |
| 181 block_stack.Add(PostorderBlockEntryWrapper(graph_entry)); | |
| 182 | |
| 183 BitVector visited(isolate, num_blocks); | |
| 184 while (!block_stack.is_empty()) { | |
| 185 PostorderBlockEntryWrapper &last = block_stack.Last(); | |
| 186 BlockEntryInstr* block = last.block(); | |
| 187 visited.Add(block->preorder_number()); | |
| 188 if (last.HasNextSuccessor()) { | |
| 189 // Process successors one-by-one. | |
| 190 BlockEntryInstr* succ = last.NextSuccessor(); | |
| 191 if (!visited.Contains(succ->preorder_number())) { | |
| 192 block_stack.Add(PostorderBlockEntryWrapper(succ)); | |
| 193 } | |
| 194 } else { | |
| 195 // All successors have been processed, pop the current block entry node | |
| 196 // and add it to the postorder list. | |
| 197 block_stack.RemoveLast(); | |
| 198 block->set_postorder_number(postorder->length()); | |
| 199 postorder->Add(block); | |
| 200 } | |
| 201 } | |
| 202 } | |
| 203 | |
| 204 | |
| 152 void FlowGraph::DiscoverBlocks() { | 205 void FlowGraph::DiscoverBlocks() { |
| 153 // Initialize state. | 206 // Initialize state. |
| 154 preorder_.Clear(); | 207 preorder_.Clear(); |
| 155 postorder_.Clear(); | 208 postorder_.Clear(); |
| 156 reverse_postorder_.Clear(); | 209 reverse_postorder_.Clear(); |
| 157 parent_.Clear(); | 210 parent_.Clear(); |
| 158 // Perform a depth-first traversal of the graph to build preorder and | 211 |
| 159 // postorder block orders. | 212 // Perform an iterative depth-first traversal of the graph to build preorder |
| 160 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. | 213 // block order, spanning-tree parents, and predecessors for each block entry. |
| 214 GrowableArray<BlockEntryEdge> block_stack; | |
|
Vyacheslav Egorov (Google)
2014/10/07 12:43:17
I would really like to have this block_stack die a
jgruber1
2014/10/08 15:11:29
Done. I didn't realize the array memory sticks aro
| |
| 215 block_stack.Add(BlockEntryEdge(NULL, graph_entry())); | |
| 216 while (!block_stack.is_empty()) { | |
| 217 BlockEntryEdge pair = block_stack.RemoveLast(); | |
| 218 pair.child->DiscoverBlocks(pair.parent, | |
| 161 &preorder_, | 219 &preorder_, |
| 162 &postorder_, | |
| 163 &parent_, | 220 &parent_, |
| 164 variable_count(), | 221 &block_stack); |
| 165 num_non_copied_params()); | 222 } |
| 223 | |
| 224 // Create an array of blocks in postorder. | |
| 225 const intptr_t block_count = preorder_.length(); | |
|
Vyacheslav Egorov (Google)
2014/10/07 12:43:17
Maybe I am missing something but I think you can b
jgruber1
2014/10/08 15:11:29
Good point, done.
| |
| 226 BuildPostorder(isolate(), graph_entry(), &postorder_, block_count); | |
| 227 ASSERT(postorder_.length() == preorder_.length()); | |
| 228 | |
| 166 // Create an array of blocks in reverse postorder. | 229 // Create an array of blocks in reverse postorder. |
| 167 intptr_t block_count = postorder_.length(); | |
| 168 for (intptr_t i = 0; i < block_count; ++i) { | 230 for (intptr_t i = 0; i < block_count; ++i) { |
| 169 reverse_postorder_.Add(postorder_[block_count - i - 1]); | 231 reverse_postorder_.Add(postorder_[block_count - i - 1]); |
| 170 } | 232 } |
| 171 | 233 |
| 172 // Block effects are using postorder numbering. Discard computed information. | 234 // Block effects are using postorder numbering. Discard computed information. |
| 173 block_effects_ = NULL; | 235 block_effects_ = NULL; |
| 174 loop_headers_ = NULL; | 236 loop_headers_ = NULL; |
| 175 loop_invariant_loads_ = NULL; | 237 loop_invariant_loads_ = NULL; |
| 176 } | 238 } |
| 177 | 239 |
| (...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1255 } | 1317 } |
| 1256 | 1318 |
| 1257 | 1319 |
| 1258 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1320 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
| 1259 BlockEntryInstr* to) const { | 1321 BlockEntryInstr* to) const { |
| 1260 return available_at_[to->postorder_number()]->Contains( | 1322 return available_at_[to->postorder_number()]->Contains( |
| 1261 from->postorder_number()); | 1323 from->postorder_number()); |
| 1262 } | 1324 } |
| 1263 | 1325 |
| 1264 } // namespace dart | 1326 } // namespace dart |
| OLD | NEW |