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 |