| 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 Instruction* BranchInstr::Accept(FlowGraphVisitor* visitor) { | 78 Instruction* BranchInstr::Accept(FlowGraphVisitor* visitor) { |
| 79 visitor->VisitBranch(this); | 79 visitor->VisitBranch(this); |
| 80 return NULL; | 80 return NULL; |
| 81 } | 81 } |
| 82 | 82 |
| 83 | 83 |
| 84 // Default implementation of visiting basic blocks. Can be overridden. | 84 // Default implementation of visiting basic blocks. Can be overridden. |
| 85 void FlowGraphVisitor::VisitBlocks( | 85 void FlowGraphVisitor::VisitBlocks() { |
| 86 const GrowableArray<BlockEntryInstr*>& block_order) { | 86 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 87 for (intptr_t i = block_order.length() - 1; i >= 0; --i) { | 87 Instruction* current = block_order_[i]->Accept(this); |
| 88 Instruction* current = block_order[i]->Accept(this); | |
| 89 while ((current != NULL) && !current->IsBlockEntry()) { | 88 while ((current != NULL) && !current->IsBlockEntry()) { |
| 90 current = current->Accept(this); | 89 current = current->Accept(this); |
| 91 } | 90 } |
| 92 } | 91 } |
| 93 } | 92 } |
| 94 | 93 |
| 95 | 94 |
| 96 // ==== Postorder graph traversal. | 95 // ==== Postorder graph traversal. |
| 97 void JoinEntryInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) { | 96 void JoinEntryInstr::DepthFirstSearch( |
| 98 flip_mark(); | 97 GrowableArray<BlockEntryInstr*>* preorder, |
| 98 GrowableArray<BlockEntryInstr*>* postorder) { |
| 99 // JoinEntryInstr is the only instruction that can have more than one |
| 100 // predecessor, so it is the only one that could be reached more than once |
| 101 // during the traversal. |
| 102 // |
| 103 // Use the presence of a preorder number to indicate that it has already |
| 104 // been reached. |
| 105 if (preorder_number() >= 0) return; |
| 106 set_preorder_number(preorder->length()); |
| 107 preorder->Add(this); |
| 99 ASSERT(successor_ != NULL); | 108 ASSERT(successor_ != NULL); |
| 100 if (successor_->mark() != mark()) successor_->Postorder(block_entries); | 109 successor_->DepthFirstSearch(preorder, postorder); |
| 101 block_entries->Add(this); | 110 set_postorder_number(postorder->length()); |
| 111 postorder->Add(this); |
| 102 } | 112 } |
| 103 | 113 |
| 104 | 114 |
| 105 void TargetEntryInstr::Postorder( | 115 void TargetEntryInstr::DepthFirstSearch( |
| 106 GrowableArray<BlockEntryInstr*>* block_entries) { | 116 GrowableArray<BlockEntryInstr*>* preorder, |
| 107 flip_mark(); | 117 GrowableArray<BlockEntryInstr*>* postorder) { |
| 118 ASSERT(preorder_number() == -1); |
| 119 set_preorder_number(preorder->length()); |
| 120 preorder->Add(this); |
| 108 ASSERT(successor_ != NULL); | 121 ASSERT(successor_ != NULL); |
| 109 if (successor_->mark() != mark()) successor_->Postorder(block_entries); | 122 successor_->DepthFirstSearch(preorder, postorder); |
| 110 block_entries->Add(this); | 123 set_postorder_number(postorder->length()); |
| 124 postorder->Add(this); |
| 111 } | 125 } |
| 112 | 126 |
| 113 | 127 |
| 114 void PickTempInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) { | 128 void PickTempInstr::DepthFirstSearch( |
| 115 flip_mark(); | 129 GrowableArray<BlockEntryInstr*>* preorder, |
| 130 GrowableArray<BlockEntryInstr*>* postorder) { |
| 116 ASSERT(successor_ != NULL); | 131 ASSERT(successor_ != NULL); |
| 117 if (successor_->mark() != mark()) successor_->Postorder(block_entries); | 132 successor_->DepthFirstSearch(preorder, postorder); |
| 118 } | 133 } |
| 119 | 134 |
| 120 | 135 |
| 121 void TuckTempInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) { | 136 void TuckTempInstr::DepthFirstSearch( |
| 122 flip_mark(); | 137 GrowableArray<BlockEntryInstr*>* preorder, |
| 138 GrowableArray<BlockEntryInstr*>* postorder) { |
| 123 ASSERT(successor_ != NULL); | 139 ASSERT(successor_ != NULL); |
| 124 if (successor_->mark() != mark()) successor_->Postorder(block_entries); | 140 successor_->DepthFirstSearch(preorder, postorder); |
| 125 } | 141 } |
| 126 | 142 |
| 127 | 143 |
| 128 void DoInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) { | 144 void DoInstr::DepthFirstSearch( |
| 129 flip_mark(); | 145 GrowableArray<BlockEntryInstr*>* preorder, |
| 146 GrowableArray<BlockEntryInstr*>* postorder) { |
| 130 ASSERT(successor_ != NULL); | 147 ASSERT(successor_ != NULL); |
| 131 if (successor_->mark() != mark()) successor_->Postorder(block_entries); | 148 successor_->DepthFirstSearch(preorder, postorder); |
| 132 } | 149 } |
| 133 | 150 |
| 134 | 151 |
| 135 void BindInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) { | 152 void BindInstr::DepthFirstSearch( |
| 136 flip_mark(); | 153 GrowableArray<BlockEntryInstr*>* preorder, |
| 154 GrowableArray<BlockEntryInstr*>* postorder) { |
| 137 ASSERT(successor_ != NULL); | 155 ASSERT(successor_ != NULL); |
| 138 if (successor_->mark() != mark()) successor_->Postorder(block_entries); | 156 successor_->DepthFirstSearch(preorder, postorder); |
| 139 } | 157 } |
| 140 | 158 |
| 141 | 159 |
| 142 void ReturnInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) { | 160 void ReturnInstr::DepthFirstSearch( |
| 143 flip_mark(); | 161 GrowableArray<BlockEntryInstr*>* preorder, |
| 162 GrowableArray<BlockEntryInstr*>* postorder) { |
| 144 } | 163 } |
| 145 | 164 |
| 146 | 165 |
| 147 void ThrowInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) { | 166 void ThrowInstr::DepthFirstSearch( |
| 148 flip_mark(); | 167 GrowableArray<BlockEntryInstr*>* preorder, |
| 168 GrowableArray<BlockEntryInstr*>* postorder) { |
| 149 } | 169 } |
| 150 | 170 |
| 151 | 171 |
| 152 void ReThrowInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) { | 172 void ReThrowInstr::DepthFirstSearch( |
| 153 flip_mark(); | 173 GrowableArray<BlockEntryInstr*>* preorder, |
| 174 GrowableArray<BlockEntryInstr*>* postorder) { |
| 154 } | 175 } |
| 155 | 176 |
| 156 | 177 |
| 157 void BranchInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) { | 178 void BranchInstr::DepthFirstSearch( |
| 158 flip_mark(); | 179 GrowableArray<BlockEntryInstr*>* preorder, |
| 180 GrowableArray<BlockEntryInstr*>* postorder) { |
| 159 // Visit the false successor before the true successor so they appear in | 181 // Visit the false successor before the true successor so they appear in |
| 160 // true/false order in reverse postorder. | 182 // true/false order in reverse postorder used as the block ordering in the |
| 183 // nonoptimizing compiler. |
| 184 ASSERT(true_successor_ != NULL); |
| 161 ASSERT(false_successor_ != NULL); | 185 ASSERT(false_successor_ != NULL); |
| 162 ASSERT(true_successor_ != NULL); | 186 false_successor_->DepthFirstSearch(preorder, postorder); |
| 163 if (false_successor_->mark() != mark()) { | 187 true_successor_->DepthFirstSearch(preorder, postorder); |
| 164 false_successor_->Postorder(block_entries); | |
| 165 } | |
| 166 if (true_successor_->mark() != mark()) { | |
| 167 true_successor_->Postorder(block_entries); | |
| 168 } | |
| 169 } | 188 } |
| 170 | 189 |
| 171 | 190 |
| 172 } // namespace dart | 191 } // namespace dart |
| OLD | NEW |