| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include "src/compiler/instruction.h" | 5 #include "src/compiler/instruction.h" |
| 6 | 6 |
| 7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
| 8 #include "src/compiler/generic-node-inl.h" | 8 #include "src/compiler/generic-node-inl.h" |
| 9 #include "src/compiler/graph.h" |
| 9 | 10 |
| 10 namespace v8 { | 11 namespace v8 { |
| 11 namespace internal { | 12 namespace internal { |
| 12 namespace compiler { | 13 namespace compiler { |
| 13 | 14 |
| 14 std::ostream& operator<<(std::ostream& os, const InstructionOperand& op) { | 15 std::ostream& operator<<(std::ostream& os, const InstructionOperand& op) { |
| 15 switch (op.kind()) { | 16 switch (op.kind()) { |
| 16 case InstructionOperand::INVALID: | 17 case InstructionOperand::INVALID: |
| 17 return os << "(0)"; | 18 return os << "(0)"; |
| 18 case InstructionOperand::UNALLOCATED: { | 19 case InstructionOperand::UNALLOCATED: { |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 UNREACHABLE(); | 315 UNREACHABLE(); |
| 315 return os; | 316 return os; |
| 316 } | 317 } |
| 317 | 318 |
| 318 | 319 |
| 319 InstructionSequence::InstructionSequence(Linkage* linkage, Graph* graph, | 320 InstructionSequence::InstructionSequence(Linkage* linkage, Graph* graph, |
| 320 Schedule* schedule) | 321 Schedule* schedule) |
| 321 : zone_(schedule->zone()), | 322 : zone_(schedule->zone()), |
| 322 node_count_(graph->NodeCount()), | 323 node_count_(graph->NodeCount()), |
| 323 node_map_(zone()->NewArray<int>(node_count_)), | 324 node_map_(zone()->NewArray<int>(node_count_)), |
| 325 block_data_(schedule->BasicBlockCount(), zone()), |
| 324 linkage_(linkage), | 326 linkage_(linkage), |
| 325 schedule_(schedule), | 327 schedule_(schedule), |
| 326 constants_(ConstantMap::key_compare(), | 328 constants_(ConstantMap::key_compare(), |
| 327 ConstantMap::allocator_type(zone())), | 329 ConstantMap::allocator_type(zone())), |
| 328 immediates_(zone()), | 330 immediates_(zone()), |
| 329 instructions_(zone()), | 331 instructions_(zone()), |
| 330 next_virtual_register_(0), | 332 next_virtual_register_(0), |
| 331 pointer_maps_(zone()), | 333 pointer_maps_(zone()), |
| 332 doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), | 334 doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
| 333 references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), | 335 references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
| 334 deoptimization_entries_(zone()) { | 336 deoptimization_entries_(zone()) { |
| 335 for (int i = 0; i < node_count_; ++i) { | 337 for (int i = 0; i < node_count_; ++i) { |
| 336 node_map_[i] = -1; | 338 node_map_[i] = -1; |
| 337 } | 339 } |
| 338 } | 340 } |
| 339 | 341 |
| 340 | 342 |
| 341 int InstructionSequence::GetVirtualRegister(const Node* node) { | 343 int InstructionSequence::GetVirtualRegister(const Node* node) { |
| 342 if (node_map_[node->id()] == -1) { | 344 if (node_map_[node->id()] == -1) { |
| 343 node_map_[node->id()] = NextVirtualRegister(); | 345 node_map_[node->id()] = NextVirtualRegister(); |
| 344 } | 346 } |
| 345 return node_map_[node->id()]; | 347 return node_map_[node->id()]; |
| 346 } | 348 } |
| 347 | 349 |
| 348 | 350 |
| 349 Label* InstructionSequence::GetLabel(BasicBlock* block) { | 351 Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) { |
| 350 return GetBlockStart(block)->label(); | 352 return GetBlockStart(rpo)->label(); |
| 351 } | 353 } |
| 352 | 354 |
| 353 | 355 |
| 354 BlockStartInstruction* InstructionSequence::GetBlockStart(BasicBlock* block) { | 356 BlockStartInstruction* InstructionSequence::GetBlockStart( |
| 355 return BlockStartInstruction::cast(InstructionAt(block->code_start())); | 357 BasicBlock::RpoNumber rpo) { |
| 358 BlockStartInstruction* block_start = |
| 359 BlockStartInstruction::cast(InstructionAt(code_start(rpo))); |
| 360 DCHECK_EQ(rpo.ToInt(), block_start->rpo_number().ToInt()); |
| 361 return block_start; |
| 356 } | 362 } |
| 357 | 363 |
| 358 | 364 |
| 359 void InstructionSequence::StartBlock(BasicBlock* block) { | 365 void InstructionSequence::StartBlock(BasicBlock* block) { |
| 360 block->set_code_start(static_cast<int>(instructions_.size())); | 366 set_code_start(block, static_cast<int>(instructions_.size())); |
| 361 BlockStartInstruction* block_start = | 367 BlockStartInstruction* block_start = |
| 362 BlockStartInstruction::New(zone(), block); | 368 BlockStartInstruction::New(zone(), block); |
| 363 AddInstruction(block_start, block); | 369 AddInstruction(block_start); |
| 364 } | 370 } |
| 365 | 371 |
| 366 | 372 |
| 367 void InstructionSequence::EndBlock(BasicBlock* block) { | 373 void InstructionSequence::EndBlock(BasicBlock* block) { |
| 368 int end = static_cast<int>(instructions_.size()); | 374 int end = static_cast<int>(instructions_.size()); |
| 369 DCHECK(block->code_start() >= 0 && block->code_start() < end); | 375 DCHECK(code_start(block) >= 0 && code_start(block) < end); |
| 370 block->set_code_end(end); | 376 set_code_end(block, end); |
| 371 } | 377 } |
| 372 | 378 |
| 373 | 379 |
| 374 int InstructionSequence::AddInstruction(Instruction* instr, BasicBlock* block) { | 380 int InstructionSequence::AddInstruction(Instruction* instr) { |
| 375 // TODO(titzer): the order of these gaps is a holdover from Lithium. | 381 // TODO(titzer): the order of these gaps is a holdover from Lithium. |
| 376 GapInstruction* gap = GapInstruction::New(zone()); | 382 GapInstruction* gap = GapInstruction::New(zone()); |
| 377 if (instr->IsControl()) instructions_.push_back(gap); | 383 if (instr->IsControl()) instructions_.push_back(gap); |
| 378 int index = static_cast<int>(instructions_.size()); | 384 int index = static_cast<int>(instructions_.size()); |
| 379 instructions_.push_back(instr); | 385 instructions_.push_back(instr); |
| 380 if (!instr->IsControl()) instructions_.push_back(gap); | 386 if (!instr->IsControl()) instructions_.push_back(gap); |
| 381 if (instr->NeedsPointerMap()) { | 387 if (instr->NeedsPointerMap()) { |
| 382 DCHECK(instr->pointer_map() == NULL); | 388 DCHECK(instr->pointer_map() == NULL); |
| 383 PointerMap* pointer_map = new (zone()) PointerMap(zone()); | 389 PointerMap* pointer_map = new (zone()) PointerMap(zone()); |
| 384 pointer_map->set_instruction_position(index); | 390 pointer_map->set_instruction_position(index); |
| 385 instr->set_pointer_map(pointer_map); | 391 instr->set_pointer_map(pointer_map); |
| 386 pointer_maps_.push_back(pointer_map); | 392 pointer_maps_.push_back(pointer_map); |
| 387 } | 393 } |
| 388 return index; | 394 return index; |
| 389 } | 395 } |
| 390 | 396 |
| 391 | 397 |
| 392 BasicBlock* InstructionSequence::GetBasicBlock(int instruction_index) { | 398 BasicBlock* InstructionSequence::GetBasicBlock(int instruction_index) { |
| 393 // TODO(turbofan): Optimize this. | 399 // TODO(turbofan): Optimize this. |
| 394 for (;;) { | 400 for (;;) { |
| 395 DCHECK_LE(0, instruction_index); | 401 DCHECK_LE(0, instruction_index); |
| 396 Instruction* instruction = InstructionAt(instruction_index--); | 402 Instruction* instruction = InstructionAt(instruction_index--); |
| 397 if (instruction->IsBlockStart()) { | 403 if (instruction->IsBlockStart()) { |
| 398 return BlockStartInstruction::cast(instruction)->block(); | 404 return schedule()->rpo_order()->at( |
| 405 BlockStartInstruction::cast(instruction)->rpo_number().ToSize()); |
| 399 } | 406 } |
| 400 } | 407 } |
| 401 } | 408 } |
| 402 | 409 |
| 403 | 410 |
| 404 bool InstructionSequence::IsReference(int virtual_register) const { | 411 bool InstructionSequence::IsReference(int virtual_register) const { |
| 405 return references_.find(virtual_register) != references_.end(); | 412 return references_.find(virtual_register) != references_.end(); |
| 406 } | 413 } |
| 407 | 414 |
| 408 | 415 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 } | 537 } |
| 531 for (int i = 0; i < code.BasicBlockCount(); i++) { | 538 for (int i = 0; i < code.BasicBlockCount(); i++) { |
| 532 BasicBlock* block = code.BlockAt(i); | 539 BasicBlock* block = code.BlockAt(i); |
| 533 | 540 |
| 534 os << "RPO#" << block->rpo_number() << ": B" << block->id(); | 541 os << "RPO#" << block->rpo_number() << ": B" << block->id(); |
| 535 CHECK(block->rpo_number() == i); | 542 CHECK(block->rpo_number() == i); |
| 536 if (block->IsLoopHeader()) { | 543 if (block->IsLoopHeader()) { |
| 537 os << " loop blocks: [" << block->rpo_number() << ", " | 544 os << " loop blocks: [" << block->rpo_number() << ", " |
| 538 << block->loop_end() << ")"; | 545 << block->loop_end() << ")"; |
| 539 } | 546 } |
| 540 os << " instructions: [" << block->code_start() << ", " | 547 os << " instructions: [" << code.code_start(block) << ", " |
| 541 << block->code_end() << ")\n predecessors:"; | 548 << code.code_end(block) << ")\n predecessors:"; |
| 542 | 549 |
| 543 for (BasicBlock::Predecessors::iterator iter = block->predecessors_begin(); | 550 for (BasicBlock::Predecessors::iterator iter = block->predecessors_begin(); |
| 544 iter != block->predecessors_end(); ++iter) { | 551 iter != block->predecessors_end(); ++iter) { |
| 545 os << " B" << (*iter)->id(); | 552 os << " B" << (*iter)->id(); |
| 546 } | 553 } |
| 547 os << "\n"; | 554 os << "\n"; |
| 548 | 555 |
| 549 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); | 556 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); |
| 550 ++j) { | 557 ++j) { |
| 551 Node* phi = *j; | 558 Node* phi = *j; |
| 552 if (phi->opcode() != IrOpcode::kPhi) continue; | 559 if (phi->opcode() != IrOpcode::kPhi) continue; |
| 553 os << " phi: v" << phi->id() << " ="; | 560 os << " phi: v" << phi->id() << " ="; |
| 554 Node::Inputs inputs = phi->inputs(); | 561 Node::Inputs inputs = phi->inputs(); |
| 555 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | 562 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); |
| 556 ++iter) { | 563 ++iter) { |
| 557 os << " v" << (*iter)->id(); | 564 os << " v" << (*iter)->id(); |
| 558 } | 565 } |
| 559 os << "\n"; | 566 os << "\n"; |
| 560 } | 567 } |
| 561 | 568 |
| 562 ScopedVector<char> buf(32); | 569 ScopedVector<char> buf(32); |
| 563 for (int j = block->first_instruction_index(); | 570 for (int j = code.first_instruction_index(block); |
| 564 j <= block->last_instruction_index(); j++) { | 571 j <= code.last_instruction_index(block); j++) { |
| 565 // TODO(svenpanne) Add some basic formatting to our streams. | 572 // TODO(svenpanne) Add some basic formatting to our streams. |
| 566 SNPrintF(buf, "%5d", j); | 573 SNPrintF(buf, "%5d", j); |
| 567 os << " " << buf.start() << ": " << *code.InstructionAt(j); | 574 os << " " << buf.start() << ": " << *code.InstructionAt(j); |
| 568 } | 575 } |
| 569 | 576 |
| 570 os << " " << block->control(); | 577 os << " " << block->control(); |
| 571 | 578 |
| 572 if (block->control_input() != NULL) { | 579 if (block->control_input() != NULL) { |
| 573 os << " v" << block->control_input()->id(); | 580 os << " v" << block->control_input()->id(); |
| 574 } | 581 } |
| 575 | 582 |
| 576 for (BasicBlock::Successors::iterator iter = block->successors_begin(); | 583 for (BasicBlock::Successors::iterator iter = block->successors_begin(); |
| 577 iter != block->successors_end(); ++iter) { | 584 iter != block->successors_end(); ++iter) { |
| 578 os << " B" << (*iter)->id(); | 585 os << " B" << (*iter)->id(); |
| 579 } | 586 } |
| 580 os << "\n"; | 587 os << "\n"; |
| 581 } | 588 } |
| 582 return os; | 589 return os; |
| 583 } | 590 } |
| 584 | 591 |
| 585 } // namespace compiler | 592 } // namespace compiler |
| 586 } // namespace internal | 593 } // namespace internal |
| 587 } // namespace v8 | 594 } // namespace v8 |
| OLD | NEW |