| 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 #include "src/compiler/graph.h" |
| 10 | 10 |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 return BasicBlock::RpoNumber::FromInt(block->loop_end()); | 328 return BasicBlock::RpoNumber::FromInt(block->loop_end()); |
| 329 } | 329 } |
| 330 | 330 |
| 331 | 331 |
| 332 InstructionBlock::InstructionBlock(Zone* zone, const BasicBlock* block) | 332 InstructionBlock::InstructionBlock(Zone* zone, const BasicBlock* block) |
| 333 : successors_(static_cast<int>(block->SuccessorCount()), | 333 : successors_(static_cast<int>(block->SuccessorCount()), |
| 334 BasicBlock::RpoNumber::Invalid(), zone), | 334 BasicBlock::RpoNumber::Invalid(), zone), |
| 335 predecessors_(static_cast<int>(block->PredecessorCount()), | 335 predecessors_(static_cast<int>(block->PredecessorCount()), |
| 336 BasicBlock::RpoNumber::Invalid(), zone), | 336 BasicBlock::RpoNumber::Invalid(), zone), |
| 337 phis_(zone), | 337 phis_(zone), |
| 338 id_(block->id()), |
| 338 rpo_number_(block->GetRpoNumber()), | 339 rpo_number_(block->GetRpoNumber()), |
| 339 loop_header_(GetRpo(block->loop_header())), | 340 loop_header_(GetRpo(block->loop_header())), |
| 340 loop_end_(GetLoopEndRpo(block)), | 341 loop_end_(GetLoopEndRpo(block)), |
| 341 code_start_(-1), | 342 code_start_(-1), |
| 342 code_end_(-1) { | 343 code_end_(-1) { |
| 343 // Map successors and precessors | 344 // Map successors and precessors |
| 344 size_t index = 0; | 345 size_t index = 0; |
| 345 for (BasicBlock::Successors::const_iterator it = block->successors_begin(); | 346 for (BasicBlock::Successors::const_iterator it = block->successors_begin(); |
| 346 it != block->successors_end(); ++it, ++index) { | 347 it != block->successors_end(); ++it, ++index) { |
| 347 successors_[index] = (*it)->GetRpoNumber(); | 348 successors_[index] = (*it)->GetRpoNumber(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 372 size_t rpo_number = 0; | 373 size_t rpo_number = 0; |
| 373 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); | 374 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); |
| 374 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { | 375 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { |
| 375 DCHECK_EQ(NULL, (*blocks)[rpo_number]); | 376 DCHECK_EQ(NULL, (*blocks)[rpo_number]); |
| 376 DCHECK((*it)->GetRpoNumber().ToSize() == rpo_number); | 377 DCHECK((*it)->GetRpoNumber().ToSize() == rpo_number); |
| 377 (*blocks)[rpo_number] = new (zone) InstructionBlock(zone, *it); | 378 (*blocks)[rpo_number] = new (zone) InstructionBlock(zone, *it); |
| 378 } | 379 } |
| 379 } | 380 } |
| 380 | 381 |
| 381 | 382 |
| 382 InstructionSequence::InstructionSequence(Linkage* linkage, Graph* graph, | 383 InstructionSequence::InstructionSequence(Linkage* linkage, const Graph* graph, |
| 383 Schedule* schedule) | 384 const Schedule* schedule) |
| 384 : zone_(schedule->zone()), // TODO(dcarney): new zone. | 385 : zone_(graph->zone()->isolate()), |
| 385 node_count_(graph->NodeCount()), | 386 node_count_(graph->NodeCount()), |
| 386 node_map_(zone()->NewArray<int>(node_count_)), | 387 node_map_(zone()->NewArray<int>(node_count_)), |
| 387 instruction_blocks_(static_cast<int>(schedule->rpo_order()->size()), NULL, | 388 instruction_blocks_(static_cast<int>(schedule->rpo_order()->size()), NULL, |
| 388 zone()), | 389 zone()), |
| 389 linkage_(linkage), | 390 linkage_(linkage), |
| 390 schedule_(schedule), | |
| 391 constants_(ConstantMap::key_compare(), | 391 constants_(ConstantMap::key_compare(), |
| 392 ConstantMap::allocator_type(zone())), | 392 ConstantMap::allocator_type(zone())), |
| 393 immediates_(zone()), | 393 immediates_(zone()), |
| 394 instructions_(zone()), | 394 instructions_(zone()), |
| 395 next_virtual_register_(0), | 395 next_virtual_register_(0), |
| 396 pointer_maps_(zone()), | 396 pointer_maps_(zone()), |
| 397 doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), | 397 doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
| 398 references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), | 398 references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
| 399 deoptimization_entries_(zone()) { | 399 deoptimization_entries_(zone()) { |
| 400 for (int i = 0; i < node_count_; ++i) { | 400 for (int i = 0; i < node_count_; ++i) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 412 } | 412 } |
| 413 | 413 |
| 414 | 414 |
| 415 Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) { | 415 Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) { |
| 416 return GetBlockStart(rpo)->label(); | 416 return GetBlockStart(rpo)->label(); |
| 417 } | 417 } |
| 418 | 418 |
| 419 | 419 |
| 420 BlockStartInstruction* InstructionSequence::GetBlockStart( | 420 BlockStartInstruction* InstructionSequence::GetBlockStart( |
| 421 BasicBlock::RpoNumber rpo) { | 421 BasicBlock::RpoNumber rpo) { |
| 422 InstructionBlock* block = InstructionBlockAt(rpo); |
| 422 BlockStartInstruction* block_start = | 423 BlockStartInstruction* block_start = |
| 423 BlockStartInstruction::cast(InstructionAt(code_start(rpo))); | 424 BlockStartInstruction::cast(InstructionAt(block->code_start())); |
| 424 DCHECK_EQ(rpo.ToInt(), block_start->rpo_number().ToInt()); | 425 DCHECK_EQ(rpo.ToInt(), block_start->rpo_number().ToInt()); |
| 425 return block_start; | 426 return block_start; |
| 426 } | 427 } |
| 427 | 428 |
| 428 | 429 |
| 429 void InstructionSequence::StartBlock(BasicBlock* block) { | 430 void InstructionSequence::StartBlock(BasicBlock* basic_block) { |
| 430 set_code_start(block, static_cast<int>(instructions_.size())); | 431 InstructionBlock* block = InstructionBlockAt(basic_block->GetRpoNumber()); |
| 432 block->set_code_start(static_cast<int>(instructions_.size())); |
| 431 BlockStartInstruction* block_start = | 433 BlockStartInstruction* block_start = |
| 432 BlockStartInstruction::New(zone(), block); | 434 BlockStartInstruction::New(zone(), basic_block); |
| 433 AddInstruction(block_start); | 435 AddInstruction(block_start); |
| 434 } | 436 } |
| 435 | 437 |
| 436 | 438 |
| 437 void InstructionSequence::EndBlock(BasicBlock* block) { | 439 void InstructionSequence::EndBlock(BasicBlock* basic_block) { |
| 438 int end = static_cast<int>(instructions_.size()); | 440 int end = static_cast<int>(instructions_.size()); |
| 439 DCHECK(code_start(block) >= 0 && code_start(block) < end); | 441 InstructionBlock* block = InstructionBlockAt(basic_block->GetRpoNumber()); |
| 440 set_code_end(block, end); | 442 DCHECK(block->code_start() >= 0 && block->code_start() < end); |
| 443 block->set_code_end(end); |
| 441 } | 444 } |
| 442 | 445 |
| 443 | 446 |
| 444 int InstructionSequence::AddInstruction(Instruction* instr) { | 447 int InstructionSequence::AddInstruction(Instruction* instr) { |
| 445 // TODO(titzer): the order of these gaps is a holdover from Lithium. | 448 // TODO(titzer): the order of these gaps is a holdover from Lithium. |
| 446 GapInstruction* gap = GapInstruction::New(zone()); | 449 GapInstruction* gap = GapInstruction::New(zone()); |
| 447 if (instr->IsControl()) instructions_.push_back(gap); | 450 if (instr->IsControl()) instructions_.push_back(gap); |
| 448 int index = static_cast<int>(instructions_.size()); | 451 int index = static_cast<int>(instructions_.size()); |
| 449 instructions_.push_back(instr); | 452 instructions_.push_back(instr); |
| 450 if (!instr->IsControl()) instructions_.push_back(gap); | 453 if (!instr->IsControl()) instructions_.push_back(gap); |
| 451 if (instr->NeedsPointerMap()) { | 454 if (instr->NeedsPointerMap()) { |
| 452 DCHECK(instr->pointer_map() == NULL); | 455 DCHECK(instr->pointer_map() == NULL); |
| 453 PointerMap* pointer_map = new (zone()) PointerMap(zone()); | 456 PointerMap* pointer_map = new (zone()) PointerMap(zone()); |
| 454 pointer_map->set_instruction_position(index); | 457 pointer_map->set_instruction_position(index); |
| 455 instr->set_pointer_map(pointer_map); | 458 instr->set_pointer_map(pointer_map); |
| 456 pointer_maps_.push_back(pointer_map); | 459 pointer_maps_.push_back(pointer_map); |
| 457 } | 460 } |
| 458 return index; | 461 return index; |
| 459 } | 462 } |
| 460 | 463 |
| 461 | 464 |
| 462 BasicBlock* InstructionSequence::GetBasicBlock(int instruction_index) { | |
| 463 // TODO(turbofan): Optimize this. | |
| 464 for (;;) { | |
| 465 DCHECK_LE(0, instruction_index); | |
| 466 Instruction* instruction = InstructionAt(instruction_index--); | |
| 467 if (instruction->IsBlockStart()) { | |
| 468 return schedule()->rpo_order()->at( | |
| 469 BlockStartInstruction::cast(instruction)->rpo_number().ToSize()); | |
| 470 } | |
| 471 } | |
| 472 } | |
| 473 | |
| 474 | |
| 475 const InstructionBlock* InstructionSequence::GetInstructionBlock( | 465 const InstructionBlock* InstructionSequence::GetInstructionBlock( |
| 476 int instruction_index) const { | 466 int instruction_index) const { |
| 477 // TODO(turbofan): Optimize this. | 467 // TODO(turbofan): Optimize this. |
| 478 for (;;) { | 468 for (;;) { |
| 479 DCHECK_LE(0, instruction_index); | 469 DCHECK_LE(0, instruction_index); |
| 480 Instruction* instruction = InstructionAt(instruction_index--); | 470 Instruction* instruction = InstructionAt(instruction_index--); |
| 481 if (instruction->IsBlockStart()) { | 471 if (instruction->IsBlockStart()) { |
| 482 return instruction_blocks_ | 472 return instruction_blocks_ |
| 483 [BlockStartInstruction::cast(instruction)->rpo_number().ToSize()]; | 473 [BlockStartInstruction::cast(instruction)->rpo_number().ToSize()]; |
| 484 } | 474 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 for (size_t i = 0; i < code.immediates_.size(); ++i) { | 597 for (size_t i = 0; i < code.immediates_.size(); ++i) { |
| 608 Constant constant = code.immediates_[i]; | 598 Constant constant = code.immediates_[i]; |
| 609 os << "IMM#" << i << ": " << constant << "\n"; | 599 os << "IMM#" << i << ": " << constant << "\n"; |
| 610 } | 600 } |
| 611 int i = 0; | 601 int i = 0; |
| 612 for (ConstantMap::const_iterator it = code.constants_.begin(); | 602 for (ConstantMap::const_iterator it = code.constants_.begin(); |
| 613 it != code.constants_.end(); ++i, ++it) { | 603 it != code.constants_.end(); ++i, ++it) { |
| 614 os << "CST#" << i << ": v" << it->first << " = " << it->second << "\n"; | 604 os << "CST#" << i << ": v" << it->first << " = " << it->second << "\n"; |
| 615 } | 605 } |
| 616 for (int i = 0; i < code.BasicBlockCount(); i++) { | 606 for (int i = 0; i < code.BasicBlockCount(); i++) { |
| 617 BasicBlock* block = code.BlockAt(i); | 607 BasicBlock::RpoNumber rpo = BasicBlock::RpoNumber::FromInt(i); |
| 608 const InstructionBlock* block = code.InstructionBlockAt(rpo); |
| 609 CHECK(block->rpo_number() == rpo); |
| 618 | 610 |
| 619 os << "RPO#" << block->rpo_number() << ": B" << block->id(); | 611 os << "RPO#" << block->rpo_number() << ": B" << block->id(); |
| 620 CHECK(block->rpo_number() == i); | |
| 621 if (block->IsLoopHeader()) { | 612 if (block->IsLoopHeader()) { |
| 622 os << " loop blocks: [" << block->rpo_number() << ", " | 613 os << " loop blocks: [" << block->rpo_number() << ", " |
| 623 << block->loop_end() << ")"; | 614 << block->loop_end() << ")"; |
| 624 } | 615 } |
| 625 os << " instructions: [" << code.code_start(block) << ", " | 616 os << " instructions: [" << block->code_start() << ", " |
| 626 << code.code_end(block) << ")\n predecessors:"; | 617 << block->code_end() << ")\n predecessors:"; |
| 627 | 618 |
| 628 for (BasicBlock::Predecessors::iterator iter = block->predecessors_begin(); | 619 for (auto pred : block->predecessors()) { |
| 629 iter != block->predecessors_end(); ++iter) { | 620 const InstructionBlock* pred_block = code.InstructionBlockAt(pred); |
| 630 os << " B" << (*iter)->id(); | 621 os << " B" << pred_block->id(); |
| 631 } | 622 } |
| 632 os << "\n"; | 623 os << "\n"; |
| 633 | 624 |
| 634 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); | 625 for (auto phi : block->phis()) { |
| 635 ++j) { | 626 os << " phi: v" << phi->virtual_register() << " ="; |
| 636 Node* phi = *j; | 627 for (auto op_vreg : phi->operands()) { |
| 637 if (phi->opcode() != IrOpcode::kPhi) continue; | 628 os << " v" << op_vreg; |
| 638 os << " phi: v" << phi->id() << " ="; | |
| 639 Node::Inputs inputs = phi->inputs(); | |
| 640 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | |
| 641 ++iter) { | |
| 642 os << " v" << (*iter)->id(); | |
| 643 } | 629 } |
| 644 os << "\n"; | 630 os << "\n"; |
| 645 } | 631 } |
| 646 | 632 |
| 647 ScopedVector<char> buf(32); | 633 ScopedVector<char> buf(32); |
| 648 for (int j = code.first_instruction_index(block); | 634 for (int j = block->first_instruction_index(); |
| 649 j <= code.last_instruction_index(block); j++) { | 635 j <= block->last_instruction_index(); j++) { |
| 650 // TODO(svenpanne) Add some basic formatting to our streams. | 636 // TODO(svenpanne) Add some basic formatting to our streams. |
| 651 SNPrintF(buf, "%5d", j); | 637 SNPrintF(buf, "%5d", j); |
| 652 os << " " << buf.start() << ": " << *code.InstructionAt(j) << "\n"; | 638 os << " " << buf.start() << ": " << *code.InstructionAt(j) << "\n"; |
| 653 } | 639 } |
| 654 | 640 |
| 655 os << " " << block->control(); | 641 // TODO(dcarney): add this back somehow? |
| 642 // os << " " << block->control(); |
| 656 | 643 |
| 657 if (block->control_input() != NULL) { | 644 // if (block->control_input() != NULL) { |
| 658 os << " v" << block->control_input()->id(); | 645 // os << " v" << block->control_input()->id(); |
| 659 } | 646 // } |
| 660 | 647 |
| 661 for (BasicBlock::Successors::iterator iter = block->successors_begin(); | 648 for (auto succ : block->successors()) { |
| 662 iter != block->successors_end(); ++iter) { | 649 const InstructionBlock* succ_block = code.InstructionBlockAt(succ); |
| 663 os << " B" << (*iter)->id(); | 650 os << " B" << succ_block->id(); |
| 664 } | 651 } |
| 665 os << "\n"; | 652 os << "\n"; |
| 666 } | 653 } |
| 667 return os; | 654 return os; |
| 668 } | 655 } |
| 669 | 656 |
| 670 } // namespace compiler | 657 } // namespace compiler |
| 671 } // namespace internal | 658 } // namespace internal |
| 672 } // namespace v8 | 659 } // namespace v8 |
| OLD | NEW |