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 |