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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 143 if (use_kind == kValue) { | 143 if (use_kind == kValue) { |
| 144 ASSERT(instr->IsDefinition()); | 144 ASSERT(instr->IsDefinition()); |
| 145 AllocateSSAIndexes(instr->AsDefinition()); | 145 AllocateSSAIndexes(instr->AsDefinition()); |
| 146 } | 146 } |
| 147 ASSERT(instr->env() == NULL); | 147 ASSERT(instr->env() == NULL); |
| 148 if (env != NULL) env->DeepCopyTo(isolate(), instr); | 148 if (env != NULL) env->DeepCopyTo(isolate(), instr); |
| 149 return prev->AppendInstruction(instr); | 149 return prev->AppendInstruction(instr); |
| 150 } | 150 } |
| 151 | 151 |
| 152 | 152 |
| 153 // A wrapper around block entries including an index of the next successor to | |
| 154 // be read. | |
| 155 class BlockTraversalState { | |
| 156 public: | |
| 157 explicit BlockTraversalState(BlockEntryInstr* block) | |
| 158 : block_(block), | |
| 159 next_successor_ix_(block->last_instruction()->SuccessorCount() - 1) { } | |
| 160 | |
| 161 bool HasNextSuccessor() const { return next_successor_ix_ >= 0; } | |
| 162 BlockEntryInstr* NextSuccessor() { | |
| 163 ASSERT(HasNextSuccessor()); | |
| 164 return block_->last_instruction()->SuccessorAt(next_successor_ix_--); | |
| 165 } | |
| 166 | |
| 167 BlockEntryInstr* block() const { return block_; } | |
| 168 | |
| 169 private: | |
| 170 BlockEntryInstr* block_; | |
| 171 intptr_t next_successor_ix_; | |
| 172 | |
| 173 DISALLOW_ALLOCATION(); | |
| 174 }; | |
| 175 | |
| 176 | |
| 153 void FlowGraph::DiscoverBlocks() { | 177 void FlowGraph::DiscoverBlocks() { |
| 178 StackZone zone(isolate()); | |
| 179 | |
| 154 // Initialize state. | 180 // Initialize state. |
| 155 preorder_.Clear(); | 181 preorder_.Clear(); |
| 156 postorder_.Clear(); | 182 postorder_.Clear(); |
| 157 reverse_postorder_.Clear(); | 183 reverse_postorder_.Clear(); |
| 158 parent_.Clear(); | 184 parent_.Clear(); |
| 159 // Perform a depth-first traversal of the graph to build preorder and | 185 |
| 160 // postorder block orders. | 186 GrowableArray<BlockTraversalState> block_stack; |
| 161 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. | 187 graph_entry()->DiscoverBlock(NULL, &preorder_, &parent_); |
| 162 &preorder_, | 188 block_stack.Add(BlockTraversalState(graph_entry_)); |
|
zerny-google
2014/10/09 09:53:32
Nit: consistent use of graph_entry()/graph_entry_
jgruber1
2014/10/09 14:08:36
Done.
| |
| 163 &postorder_, | 189 while (!block_stack.is_empty()) { |
| 164 &parent_, | 190 BlockTraversalState &state = block_stack.Last(); |
| 165 variable_count(), | 191 BlockEntryInstr* block = state.block(); |
| 166 num_non_copied_params()); | 192 if (state.HasNextSuccessor()) { |
| 193 // Process successors one-by-one. | |
| 194 BlockEntryInstr* succ = state.NextSuccessor(); | |
| 195 if (succ->DiscoverBlock(block, &preorder_, &parent_)) { | |
| 196 block_stack.Add(BlockTraversalState(succ)); | |
| 197 } | |
| 198 } else { | |
| 199 // All successors have been processed, pop the current block entry node | |
| 200 // and add it to the postorder list. | |
| 201 block_stack.RemoveLast(); | |
| 202 block->set_postorder_number(postorder_.length()); | |
| 203 postorder_.Add(block); | |
| 204 } | |
| 205 } | |
| 206 | |
| 207 ASSERT(postorder_.length() == preorder_.length()); | |
| 208 | |
| 167 // Create an array of blocks in reverse postorder. | 209 // Create an array of blocks in reverse postorder. |
| 168 intptr_t block_count = postorder_.length(); | 210 intptr_t block_count = postorder_.length(); |
| 169 for (intptr_t i = 0; i < block_count; ++i) { | 211 for (intptr_t i = 0; i < block_count; ++i) { |
| 170 reverse_postorder_.Add(postorder_[block_count - i - 1]); | 212 reverse_postorder_.Add(postorder_[block_count - i - 1]); |
| 171 } | 213 } |
| 172 | 214 |
| 173 // Block effects are using postorder numbering. Discard computed information. | 215 // Block effects are using postorder numbering. Discard computed information. |
| 174 block_effects_ = NULL; | 216 block_effects_ = NULL; |
| 175 loop_headers_ = NULL; | 217 loop_headers_ = NULL; |
| 176 loop_invariant_loads_ = NULL; | 218 loop_invariant_loads_ = NULL; |
| (...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1256 } | 1298 } |
| 1257 | 1299 |
| 1258 | 1300 |
| 1259 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1301 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
| 1260 BlockEntryInstr* to) const { | 1302 BlockEntryInstr* to) const { |
| 1261 return available_at_[to->postorder_number()]->Contains( | 1303 return available_at_[to->postorder_number()]->Contains( |
| 1262 from->postorder_number()); | 1304 from->postorder_number()); |
| 1263 } | 1305 } |
| 1264 | 1306 |
| 1265 } // namespace dart | 1307 } // namespace dart |
| OLD | NEW |