| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 } | 92 } |
| 93 | 93 |
| 94 | 94 |
| 95 // ==== Postorder graph traversal. | 95 // ==== Postorder graph traversal. |
| 96 void JoinEntryInstr::DiscoverBlocks( | 96 void JoinEntryInstr::DiscoverBlocks( |
| 97 BlockEntryInstr* current_block, | 97 BlockEntryInstr* current_block, |
| 98 GrowableArray<BlockEntryInstr*>* preorder, | 98 GrowableArray<BlockEntryInstr*>* preorder, |
| 99 GrowableArray<BlockEntryInstr*>* postorder, | 99 GrowableArray<BlockEntryInstr*>* postorder, |
| 100 GrowableArray<BlockEntryInstr*>* parent) { | 100 GrowableArray<intptr_t>* parent) { |
| 101 // The global graph entry is a TargetEntryInstr, so we can assume | 101 // The global graph entry is a TargetEntryInstr, so we can assume |
| 102 // current_block is non-null and preorder array is non-empty. | 102 // current_block is non-null and preorder array is non-empty. |
| 103 ASSERT(current_block != NULL); | 103 ASSERT(current_block != NULL); |
| 104 ASSERT(!preorder->is_empty()); | 104 ASSERT(!preorder->is_empty()); |
| 105 | 105 |
| 106 // 1. Record control-flow-graph basic-block predecessors. | 106 // 1. Record control-flow-graph basic-block predecessors. |
| 107 predecessors_.Add(current_block); | 107 predecessors_.Add(current_block); |
| 108 | 108 |
| 109 // 2. If the block has already been reached by the traversal, we are done. | 109 // 2. If the block has already been reached by the traversal, we are done. |
| 110 if (preorder_number() >= 0) return; | 110 if (preorder_number() >= 0) return; |
| 111 | 111 |
| 112 // 3. The last entry in the preorder array is the spanning-tree parent. | 112 // 3. The last entry in the preorder array is the spanning-tree parent. |
| 113 parent->Add(preorder->Last()); | 113 intptr_t parent_number = preorder->length() - 1; |
| 114 parent->Add(parent_number); |
| 114 | 115 |
| 115 // 4. Assign preorder number and add the block entry to the list. | 116 // 4. Assign preorder number and add the block entry to the list. |
| 116 set_preorder_number(preorder->length()); | 117 set_preorder_number(parent_number + 1); |
| 117 preorder->Add(this); | 118 preorder->Add(this); |
| 118 // The preorder and parent arrays are both indexed by preorder block | 119 // The preorder and parent arrays are both indexed by preorder block |
| 119 // number, so they should stay in lockstep. | 120 // number, so they should stay in lockstep. |
| 120 ASSERT(preorder->length() == parent->length()); | 121 ASSERT(preorder->length() == parent->length()); |
| 121 | 122 |
| 122 // 5. Iterate straight-line successors until a branch instruction or | 123 // 5. Iterate straight-line successors until a branch instruction or |
| 123 // another basic block entry instruction, and visit that instruction. | 124 // another basic block entry instruction, and visit that instruction. |
| 124 ASSERT(successor_ != NULL); | 125 ASSERT(successor_ != NULL); |
| 125 Instruction* next = successor_; | 126 Instruction* next = successor_; |
| 126 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) { | 127 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) { |
| 127 set_last_instruction(next); | 128 set_last_instruction(next); |
| 128 next = next->StraightLineSuccessor(); | 129 next = next->StraightLineSuccessor(); |
| 129 } | 130 } |
| 130 if (next != NULL) { | 131 if (next != NULL) { |
| 131 next->DiscoverBlocks(this, preorder, postorder, parent); | 132 next->DiscoverBlocks(this, preorder, postorder, parent); |
| 132 } | 133 } |
| 133 | 134 |
| 134 // 6. Assign postorder number and add the block entry to the list. | 135 // 6. Assign postorder number and add the block entry to the list. |
| 135 set_postorder_number(postorder->length()); | 136 set_postorder_number(postorder->length()); |
| 136 postorder->Add(this); | 137 postorder->Add(this); |
| 137 } | 138 } |
| 138 | 139 |
| 139 | 140 |
| 140 void TargetEntryInstr::DiscoverBlocks( | 141 void TargetEntryInstr::DiscoverBlocks( |
| 141 BlockEntryInstr* current_block, | 142 BlockEntryInstr* current_block, |
| 142 GrowableArray<BlockEntryInstr*>* preorder, | 143 GrowableArray<BlockEntryInstr*>* preorder, |
| 143 GrowableArray<BlockEntryInstr*>* postorder, | 144 GrowableArray<BlockEntryInstr*>* postorder, |
| 144 GrowableArray<BlockEntryInstr*>* parent) { | 145 GrowableArray<intptr_t>* parent) { |
| 145 // 1. Record control-flow-graph basic-block predecessors. | 146 // 1. Record control-flow-graph basic-block predecessors. |
| 146 ASSERT(predecessor_ == NULL); | 147 ASSERT(predecessor_ == NULL); |
| 147 predecessor_ = current_block; // Might be NULL (for the graph entry). | 148 predecessor_ = current_block; // Might be NULL (for the graph entry). |
| 148 | 149 |
| 149 // 2. There is a single predecessor, so we should only reach this block once. | 150 // 2. There is a single predecessor, so we should only reach this block once. |
| 150 ASSERT(preorder_number() == -1); | 151 ASSERT(preorder_number() == -1); |
| 151 | 152 |
| 152 // 3. The last entry in the preorder array is the spanning-tree parent. | 153 // 3. The last entry in the preorder array is the spanning-tree parent. |
| 153 // The global graph entry has a NULL parent. | 154 // The global graph entry has no parent, indicated by -1. |
| 154 parent->Add(preorder->is_empty() ? NULL : preorder->Last()); | 155 intptr_t parent_number = preorder->length() - 1; |
| 156 parent->Add(parent_number); |
| 155 | 157 |
| 156 // 4. Assign preorder number and add the block entry to the list. | 158 // 4. Assign preorder number and add the block entry to the list. |
| 157 set_preorder_number(preorder->length()); | 159 set_preorder_number(parent_number + 1); |
| 158 preorder->Add(this); | 160 preorder->Add(this); |
| 159 // The preorder and parent arrays are indexed by preorder block number, so | 161 // The preorder and parent arrays are indexed by preorder block number, so |
| 160 // they should stay in lockstep. | 162 // they should stay in lockstep. |
| 161 ASSERT(preorder->length() == parent->length()); | 163 ASSERT(preorder->length() == parent->length()); |
| 162 | 164 |
| 163 // 5. Iterate straight-line successors until a branch instruction or | 165 // 5. Iterate straight-line successors until a branch instruction or |
| 164 // another basic block entry instruction, and visit that instruction. | 166 // another basic block entry instruction, and visit that instruction. |
| 165 ASSERT(successor_ != NULL); | 167 ASSERT(successor_ != NULL); |
| 166 Instruction* next = successor_; | 168 Instruction* next = successor_; |
| 167 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) { | 169 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) { |
| 168 set_last_instruction(next); | 170 set_last_instruction(next); |
| 169 next = next->StraightLineSuccessor(); | 171 next = next->StraightLineSuccessor(); |
| 170 } | 172 } |
| 171 if (next != NULL) { | 173 if (next != NULL) { |
| 172 next->DiscoverBlocks(this, preorder, postorder, parent); | 174 next->DiscoverBlocks(this, preorder, postorder, parent); |
| 173 } | 175 } |
| 174 | 176 |
| 175 // 6. Assign postorder number and add the block entry to the list. | 177 // 6. Assign postorder number and add the block entry to the list. |
| 176 set_postorder_number(postorder->length()); | 178 set_postorder_number(postorder->length()); |
| 177 postorder->Add(this); | 179 postorder->Add(this); |
| 178 } | 180 } |
| 179 | 181 |
| 180 | 182 |
| 181 void BranchInstr::DiscoverBlocks( | 183 void BranchInstr::DiscoverBlocks( |
| 182 BlockEntryInstr* current_block, | 184 BlockEntryInstr* current_block, |
| 183 GrowableArray<BlockEntryInstr*>* preorder, | 185 GrowableArray<BlockEntryInstr*>* preorder, |
| 184 GrowableArray<BlockEntryInstr*>* postorder, | 186 GrowableArray<BlockEntryInstr*>* postorder, |
| 185 GrowableArray<BlockEntryInstr*>* parent) { | 187 GrowableArray<intptr_t>* parent) { |
| 186 current_block->set_last_instruction(this); | 188 current_block->set_last_instruction(this); |
| 187 // Visit the false successor before the true successor so they appear in | 189 // Visit the false successor before the true successor so they appear in |
| 188 // true/false order in reverse postorder used as the block ordering in the | 190 // true/false order in reverse postorder used as the block ordering in the |
| 189 // nonoptimizing compiler. | 191 // nonoptimizing compiler. |
| 190 ASSERT(true_successor_ != NULL); | 192 ASSERT(true_successor_ != NULL); |
| 191 ASSERT(false_successor_ != NULL); | 193 ASSERT(false_successor_ != NULL); |
| 192 false_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); | 194 false_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); |
| 193 true_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); | 195 true_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); |
| 194 } | 196 } |
| 195 | 197 |
| 196 | 198 |
| 197 } // namespace dart | 199 } // namespace dart |
| OLD | NEW |