| Index: src/compiler/instruction-selector.cc
|
| diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc
|
| index a8dbd7603b3a72baddd0a94ec475e2aca634d6d9..f233cae5b5ac89e324c159daaf7fd71c54127ee1 100644
|
| --- a/src/compiler/instruction-selector.cc
|
| +++ b/src/compiler/instruction-selector.cc
|
| @@ -38,13 +38,13 @@ InstructionSelector::InstructionSelector(
|
| effect_level_(node_count, 0, zone),
|
| virtual_registers_(node_count,
|
| InstructionOperand::kInvalidVirtualRegister, zone),
|
| + virtual_register_rename_(zone),
|
| scheduler_(nullptr),
|
| enable_scheduling_(enable_scheduling),
|
| frame_(frame) {
|
| instructions_.reserve(node_count);
|
| }
|
|
|
| -
|
| void InstructionSelector::SelectInstructions() {
|
| // Mark the inputs of all phis in loop headers as used.
|
| BasicBlockVector* blocks = schedule()->rpo_order();
|
| @@ -74,11 +74,15 @@ void InstructionSelector::SelectInstructions() {
|
| for (auto const block : *blocks) {
|
| InstructionBlock* instruction_block =
|
| sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
|
| + for (size_t i = 0; i < instruction_block->phis().size(); i++) {
|
| + UpdateRenamesInPhi(instruction_block->PhiAt(i));
|
| + }
|
| size_t end = instruction_block->code_end();
|
| size_t start = instruction_block->code_start();
|
| DCHECK_LE(end, start);
|
| StartBlock(RpoNumber::FromInt(block->rpo_number()));
|
| while (start-- > end) {
|
| + UpdateRenames(instructions_[start]);
|
| AddInstruction(instructions_[start]);
|
| }
|
| EndBlock(RpoNumber::FromInt(block->rpo_number()));
|
| @@ -253,6 +257,53 @@ bool InstructionSelector::IsOnlyUserOfNodeInSameBlock(Node* user,
|
| return true;
|
| }
|
|
|
| +void InstructionSelector::UpdateRenames(Instruction* instruction) {
|
| + for (size_t i = 0; i < instruction->InputCount(); i++) {
|
| + TryRename(instruction->InputAt(i));
|
| + }
|
| +}
|
| +
|
| +void InstructionSelector::UpdateRenamesInPhi(PhiInstruction* phi) {
|
| + for (size_t i = 0; i < phi->operands().size(); i++) {
|
| + int vreg = phi->operands()[i];
|
| + int renamed = GetRename(vreg);
|
| + if (vreg != renamed) {
|
| + phi->RenameInput(i, renamed);
|
| + }
|
| + }
|
| +}
|
| +
|
| +int InstructionSelector::GetRename(int virtual_register) {
|
| + int rename = virtual_register;
|
| + while (true) {
|
| + if (static_cast<size_t>(rename) >= virtual_register_rename_.size()) break;
|
| + int next = virtual_register_rename_[rename];
|
| + if (next == InstructionOperand::kInvalidVirtualRegister) {
|
| + break;
|
| + }
|
| + rename = next;
|
| + }
|
| + return rename;
|
| +}
|
| +
|
| +void InstructionSelector::TryRename(InstructionOperand* op) {
|
| + if (!op->IsUnallocated()) return;
|
| + int vreg = UnallocatedOperand::cast(op)->virtual_register();
|
| + int rename = GetRename(vreg);
|
| + if (rename != vreg) {
|
| + UnallocatedOperand::cast(op)->set_virtual_register(rename);
|
| + }
|
| +}
|
| +
|
| +void InstructionSelector::SetRename(const Node* node, const Node* rename) {
|
| + int vreg = GetVirtualRegister(node);
|
| + if (static_cast<size_t>(vreg) >= virtual_register_rename_.size()) {
|
| + int invalid = InstructionOperand::kInvalidVirtualRegister;
|
| + virtual_register_rename_.resize(vreg + 1, invalid);
|
| + }
|
| + virtual_register_rename_[vreg] = GetVirtualRegister(rename);
|
| +}
|
| +
|
| int InstructionSelector::GetVirtualRegister(const Node* node) {
|
| DCHECK_NOT_NULL(node);
|
| size_t const id = node->id();
|
| @@ -1451,7 +1502,8 @@ void InstructionSelector::VisitStackSlot(Node* node) {
|
| }
|
|
|
| void InstructionSelector::VisitBitcastWordToTagged(Node* node) {
|
| - EmitIdentity(node);
|
| + OperandGenerator g(this);
|
| + Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(node->InputAt(0)));
|
| }
|
|
|
| // 32 bit targets do not implement the following instructions.
|
| @@ -1948,8 +2000,8 @@ Instruction* InstructionSelector::EmitDeoptimize(
|
|
|
| void InstructionSelector::EmitIdentity(Node* node) {
|
| OperandGenerator g(this);
|
| - Node* value = node->InputAt(0);
|
| - Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
|
| + MarkAsUsed(node->InputAt(0));
|
| + SetRename(node, node->InputAt(0));
|
| }
|
|
|
| void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind,
|
|
|