diff options
Diffstat (limited to 'deps/v8/src/compiler/instruction.cc')
-rw-r--r-- | deps/v8/src/compiler/instruction.cc | 333 |
1 files changed, 201 insertions, 132 deletions
diff --git a/deps/v8/src/compiler/instruction.cc b/deps/v8/src/compiler/instruction.cc index 8446a0dced..cea74a7012 100644 --- a/deps/v8/src/compiler/instruction.cc +++ b/deps/v8/src/compiler/instruction.cc @@ -13,7 +13,7 @@ namespace compiler { std::ostream& operator<<(std::ostream& os, const PrintableInstructionOperand& printable) { - const InstructionOperand& op = *printable.op_; + const InstructionOperand& op = printable.op_; const RegisterConfiguration* conf = printable.register_configuration_; switch (op.kind()) { case InstructionOperand::UNALLOCATED: { @@ -42,17 +42,59 @@ std::ostream& operator<<(std::ostream& os, } } case InstructionOperand::CONSTANT: - return os << "[constant:" << op.index() << "]"; - case InstructionOperand::IMMEDIATE: - return os << "[immediate:" << op.index() << "]"; - case InstructionOperand::STACK_SLOT: - return os << "[stack:" << op.index() << "]"; - case InstructionOperand::DOUBLE_STACK_SLOT: - return os << "[double_stack:" << op.index() << "]"; - case InstructionOperand::REGISTER: - return os << "[" << conf->general_register_name(op.index()) << "|R]"; - case InstructionOperand::DOUBLE_REGISTER: - return os << "[" << conf->double_register_name(op.index()) << "|R]"; + return os << "[constant:" << ConstantOperand::cast(op).virtual_register() + << "]"; + case InstructionOperand::IMMEDIATE: { + auto imm = ImmediateOperand::cast(op); + switch (imm.type()) { + case ImmediateOperand::INLINE: + return os << "#" << imm.inline_value(); + case ImmediateOperand::INDEXED: + return os << "[immediate:" << imm.indexed_value() << "]"; + } + } + case InstructionOperand::ALLOCATED: { + auto allocated = AllocatedOperand::cast(op); + switch (allocated.allocated_kind()) { + case AllocatedOperand::STACK_SLOT: + os << "[stack:" << StackSlotOperand::cast(op).index(); + break; + case AllocatedOperand::DOUBLE_STACK_SLOT: + os << "[double_stack:" << DoubleStackSlotOperand::cast(op).index(); + break; + case AllocatedOperand::REGISTER: + os << "[" + << conf->general_register_name(RegisterOperand::cast(op).index()) + << "|R"; + break; + case AllocatedOperand::DOUBLE_REGISTER: + os << "[" + << conf->double_register_name( + DoubleRegisterOperand::cast(op).index()) << "|R"; + break; + } + switch (allocated.machine_type()) { + case kRepWord32: + os << "|w32"; + break; + case kRepWord64: + os << "|w64"; + break; + case kRepFloat32: + os << "|f32"; + break; + case kRepFloat64: + os << "|f64"; + break; + case kRepTagged: + os << "|t"; + break; + default: + os << "|?"; + break; + } + return os << "]"; + } case InstructionOperand::INVALID: return os << "(x)"; } @@ -66,9 +108,8 @@ std::ostream& operator<<(std::ostream& os, const MoveOperands& mo = *printable.move_operands_; PrintableInstructionOperand printable_op = {printable.register_configuration_, mo.destination()}; - os << printable_op; - if (!mo.source()->Equals(mo.destination())) { + if (!mo.source().Equals(mo.destination())) { printable_op.op_ = mo.source(); os << " = " << printable_op; } @@ -77,24 +118,23 @@ std::ostream& operator<<(std::ostream& os, bool ParallelMove::IsRedundant() const { - for (int i = 0; i < move_operands_.length(); ++i) { - if (!move_operands_[i].IsRedundant()) return false; + for (auto move : *this) { + if (!move->IsRedundant()) return false; } return true; } MoveOperands* ParallelMove::PrepareInsertAfter(MoveOperands* move) const { - auto move_ops = move_operands(); MoveOperands* replacement = nullptr; MoveOperands* to_eliminate = nullptr; - for (auto curr = move_ops->begin(); curr != move_ops->end(); ++curr) { + for (auto curr : *this) { if (curr->IsEliminated()) continue; - if (curr->destination()->Equals(move->source())) { + if (curr->destination().EqualsModuloType(move->source())) { DCHECK(!replacement); replacement = curr; if (to_eliminate != nullptr) break; - } else if (curr->destination()->Equals(move->destination())) { + } else if (curr->destination().EqualsModuloType(move->destination())) { DCHECK(!to_eliminate); to_eliminate = curr; if (replacement != nullptr) break; @@ -110,7 +150,10 @@ Instruction::Instruction(InstructionCode opcode) : opcode_(opcode), bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | TempCountField::encode(0) | IsCallField::encode(false)), - pointer_map_(NULL) {} + reference_map_(NULL) { + parallel_moves_[0] = nullptr; + parallel_moves_[1] = nullptr; +} Instruction::Instruction(InstructionCode opcode, size_t output_count, @@ -122,7 +165,9 @@ Instruction::Instruction(InstructionCode opcode, size_t output_count, InputCountField::encode(input_count) | TempCountField::encode(temp_count) | IsCallField::encode(false)), - pointer_map_(NULL) { + reference_map_(NULL) { + parallel_moves_[0] = nullptr; + parallel_moves_[1] = nullptr; size_t offset = 0; for (size_t i = 0; i < output_count; ++i) { DCHECK(!outputs[i].IsInvalid()); @@ -139,11 +184,12 @@ Instruction::Instruction(InstructionCode opcode, size_t output_count, } -bool GapInstruction::IsRedundant() const { - for (int i = GapInstruction::FIRST_INNER_POSITION; - i <= GapInstruction::LAST_INNER_POSITION; i++) { - if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) +bool Instruction::AreMovesRedundant() const { + for (int i = Instruction::FIRST_GAP_POSITION; + i <= Instruction::LAST_GAP_POSITION; i++) { + if (parallel_moves_[i] != nullptr && !parallel_moves_[i]->IsRedundant()) { return false; + } } return true; } @@ -153,8 +199,7 @@ std::ostream& operator<<(std::ostream& os, const PrintableParallelMove& printable) { const ParallelMove& pm = *printable.parallel_move_; bool first = true; - for (ZoneList<MoveOperands>::iterator move = pm.move_operands()->begin(); - move != pm.move_operands()->end(); ++move) { + for (auto move : pm) { if (move->IsEliminated()) continue; if (!first) os << " "; first = false; @@ -165,42 +210,27 @@ std::ostream& operator<<(std::ostream& os, } -void PointerMap::RecordPointer(InstructionOperand* op, Zone* zone) { +void ReferenceMap::RecordReference(const AllocatedOperand& op) { // Do not record arguments as pointers. - if (op->IsStackSlot() && op->index() < 0) return; - DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); - pointer_operands_.Add(op, zone); + if (op.IsStackSlot() && StackSlotOperand::cast(op).index() < 0) return; + DCHECK(!op.IsDoubleRegister() && !op.IsDoubleStackSlot()); + reference_operands_.push_back(op); } -void PointerMap::RemovePointer(InstructionOperand* op) { - // Do not record arguments as pointers. - if (op->IsStackSlot() && op->index() < 0) return; - DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); - for (int i = 0; i < pointer_operands_.length(); ++i) { - if (pointer_operands_[i]->Equals(op)) { - pointer_operands_.Remove(i); - --i; - } - } -} - - -void PointerMap::RecordUntagged(InstructionOperand* op, Zone* zone) { - // Do not record arguments as pointers. - if (op->IsStackSlot() && op->index() < 0) return; - DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); - untagged_operands_.Add(op, zone); -} - - -std::ostream& operator<<(std::ostream& os, const PointerMap& pm) { +std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm) { os << "{"; - for (ZoneList<InstructionOperand*>::iterator op = - pm.pointer_operands_.begin(); - op != pm.pointer_operands_.end(); ++op) { - if (op != pm.pointer_operands_.begin()) os << ";"; - os << *op; + bool first = true; + PrintableInstructionOperand poi = {RegisterConfiguration::ArchDefault(), + InstructionOperand()}; + for (auto& op : pm.reference_operands_) { + if (!first) { + os << ";"; + } else { + first = false; + } + poi.op_ = op; + os << poi; } return os << "}"; } @@ -288,49 +318,42 @@ std::ostream& operator<<(std::ostream& os, const PrintableInstruction& printable) { const Instruction& instr = *printable.instr_; PrintableInstructionOperand printable_op = {printable.register_configuration_, - NULL}; + InstructionOperand()}; + os << "gap "; + for (int i = Instruction::FIRST_GAP_POSITION; + i <= Instruction::LAST_GAP_POSITION; i++) { + os << "("; + if (instr.parallel_moves()[i] != NULL) { + PrintableParallelMove ppm = {printable.register_configuration_, + instr.parallel_moves()[i]}; + os << ppm; + } + os << ") "; + } + os << "\n "; + if (instr.OutputCount() > 1) os << "("; for (size_t i = 0; i < instr.OutputCount(); i++) { if (i > 0) os << ", "; - printable_op.op_ = instr.OutputAt(i); + printable_op.op_ = *instr.OutputAt(i); os << printable_op; } if (instr.OutputCount() > 1) os << ") = "; if (instr.OutputCount() == 1) os << " = "; - if (instr.IsGapMoves()) { - const GapInstruction* gap = GapInstruction::cast(&instr); - os << "gap "; - for (int i = GapInstruction::FIRST_INNER_POSITION; - i <= GapInstruction::LAST_INNER_POSITION; i++) { - os << "("; - if (gap->parallel_moves_[i] != NULL) { - PrintableParallelMove ppm = {printable.register_configuration_, - gap->parallel_moves_[i]}; - os << ppm; - } - os << ") "; - } - } else if (instr.IsSourcePosition()) { - const SourcePositionInstruction* pos = - SourcePositionInstruction::cast(&instr); - os << "position (" << pos->source_position().raw() << ")"; - } else { - os << ArchOpcodeField::decode(instr.opcode()); - AddressingMode am = AddressingModeField::decode(instr.opcode()); - if (am != kMode_None) { - os << " : " << AddressingModeField::decode(instr.opcode()); - } - FlagsMode fm = FlagsModeField::decode(instr.opcode()); - if (fm != kFlags_none) { - os << " && " << fm << " if " - << FlagsConditionField::decode(instr.opcode()); - } + os << ArchOpcodeField::decode(instr.opcode()); + AddressingMode am = AddressingModeField::decode(instr.opcode()); + if (am != kMode_None) { + os << " : " << AddressingModeField::decode(instr.opcode()); + } + FlagsMode fm = FlagsModeField::decode(instr.opcode()); + if (fm != kFlags_none) { + os << " && " << fm << " if " << FlagsConditionField::decode(instr.opcode()); } if (instr.InputCount() > 0) { for (size_t i = 0; i < instr.InputCount(); i++) { - printable_op.op_ = instr.InputAt(i); + printable_op.op_ = *instr.InputAt(i); os << " " << printable_op; } } @@ -368,14 +391,12 @@ PhiInstruction::PhiInstruction(Zone* zone, int virtual_register, size_t input_count) : virtual_register_(virtual_register), output_(UnallocatedOperand(UnallocatedOperand::NONE, virtual_register)), - operands_(input_count, zone), - inputs_(input_count, zone) {} + operands_(input_count, InstructionOperand::kInvalidVirtualRegister, + zone) {} void PhiInstruction::SetInput(size_t offset, int virtual_register) { - DCHECK(inputs_[offset].IsInvalid()); - auto input = UnallocatedOperand(UnallocatedOperand::ANY, virtual_register); - inputs_[offset] = input; + DCHECK_EQ(InstructionOperand::kInvalidVirtualRegister, operands_[offset]); operands_[offset] = virtual_register; } @@ -392,7 +413,10 @@ InstructionBlock::InstructionBlock(Zone* zone, RpoNumber rpo_number, loop_end_(loop_end), code_start_(-1), code_end_(-1), - deferred_(deferred) {} + deferred_(deferred), + needs_frame_(false), + must_construct_frame_(false), + must_deconstruct_frame_(false) {} size_t InstructionBlock::PredecessorIndexOf(RpoNumber rpo_number) const { @@ -473,15 +497,15 @@ InstructionSequence::InstructionSequence(Isolate* isolate, : isolate_(isolate), zone_(instruction_zone), instruction_blocks_(instruction_blocks), + source_positions_(zone()), block_starts_(zone()), constants_(ConstantMap::key_compare(), ConstantMap::allocator_type(zone())), immediates_(zone()), instructions_(zone()), next_virtual_register_(0), - pointer_maps_(zone()), - doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), - references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), + reference_maps_(zone()), + representations_(zone()), deoptimization_entries_(zone()) { block_starts_.reserve(instruction_blocks_->size()); } @@ -494,9 +518,9 @@ int InstructionSequence::NextVirtualRegister() { } -GapInstruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const { +Instruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const { const InstructionBlock* block = InstructionBlockAt(rpo); - return GapInstruction::cast(InstructionAt(block->code_start())); + return InstructionAt(block->code_start()); } @@ -522,22 +546,20 @@ void InstructionSequence::EndBlock(RpoNumber rpo) { int InstructionSequence::AddInstruction(Instruction* instr) { - GapInstruction* gap = GapInstruction::New(zone()); - instructions_.push_back(gap); int index = static_cast<int>(instructions_.size()); instructions_.push_back(instr); - if (instr->NeedsPointerMap()) { - DCHECK(instr->pointer_map() == NULL); - PointerMap* pointer_map = new (zone()) PointerMap(zone()); - pointer_map->set_instruction_position(index); - instr->set_pointer_map(pointer_map); - pointer_maps_.push_back(pointer_map); + if (instr->NeedsReferenceMap()) { + DCHECK(instr->reference_map() == NULL); + ReferenceMap* reference_map = new (zone()) ReferenceMap(zone()); + reference_map->set_instruction_position(index); + instr->set_reference_map(reference_map); + reference_maps_.push_back(reference_map); } return index; } -const InstructionBlock* InstructionSequence::GetInstructionBlock( +InstructionBlock* InstructionSequence::GetInstructionBlock( int instruction_index) const { DCHECK(instruction_blocks_->size() == block_starts_.size()); auto begin = block_starts_.begin(); @@ -551,30 +573,48 @@ const InstructionBlock* InstructionSequence::GetInstructionBlock( } -bool InstructionSequence::IsReference(int virtual_register) const { - return references_.find(virtual_register) != references_.end(); -} - - -bool InstructionSequence::IsDouble(int virtual_register) const { - return doubles_.find(virtual_register) != doubles_.end(); -} - - -void InstructionSequence::MarkAsReference(int virtual_register) { - references_.insert(virtual_register); +static MachineType FilterRepresentation(MachineType rep) { + DCHECK_EQ(rep, RepresentationOf(rep)); + switch (rep) { + case kRepBit: + case kRepWord8: + case kRepWord16: + return InstructionSequence::DefaultRepresentation(); + case kRepWord32: + case kRepWord64: + case kRepFloat32: + case kRepFloat64: + case kRepTagged: + return rep; + default: + break; + } + UNREACHABLE(); + return kMachNone; } -void InstructionSequence::MarkAsDouble(int virtual_register) { - doubles_.insert(virtual_register); +MachineType InstructionSequence::GetRepresentation(int virtual_register) const { + DCHECK_LE(0, virtual_register); + DCHECK_LT(virtual_register, VirtualRegisterCount()); + if (virtual_register >= static_cast<int>(representations_.size())) { + return DefaultRepresentation(); + } + return representations_[virtual_register]; } -void InstructionSequence::AddGapMove(int index, InstructionOperand* from, - InstructionOperand* to) { - GapAt(index)->GetOrCreateParallelMove(GapInstruction::START, zone())->AddMove( - from, to, zone()); +void InstructionSequence::MarkAsRepresentation(MachineType machine_type, + int virtual_register) { + DCHECK_LE(0, virtual_register); + DCHECK_LT(virtual_register, VirtualRegisterCount()); + if (virtual_register >= static_cast<int>(representations_.size())) { + representations_.resize(VirtualRegisterCount(), DefaultRepresentation()); + } + machine_type = FilterRepresentation(machine_type); + DCHECK_IMPLIES(representations_[virtual_register] != machine_type, + representations_[virtual_register] == DefaultRepresentation()); + representations_[virtual_register] = machine_type; } @@ -596,6 +636,33 @@ int InstructionSequence::GetFrameStateDescriptorCount() { } +RpoNumber InstructionSequence::InputRpo(Instruction* instr, size_t index) { + InstructionOperand* operand = instr->InputAt(index); + Constant constant = + operand->IsImmediate() + ? GetImmediate(ImmediateOperand::cast(operand)) + : GetConstant(ConstantOperand::cast(operand)->virtual_register()); + return constant.ToRpoNumber(); +} + + +bool InstructionSequence::GetSourcePosition(const Instruction* instr, + SourcePosition* result) const { + auto it = source_positions_.find(instr); + if (it == source_positions_.end()) return false; + *result = it->second; + return true; +} + + +void InstructionSequence::SetSourcePosition(const Instruction* instr, + SourcePosition value) { + DCHECK(!value.IsInvalid()); + DCHECK(!value.IsUnknown()); + source_positions_.insert(std::make_pair(instr, value)); +} + + FrameStateDescriptor::FrameStateDescriptor( Zone* zone, const FrameStateCallInfo& state_info, size_t parameters_count, size_t locals_count, size_t stack_count, FrameStateDescriptor* outer_state) @@ -693,6 +760,9 @@ std::ostream& operator<<(std::ostream& os, os << "B" << block->rpo_number(); os << ": AO#" << block->ao_number(); if (block->IsDeferred()) os << " (deferred)"; + if (!block->needs_frame()) os << " (no frame)"; + if (block->must_construct_frame()) os << " (construct frame)"; + if (block->must_deconstruct_frame()) os << " (deconstruct frame)"; if (block->IsLoopHeader()) { os << " loop blocks: [" << block->rpo_number() << ", " << block->loop_end() << ")"; @@ -707,11 +777,10 @@ std::ostream& operator<<(std::ostream& os, for (auto phi : block->phis()) { PrintableInstructionOperand printable_op = { - printable.register_configuration_, &phi->output()}; + printable.register_configuration_, phi->output()}; os << " phi: " << printable_op << " ="; - for (auto input : phi->inputs()) { - printable_op.op_ = &input; - os << " " << printable_op; + for (auto input : phi->operands()) { + os << " v" << input; } os << "\n"; } |