| 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/object.h" | 7 #include "vm/object.h" |
| 8 #include "vm/os.h" | 8 #include "vm/os.h" |
| 9 #include "vm/scopes.h" | 9 #include "vm/scopes.h" |
| 10 | 10 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 86 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 87 Instruction* current = block_order_[i]->Accept(this); | 87 Instruction* current = block_order_[i]->Accept(this); |
| 88 while ((current != NULL) && !current->IsBlockEntry()) { | 88 while ((current != NULL) && !current->IsBlockEntry()) { |
| 89 current = current->Accept(this); | 89 current = current->Accept(this); |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 } | 92 } |
| 93 | 93 |
| 94 | 94 |
| 95 // ==== Postorder graph traversal. | 95 // ==== Postorder graph traversal. |
| 96 void JoinEntryInstr::DepthFirstSearch( | 96 void JoinEntryInstr::DiscoverBlocks( |
| 97 BlockEntryInstr* current_block, |
| 97 GrowableArray<BlockEntryInstr*>* preorder, | 98 GrowableArray<BlockEntryInstr*>* preorder, |
| 98 GrowableArray<BlockEntryInstr*>* postorder) { | 99 GrowableArray<BlockEntryInstr*>* postorder, |
| 99 // JoinEntryInstr is the only instruction that can have more than one | 100 GrowableArray<BlockEntryInstr*>* parent) { |
| 100 // predecessor, so it is the only one that could be reached more than once | 101 // The global graph entry is a TargetEntryInstr, so we can assume |
| 101 // during the traversal. | 102 // current_block is non-null and preorder array is non-empty. |
| 102 // | 103 ASSERT(current_block != NULL); |
| 103 // Use the presence of a preorder number to indicate that it has already | 104 ASSERT(!preorder->is_empty()); |
| 104 // been reached. | 105 |
| 106 // 1. Record control-flow-graph basic-block predecessors. |
| 107 predecessors_.Add(current_block); |
| 108 |
| 109 // 2. If the block has already been reached by the traversal, we are done. |
| 105 if (preorder_number() >= 0) return; | 110 if (preorder_number() >= 0) return; |
| 111 |
| 112 // 3. The last entry in the preorder array is the spanning-tree parent. |
| 113 parent->Add(preorder->Last()); |
| 114 |
| 115 // 4. Assign preorder number and add the block entry to the list. |
| 106 set_preorder_number(preorder->length()); | 116 set_preorder_number(preorder->length()); |
| 107 preorder->Add(this); | 117 preorder->Add(this); |
| 118 // The preorder and parent arrays are both indexed by preorder block |
| 119 // number, so they should stay in lockstep. |
| 120 ASSERT(preorder->length() == parent->length()); |
| 121 |
| 122 // 5. Recursively visit the successor. |
| 108 ASSERT(successor_ != NULL); | 123 ASSERT(successor_ != NULL); |
| 109 successor_->DepthFirstSearch(preorder, postorder); | 124 successor_->DiscoverBlocks(this, preorder, postorder, parent); |
| 125 |
| 126 // 6. Assign postorder number and add the block entry to the list. |
| 110 set_postorder_number(postorder->length()); | 127 set_postorder_number(postorder->length()); |
| 111 postorder->Add(this); | 128 postorder->Add(this); |
| 112 } | 129 } |
| 113 | 130 |
| 114 | 131 |
| 115 void TargetEntryInstr::DepthFirstSearch( | 132 void TargetEntryInstr::DiscoverBlocks( |
| 133 BlockEntryInstr* current_block, |
| 116 GrowableArray<BlockEntryInstr*>* preorder, | 134 GrowableArray<BlockEntryInstr*>* preorder, |
| 117 GrowableArray<BlockEntryInstr*>* postorder) { | 135 GrowableArray<BlockEntryInstr*>* postorder, |
| 136 GrowableArray<BlockEntryInstr*>* parent) { |
| 137 // 1. Record control-flow-graph basic-block predecessors. |
| 138 ASSERT(predecessor_ == NULL); |
| 139 predecessor_ = current_block; // Might be NULL (for the graph entry). |
| 140 |
| 141 // 2. There is a single predecessor, so we should only reach this block once. |
| 118 ASSERT(preorder_number() == -1); | 142 ASSERT(preorder_number() == -1); |
| 143 |
| 144 // 3. The last entry in the preorder array is the spanning-tree parent. |
| 145 // The global graph entry has a NULL parent. |
| 146 parent->Add(preorder->is_empty() ? NULL : preorder->Last()); |
| 147 |
| 148 // 4. Assign preorder number and add the block entry to the list. |
| 119 set_preorder_number(preorder->length()); | 149 set_preorder_number(preorder->length()); |
| 120 preorder->Add(this); | 150 preorder->Add(this); |
| 151 // The preorder and parent arrays are indexed by preorder block number, so |
| 152 // they should stay in lockstep. |
| 153 ASSERT(preorder->length() == parent->length()); |
| 154 |
| 155 // 5. Recursively visit the successor. |
| 121 ASSERT(successor_ != NULL); | 156 ASSERT(successor_ != NULL); |
| 122 successor_->DepthFirstSearch(preorder, postorder); | 157 successor_->DiscoverBlocks(this, preorder, postorder, parent); |
| 158 |
| 159 // 6. Assign postorder number and add the block entry to the list. |
| 123 set_postorder_number(postorder->length()); | 160 set_postorder_number(postorder->length()); |
| 124 postorder->Add(this); | 161 postorder->Add(this); |
| 125 } | 162 } |
| 126 | 163 |
| 127 | 164 |
| 128 void PickTempInstr::DepthFirstSearch( | 165 void PickTempInstr::DiscoverBlocks( |
| 166 BlockEntryInstr* current_block, |
| 129 GrowableArray<BlockEntryInstr*>* preorder, | 167 GrowableArray<BlockEntryInstr*>* preorder, |
| 130 GrowableArray<BlockEntryInstr*>* postorder) { | 168 GrowableArray<BlockEntryInstr*>* postorder, |
| 169 GrowableArray<BlockEntryInstr*>* parent) { |
| 170 current_block->set_last_instruction(this); |
| 131 ASSERT(successor_ != NULL); | 171 ASSERT(successor_ != NULL); |
| 132 successor_->DepthFirstSearch(preorder, postorder); | 172 successor_->DiscoverBlocks(current_block, preorder, postorder, parent); |
| 133 } | 173 } |
| 134 | 174 |
| 135 | 175 |
| 136 void TuckTempInstr::DepthFirstSearch( | 176 void TuckTempInstr::DiscoverBlocks( |
| 177 BlockEntryInstr* current_block, |
| 137 GrowableArray<BlockEntryInstr*>* preorder, | 178 GrowableArray<BlockEntryInstr*>* preorder, |
| 138 GrowableArray<BlockEntryInstr*>* postorder) { | 179 GrowableArray<BlockEntryInstr*>* postorder, |
| 180 GrowableArray<BlockEntryInstr*>* parent) { |
| 181 current_block->set_last_instruction(this); |
| 139 ASSERT(successor_ != NULL); | 182 ASSERT(successor_ != NULL); |
| 140 successor_->DepthFirstSearch(preorder, postorder); | 183 successor_->DiscoverBlocks(current_block, preorder, postorder, parent); |
| 141 } | 184 } |
| 142 | 185 |
| 143 | 186 |
| 144 void DoInstr::DepthFirstSearch( | 187 void DoInstr::DiscoverBlocks( |
| 188 BlockEntryInstr* current_block, |
| 145 GrowableArray<BlockEntryInstr*>* preorder, | 189 GrowableArray<BlockEntryInstr*>* preorder, |
| 146 GrowableArray<BlockEntryInstr*>* postorder) { | 190 GrowableArray<BlockEntryInstr*>* postorder, |
| 191 GrowableArray<BlockEntryInstr*>* parent) { |
| 192 current_block->set_last_instruction(this); |
| 147 ASSERT(successor_ != NULL); | 193 ASSERT(successor_ != NULL); |
| 148 successor_->DepthFirstSearch(preorder, postorder); | 194 successor_->DiscoverBlocks(current_block, preorder, postorder, parent); |
| 149 } | 195 } |
| 150 | 196 |
| 151 | 197 |
| 152 void BindInstr::DepthFirstSearch( | 198 void BindInstr::DiscoverBlocks( |
| 199 BlockEntryInstr* current_block, |
| 153 GrowableArray<BlockEntryInstr*>* preorder, | 200 GrowableArray<BlockEntryInstr*>* preorder, |
| 154 GrowableArray<BlockEntryInstr*>* postorder) { | 201 GrowableArray<BlockEntryInstr*>* postorder, |
| 202 GrowableArray<BlockEntryInstr*>* parent) { |
| 203 current_block->set_last_instruction(this); |
| 155 ASSERT(successor_ != NULL); | 204 ASSERT(successor_ != NULL); |
| 156 successor_->DepthFirstSearch(preorder, postorder); | 205 successor_->DiscoverBlocks(current_block, preorder, postorder, parent); |
| 157 } | 206 } |
| 158 | 207 |
| 159 | 208 |
| 160 void ReturnInstr::DepthFirstSearch( | 209 void ReturnInstr::DiscoverBlocks( |
| 210 BlockEntryInstr* current_block, |
| 161 GrowableArray<BlockEntryInstr*>* preorder, | 211 GrowableArray<BlockEntryInstr*>* preorder, |
| 162 GrowableArray<BlockEntryInstr*>* postorder) { | 212 GrowableArray<BlockEntryInstr*>* postorder, |
| 213 GrowableArray<BlockEntryInstr*>* parent) { |
| 214 current_block->set_last_instruction(this); |
| 163 } | 215 } |
| 164 | 216 |
| 165 | 217 |
| 166 void ThrowInstr::DepthFirstSearch( | 218 void ThrowInstr::DiscoverBlocks( |
| 219 BlockEntryInstr* current_block, |
| 167 GrowableArray<BlockEntryInstr*>* preorder, | 220 GrowableArray<BlockEntryInstr*>* preorder, |
| 168 GrowableArray<BlockEntryInstr*>* postorder) { | 221 GrowableArray<BlockEntryInstr*>* postorder, |
| 222 GrowableArray<BlockEntryInstr*>* parent) { |
| 223 current_block->set_last_instruction(this); |
| 169 } | 224 } |
| 170 | 225 |
| 171 | 226 |
| 172 void ReThrowInstr::DepthFirstSearch( | 227 void ReThrowInstr::DiscoverBlocks( |
| 228 BlockEntryInstr* current_block, |
| 173 GrowableArray<BlockEntryInstr*>* preorder, | 229 GrowableArray<BlockEntryInstr*>* preorder, |
| 174 GrowableArray<BlockEntryInstr*>* postorder) { | 230 GrowableArray<BlockEntryInstr*>* postorder, |
| 231 GrowableArray<BlockEntryInstr*>* parent) { |
| 232 current_block->set_last_instruction(this); |
| 175 } | 233 } |
| 176 | 234 |
| 177 | 235 |
| 178 void BranchInstr::DepthFirstSearch( | 236 void BranchInstr::DiscoverBlocks( |
| 237 BlockEntryInstr* current_block, |
| 179 GrowableArray<BlockEntryInstr*>* preorder, | 238 GrowableArray<BlockEntryInstr*>* preorder, |
| 180 GrowableArray<BlockEntryInstr*>* postorder) { | 239 GrowableArray<BlockEntryInstr*>* postorder, |
| 240 GrowableArray<BlockEntryInstr*>* parent) { |
| 241 current_block->set_last_instruction(this); |
| 181 // Visit the false successor before the true successor so they appear in | 242 // Visit the false successor before the true successor so they appear in |
| 182 // true/false order in reverse postorder used as the block ordering in the | 243 // true/false order in reverse postorder used as the block ordering in the |
| 183 // nonoptimizing compiler. | 244 // nonoptimizing compiler. |
| 184 ASSERT(true_successor_ != NULL); | 245 ASSERT(true_successor_ != NULL); |
| 185 ASSERT(false_successor_ != NULL); | 246 ASSERT(false_successor_ != NULL); |
| 186 false_successor_->DepthFirstSearch(preorder, postorder); | 247 false_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); |
| 187 true_successor_->DepthFirstSearch(preorder, postorder); | 248 true_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); |
| 188 } | 249 } |
| 189 | 250 |
| 190 | 251 |
| 191 } // namespace dart | 252 } // namespace dart |
| OLD | NEW |