| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_COMPILER_SCHEDULE_H_ | 5 #ifndef V8_COMPILER_SCHEDULE_H_ |
| 6 #define V8_COMPILER_SCHEDULE_H_ | 6 #define V8_COMPILER_SCHEDULE_H_ |
| 7 | 7 |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "src/v8.h" | 10 #include "src/v8.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 code_start_(-1), | 61 code_start_(-1), |
| 62 code_end_(-1), | 62 code_end_(-1), |
| 63 deferred_(false), | 63 deferred_(false), |
| 64 control_(kNone), | 64 control_(kNone), |
| 65 control_input_(NULL), | 65 control_input_(NULL), |
| 66 nodes_(NodeVector::allocator_type(zone)) {} | 66 nodes_(NodeVector::allocator_type(zone)) {} |
| 67 | 67 |
| 68 inline bool IsLoopHeader() const { return loop_end_ >= 0; } | 68 inline bool IsLoopHeader() const { return loop_end_ >= 0; } |
| 69 inline bool LoopContains(BasicBlockData* block) const { | 69 inline bool LoopContains(BasicBlockData* block) const { |
| 70 // RPO numbers must be initialized. | 70 // RPO numbers must be initialized. |
| 71 ASSERT(rpo_number_ >= 0); | 71 DCHECK(rpo_number_ >= 0); |
| 72 ASSERT(block->rpo_number_ >= 0); | 72 DCHECK(block->rpo_number_ >= 0); |
| 73 if (loop_end_ < 0) return false; // This is not a loop. | 73 if (loop_end_ < 0) return false; // This is not a loop. |
| 74 return block->rpo_number_ >= rpo_number_ && block->rpo_number_ < loop_end_; | 74 return block->rpo_number_ >= rpo_number_ && block->rpo_number_ < loop_end_; |
| 75 } | 75 } |
| 76 int first_instruction_index() { | 76 int first_instruction_index() { |
| 77 ASSERT(code_start_ >= 0); | 77 DCHECK(code_start_ >= 0); |
| 78 ASSERT(code_end_ > 0); | 78 DCHECK(code_end_ > 0); |
| 79 ASSERT(code_end_ >= code_start_); | 79 DCHECK(code_end_ >= code_start_); |
| 80 return code_start_; | 80 return code_start_; |
| 81 } | 81 } |
| 82 int last_instruction_index() { | 82 int last_instruction_index() { |
| 83 ASSERT(code_start_ >= 0); | 83 DCHECK(code_start_ >= 0); |
| 84 ASSERT(code_end_ > 0); | 84 DCHECK(code_end_ > 0); |
| 85 ASSERT(code_end_ >= code_start_); | 85 DCHECK(code_end_ >= code_start_); |
| 86 return code_end_ - 1; | 86 return code_end_ - 1; |
| 87 } | 87 } |
| 88 }; | 88 }; |
| 89 | 89 |
| 90 OStream& operator<<(OStream& os, const BasicBlockData::Control& c); | 90 OStream& operator<<(OStream& os, const BasicBlockData::Control& c); |
| 91 | 91 |
| 92 // A basic block contains an ordered list of nodes and ends with a control | 92 // A basic block contains an ordered list of nodes and ends with a control |
| 93 // node. Note that if a basic block has phis, then all phis must appear as the | 93 // node. Note that if a basic block has phis, then all phis must appear as the |
| 94 // first nodes in the block. | 94 // first nodes in the block. |
| 95 class BasicBlock V8_FINAL : public GenericNode<BasicBlockData, BasicBlock> { | 95 class BasicBlock V8_FINAL : public GenericNode<BasicBlockData, BasicBlock> { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 return block; | 215 return block; |
| 216 } | 216 } |
| 217 | 217 |
| 218 // BasicBlock building: records that a node will later be added to a block but | 218 // BasicBlock building: records that a node will later be added to a block but |
| 219 // doesn't actually add the node to the block. | 219 // doesn't actually add the node to the block. |
| 220 inline void PlanNode(BasicBlock* block, Node* node) { | 220 inline void PlanNode(BasicBlock* block, Node* node) { |
| 221 if (FLAG_trace_turbo_scheduler) { | 221 if (FLAG_trace_turbo_scheduler) { |
| 222 PrintF("Planning node %d for future add to block %d\n", node->id(), | 222 PrintF("Planning node %d for future add to block %d\n", node->id(), |
| 223 block->id()); | 223 block->id()); |
| 224 } | 224 } |
| 225 ASSERT(this->block(node) == NULL); | 225 DCHECK(this->block(node) == NULL); |
| 226 SetBlockForNode(block, node); | 226 SetBlockForNode(block, node); |
| 227 } | 227 } |
| 228 | 228 |
| 229 // BasicBlock building: add a node to the end of the block. | 229 // BasicBlock building: add a node to the end of the block. |
| 230 inline void AddNode(BasicBlock* block, Node* node) { | 230 inline void AddNode(BasicBlock* block, Node* node) { |
| 231 if (FLAG_trace_turbo_scheduler) { | 231 if (FLAG_trace_turbo_scheduler) { |
| 232 PrintF("Adding node %d to block %d\n", node->id(), block->id()); | 232 PrintF("Adding node %d to block %d\n", node->id(), block->id()); |
| 233 } | 233 } |
| 234 ASSERT(this->block(node) == NULL || this->block(node) == block); | 234 DCHECK(this->block(node) == NULL || this->block(node) == block); |
| 235 block->nodes_.push_back(node); | 235 block->nodes_.push_back(node); |
| 236 SetBlockForNode(block, node); | 236 SetBlockForNode(block, node); |
| 237 } | 237 } |
| 238 | 238 |
| 239 // BasicBlock building: add a goto to the end of {block}. | 239 // BasicBlock building: add a goto to the end of {block}. |
| 240 void AddGoto(BasicBlock* block, BasicBlock* succ) { | 240 void AddGoto(BasicBlock* block, BasicBlock* succ) { |
| 241 ASSERT(block->control_ == BasicBlock::kNone); | 241 DCHECK(block->control_ == BasicBlock::kNone); |
| 242 block->control_ = BasicBlock::kGoto; | 242 block->control_ = BasicBlock::kGoto; |
| 243 AddSuccessor(block, succ); | 243 AddSuccessor(block, succ); |
| 244 } | 244 } |
| 245 | 245 |
| 246 // BasicBlock building: add a (branching) call at the end of {block}. | 246 // BasicBlock building: add a (branching) call at the end of {block}. |
| 247 void AddCall(BasicBlock* block, Node* call, BasicBlock* cont_block, | 247 void AddCall(BasicBlock* block, Node* call, BasicBlock* cont_block, |
| 248 BasicBlock* deopt_block) { | 248 BasicBlock* deopt_block) { |
| 249 ASSERT(block->control_ == BasicBlock::kNone); | 249 DCHECK(block->control_ == BasicBlock::kNone); |
| 250 ASSERT(call->opcode() == IrOpcode::kCall); | 250 DCHECK(call->opcode() == IrOpcode::kCall); |
| 251 block->control_ = BasicBlock::kCall; | 251 block->control_ = BasicBlock::kCall; |
| 252 // Insert the deopt block first so that the RPO order builder picks | 252 // Insert the deopt block first so that the RPO order builder picks |
| 253 // it first (and thus it ends up late in the RPO order). | 253 // it first (and thus it ends up late in the RPO order). |
| 254 AddSuccessor(block, deopt_block); | 254 AddSuccessor(block, deopt_block); |
| 255 AddSuccessor(block, cont_block); | 255 AddSuccessor(block, cont_block); |
| 256 SetControlInput(block, call); | 256 SetControlInput(block, call); |
| 257 } | 257 } |
| 258 | 258 |
| 259 // BasicBlock building: add a branch at the end of {block}. | 259 // BasicBlock building: add a branch at the end of {block}. |
| 260 void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock, | 260 void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock, |
| 261 BasicBlock* fblock) { | 261 BasicBlock* fblock) { |
| 262 ASSERT(block->control_ == BasicBlock::kNone); | 262 DCHECK(block->control_ == BasicBlock::kNone); |
| 263 ASSERT(branch->opcode() == IrOpcode::kBranch); | 263 DCHECK(branch->opcode() == IrOpcode::kBranch); |
| 264 block->control_ = BasicBlock::kBranch; | 264 block->control_ = BasicBlock::kBranch; |
| 265 AddSuccessor(block, tblock); | 265 AddSuccessor(block, tblock); |
| 266 AddSuccessor(block, fblock); | 266 AddSuccessor(block, fblock); |
| 267 SetControlInput(block, branch); | 267 SetControlInput(block, branch); |
| 268 } | 268 } |
| 269 | 269 |
| 270 // BasicBlock building: add a return at the end of {block}. | 270 // BasicBlock building: add a return at the end of {block}. |
| 271 void AddReturn(BasicBlock* block, Node* input) { | 271 void AddReturn(BasicBlock* block, Node* input) { |
| 272 // TODO(titzer): require a Return node here. | 272 // TODO(titzer): require a Return node here. |
| 273 ASSERT(block->control_ == BasicBlock::kNone); | 273 DCHECK(block->control_ == BasicBlock::kNone); |
| 274 block->control_ = BasicBlock::kReturn; | 274 block->control_ = BasicBlock::kReturn; |
| 275 SetControlInput(block, input); | 275 SetControlInput(block, input); |
| 276 if (block != exit()) AddSuccessor(block, exit()); | 276 if (block != exit()) AddSuccessor(block, exit()); |
| 277 } | 277 } |
| 278 | 278 |
| 279 // BasicBlock building: add a throw at the end of {block}. | 279 // BasicBlock building: add a throw at the end of {block}. |
| 280 void AddThrow(BasicBlock* block, Node* input) { | 280 void AddThrow(BasicBlock* block, Node* input) { |
| 281 ASSERT(block->control_ == BasicBlock::kNone); | 281 DCHECK(block->control_ == BasicBlock::kNone); |
| 282 block->control_ = BasicBlock::kThrow; | 282 block->control_ = BasicBlock::kThrow; |
| 283 SetControlInput(block, input); | 283 SetControlInput(block, input); |
| 284 if (block != exit()) AddSuccessor(block, exit()); | 284 if (block != exit()) AddSuccessor(block, exit()); |
| 285 } | 285 } |
| 286 | 286 |
| 287 // BasicBlock building: add a deopt at the end of {block}. | 287 // BasicBlock building: add a deopt at the end of {block}. |
| 288 void AddDeoptimize(BasicBlock* block, Node* state) { | 288 void AddDeoptimize(BasicBlock* block, Node* state) { |
| 289 ASSERT(block->control_ == BasicBlock::kNone); | 289 DCHECK(block->control_ == BasicBlock::kNone); |
| 290 block->control_ = BasicBlock::kDeoptimize; | 290 block->control_ = BasicBlock::kDeoptimize; |
| 291 SetControlInput(block, state); | 291 SetControlInput(block, state); |
| 292 block->deferred_ = true; // By default, consider deopts the slow path. | 292 block->deferred_ = true; // By default, consider deopts the slow path. |
| 293 if (block != exit()) AddSuccessor(block, exit()); | 293 if (block != exit()) AddSuccessor(block, exit()); |
| 294 } | 294 } |
| 295 | 295 |
| 296 friend class Scheduler; | 296 friend class Scheduler; |
| 297 friend class CodeGenerator; | 297 friend class CodeGenerator; |
| 298 | 298 |
| 299 void AddSuccessor(BasicBlock* block, BasicBlock* succ) { | 299 void AddSuccessor(BasicBlock* block, BasicBlock* succ) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 326 // dominator, indexed by block | 326 // dominator, indexed by block |
| 327 // id. | 327 // id. |
| 328 }; | 328 }; |
| 329 | 329 |
| 330 OStream& operator<<(OStream& os, const Schedule& s); | 330 OStream& operator<<(OStream& os, const Schedule& s); |
| 331 } | 331 } |
| 332 } | 332 } |
| 333 } // namespace v8::internal::compiler | 333 } // namespace v8::internal::compiler |
| 334 | 334 |
| 335 #endif // V8_COMPILER_SCHEDULE_H_ | 335 #endif // V8_COMPILER_SCHEDULE_H_ |
| OLD | NEW |