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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | |
| 7 #include "vm/object.h" | 8 #include "vm/object.h" |
| 8 #include "vm/os.h" | 9 #include "vm/os.h" |
| 9 #include "vm/scopes.h" | 10 #include "vm/scopes.h" |
| 10 | 11 |
| 11 namespace dart { | 12 namespace dart { |
| 12 | 13 |
| 13 // ==== Support for visiting flow graphs. | 14 // ==== Support for visiting flow graphs. |
| 14 #define DEFINE_ACCEPT(ShortName, ClassName) \ | 15 #define DEFINE_ACCEPT(ShortName, ClassName) \ |
| 15 void ClassName::Accept(FlowGraphVisitor* visitor) { \ | 16 void ClassName::Accept(FlowGraphVisitor* visitor) { \ |
| 16 visitor->Visit##ShortName(this); \ | 17 visitor->Visit##ShortName(this); \ |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 intptr_t TargetEntryInstr::InputCount() const { | 186 intptr_t TargetEntryInstr::InputCount() const { |
| 186 return 0; | 187 return 0; |
| 187 } | 188 } |
| 188 | 189 |
| 189 | 190 |
| 190 intptr_t JoinEntryInstr::InputCount() const { | 191 intptr_t JoinEntryInstr::InputCount() const { |
| 191 return 0; | 192 return 0; |
| 192 } | 193 } |
| 193 | 194 |
| 194 | 195 |
| 196 // ==== Recording assigned variables. | |
| 197 void Computation::RecordAssignedVars(BitVector* assigned_vars) { | |
| 198 // Nothing to do for the base class. | |
| 199 } | |
| 200 | |
| 201 | |
| 202 void StoreLocalComp::RecordAssignedVars(BitVector* assigned_vars) { | |
| 203 if (!local().is_captured()) { | |
| 204 int index = local().index(); | |
| 205 // Parameters have positive indexes with the lowest index being 2. | |
| 206 // Locals and copied parameters have negative indexes with the lowest | |
| 207 // being -1. | |
| 208 if (index > 0) { | |
| 209 // Shift parameter indexes so that the lowest index is 0. | |
| 210 index -= 2; | |
|
srdjan
2012/05/12 00:00:55
Note that soon we will add a third word after ebp
Kevin Millikin (Google)
2012/05/15 11:51:44
Well, we either have to deal with the 'magic' extr
srdjan
2012/05/15 22:05:32
Can we put intelligence into LocalVariable? If you
| |
| 211 } else { | |
| 212 // Store local and copied parameters backward from the end of the bit | |
| 213 // vector. | |
| 214 index = assigned_vars->length() + index; // Index is negative. | |
| 215 } | |
| 216 assigned_vars->Add(index); | |
| 217 } | |
| 218 } | |
| 219 | |
| 220 | |
| 221 void Instruction::RecordAssignedVars(BitVector* assigned_vars) { | |
| 222 // Nothing to do for the base class. | |
| 223 } | |
| 224 | |
| 225 | |
| 226 void DoInstr::RecordAssignedVars(BitVector* assigned_vars) { | |
| 227 computation()->RecordAssignedVars(assigned_vars); | |
| 228 } | |
| 229 | |
| 230 | |
| 231 void BindInstr::RecordAssignedVars(BitVector* assigned_vars) { | |
| 232 computation()->RecordAssignedVars(assigned_vars); | |
| 233 } | |
| 234 | |
| 235 | |
| 195 // ==== Postorder graph traversal. | 236 // ==== Postorder graph traversal. |
| 196 void JoinEntryInstr::DiscoverBlocks( | 237 void BlockEntryInstr::DiscoverBlocks( |
| 197 BlockEntryInstr* current_block, | 238 BlockEntryInstr* current_block, |
| 198 GrowableArray<BlockEntryInstr*>* preorder, | 239 GrowableArray<BlockEntryInstr*>* preorder, |
| 199 GrowableArray<BlockEntryInstr*>* postorder, | 240 GrowableArray<BlockEntryInstr*>* postorder, |
| 200 GrowableArray<intptr_t>* parent) { | 241 GrowableArray<intptr_t>* parent, |
| 242 GrowableArray<BitVector*>* assigned_vars, | |
| 243 intptr_t variable_count) { | |
| 201 // The global graph entry is a TargetEntryInstr, so we can assume | 244 // The global graph entry is a TargetEntryInstr, so we can assume |
| 202 // current_block is non-null and preorder array is non-empty. | 245 // current_block is non-null and preorder array is non-empty. |
| 203 ASSERT(current_block != NULL); | 246 ASSERT(!IsJoinEntry() || (current_block != NULL)); |
| 204 ASSERT(!preorder->is_empty()); | 247 ASSERT(!IsJoinEntry() || !preorder->is_empty()); |
| 205 | 248 |
| 206 // 1. Record control-flow-graph basic-block predecessors. | 249 // 1. Record control-flow-graph basic-block predecessors. |
| 207 predecessors_.Add(current_block); | 250 AddPredecessor(current_block); |
| 208 | 251 |
| 209 // 2. If the block has already been reached by the traversal, we are done. | 252 // 2. If the block has already been reached by the traversal, we are |
| 253 // done. Blocks with a single predecessor cannot have been reached | |
| 254 // before. | |
| 255 ASSERT(!IsTargetEntry() || (preorder_number() == -1)); | |
| 210 if (preorder_number() >= 0) return; | 256 if (preorder_number() >= 0) return; |
| 211 | 257 |
| 212 // 3. The last entry in the preorder array is the spanning-tree parent. | 258 // 3. The last entry in the preorder array is the spanning-tree parent. |
| 213 intptr_t parent_number = preorder->length() - 1; | 259 intptr_t parent_number = preorder->length() - 1; |
| 214 parent->Add(parent_number); | 260 parent->Add(parent_number); |
| 215 | 261 |
| 216 // 4. Assign preorder number and add the block entry to the list. | 262 // 4. Assign preorder number and add the block entry to the list. |
| 263 // Allocate an empty set of assigned variables for the block. | |
| 217 set_preorder_number(parent_number + 1); | 264 set_preorder_number(parent_number + 1); |
| 218 preorder->Add(this); | 265 preorder->Add(this); |
| 219 // The preorder and parent arrays are both indexed by preorder block | 266 BitVector* vars = (variable_count == 0) |
| 220 // number, so they should stay in lockstep. | 267 ? NULL |
| 268 : new BitVector(variable_count, Isolate::Current()->current_zone()); | |
| 269 assigned_vars->Add(vars); | |
| 270 // The preorder, parent, and assigned_vars arrays are all indexed by | |
| 271 // preorder block number, so they should stay in lockstep. | |
| 221 ASSERT(preorder->length() == parent->length()); | 272 ASSERT(preorder->length() == parent->length()); |
| 273 ASSERT(preorder->length() == assigned_vars->length()); | |
| 222 | 274 |
| 223 // 5. Iterate straight-line successors until a branch instruction or | 275 // 5. Iterate straight-line successors until a branch instruction or |
| 224 // another basic block entry instruction, and visit that instruction. | 276 // another basic block entry instruction, and visit that instruction. |
| 225 ASSERT(successor_ != NULL); | 277 ASSERT(StraightLineSuccessor() != NULL); |
| 226 Instruction* next = successor_; | 278 Instruction* next = StraightLineSuccessor(); |
| 227 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) { | 279 if (next->IsBlockEntry()) { |
| 228 set_last_instruction(next); | 280 set_last_instruction(this); |
| 229 next = next->StraightLineSuccessor(); | 281 } else { |
| 282 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) { | |
| 283 next->RecordAssignedVars(assigned_vars->Last()); | |
|
Florian Schneider
2012/05/11 13:19:37
assigned_vars->Last() == vars
The one that's just
Kevin Millikin (Google)
2012/05/15 11:51:44
Well spotted. Done.
| |
| 284 set_last_instruction(next); | |
| 285 next = next->StraightLineSuccessor(); | |
| 286 } | |
| 230 } | 287 } |
| 231 if (next != NULL) { | 288 if (next != NULL) { |
| 232 next->DiscoverBlocks(this, preorder, postorder, parent); | 289 next->DiscoverBlocks(this, preorder, postorder, parent, assigned_vars, |
| 290 variable_count); | |
| 233 } | 291 } |
| 234 | 292 |
| 235 // 6. Assign postorder number and add the block entry to the list. | 293 // 6. Assign postorder number and add the block entry to the list. |
| 236 set_postorder_number(postorder->length()); | |
| 237 postorder->Add(this); | |
| 238 } | |
| 239 | |
| 240 | |
| 241 void TargetEntryInstr::DiscoverBlocks( | |
| 242 BlockEntryInstr* current_block, | |
| 243 GrowableArray<BlockEntryInstr*>* preorder, | |
| 244 GrowableArray<BlockEntryInstr*>* postorder, | |
| 245 GrowableArray<intptr_t>* parent) { | |
| 246 // 1. Record control-flow-graph basic-block predecessors. | |
| 247 ASSERT(predecessor_ == NULL); | |
| 248 predecessor_ = current_block; // Might be NULL (for the graph entry). | |
| 249 | |
| 250 // 2. There is a single predecessor, so we should only reach this block once. | |
| 251 ASSERT(preorder_number() == -1); | |
| 252 | |
| 253 // 3. The last entry in the preorder array is the spanning-tree parent. | |
| 254 // The global graph entry has no parent, indicated by -1. | |
| 255 intptr_t parent_number = preorder->length() - 1; | |
| 256 parent->Add(parent_number); | |
| 257 | |
| 258 // 4. Assign preorder number and add the block entry to the list. | |
| 259 set_preorder_number(parent_number + 1); | |
| 260 preorder->Add(this); | |
| 261 // The preorder and parent arrays are indexed by preorder block number, so | |
| 262 // they should stay in lockstep. | |
| 263 ASSERT(preorder->length() == parent->length()); | |
| 264 | |
| 265 // 5. Iterate straight-line successors until a branch instruction or | |
| 266 // another basic block entry instruction, and visit that instruction. | |
| 267 ASSERT(successor_ != NULL); | |
| 268 Instruction* next = successor_; | |
| 269 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) { | |
| 270 set_last_instruction(next); | |
| 271 next = next->StraightLineSuccessor(); | |
| 272 } | |
| 273 if (next != NULL) { | |
| 274 next->DiscoverBlocks(this, preorder, postorder, parent); | |
| 275 } | |
| 276 | |
| 277 // 6. Assign postorder number and add the block entry to the list. | |
| 278 set_postorder_number(postorder->length()); | 294 set_postorder_number(postorder->length()); |
| 279 postorder->Add(this); | 295 postorder->Add(this); |
| 280 } | 296 } |
| 281 | 297 |
| 282 | 298 |
| 283 void BranchInstr::DiscoverBlocks( | 299 void BranchInstr::DiscoverBlocks( |
| 284 BlockEntryInstr* current_block, | 300 BlockEntryInstr* current_block, |
| 285 GrowableArray<BlockEntryInstr*>* preorder, | 301 GrowableArray<BlockEntryInstr*>* preorder, |
| 286 GrowableArray<BlockEntryInstr*>* postorder, | 302 GrowableArray<BlockEntryInstr*>* postorder, |
| 287 GrowableArray<intptr_t>* parent) { | 303 GrowableArray<intptr_t>* parent, |
| 304 GrowableArray<BitVector*>* assigned_vars, | |
| 305 intptr_t variable_count) { | |
| 288 current_block->set_last_instruction(this); | 306 current_block->set_last_instruction(this); |
| 289 // Visit the false successor before the true successor so they appear in | 307 // Visit the false successor before the true successor so they appear in |
| 290 // true/false order in reverse postorder used as the block ordering in the | 308 // true/false order in reverse postorder used as the block ordering in the |
| 291 // nonoptimizing compiler. | 309 // nonoptimizing compiler. |
| 292 ASSERT(true_successor_ != NULL); | 310 ASSERT(true_successor_ != NULL); |
| 293 ASSERT(false_successor_ != NULL); | 311 ASSERT(false_successor_ != NULL); |
| 294 false_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); | 312 false_successor_->DiscoverBlocks(current_block, preorder, postorder, parent, |
| 295 true_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); | 313 assigned_vars, variable_count); |
| 314 true_successor_->DiscoverBlocks(current_block, preorder, postorder, parent, | |
| 315 assigned_vars, variable_count); | |
| 296 } | 316 } |
| 297 | 317 |
| 298 | 318 |
| 299 } // namespace dart | 319 } // namespace dart |
| OLD | NEW |