diff options
Diffstat (limited to 'deps/v8/src/compiler/instruction.cc')
-rw-r--r-- | deps/v8/src/compiler/instruction.cc | 202 |
1 files changed, 110 insertions, 92 deletions
diff --git a/deps/v8/src/compiler/instruction.cc b/deps/v8/src/compiler/instruction.cc index c757557a0d..615b644334 100644 --- a/deps/v8/src/compiler/instruction.cc +++ b/deps/v8/src/compiler/instruction.cc @@ -12,6 +12,7 @@ namespace v8 { namespace internal { namespace compiler { +const auto GetRegConfig = RegisterConfiguration::Turbofan; FlagsCondition CommuteFlagsCondition(FlagsCondition condition) { switch (condition) { @@ -47,6 +48,10 @@ FlagsCondition CommuteFlagsCondition(FlagsCondition condition) { return kFloatGreaterThanOrEqualOrUnordered; case kFloatGreaterThan: return kFloatLessThan; + case kPositiveOrZero: + case kNegative: + UNREACHABLE(); + break; case kEqual: case kNotEqual: case kOverflow: @@ -59,6 +64,9 @@ FlagsCondition CommuteFlagsCondition(FlagsCondition condition) { return condition; } +bool InstructionOperand::InterferesWith(const InstructionOperand& that) const { + return EqualsCanonicalized(that); +} void InstructionOperand::Print(const RegisterConfiguration* config) const { OFStream os(stdout); @@ -68,13 +76,7 @@ void InstructionOperand::Print(const RegisterConfiguration* config) const { os << wrapper << std::endl; } - -void InstructionOperand::Print() const { - const RegisterConfiguration* config = - RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); - Print(config); -} - +void InstructionOperand::Print() const { Print(GetRegConfig()); } std::ostream& operator<<(std::ostream& os, const PrintableInstructionOperand& printable) { @@ -95,7 +97,7 @@ std::ostream& operator<<(std::ostream& os, << conf->GetGeneralRegisterName( unalloc->fixed_register_index()) << ")"; - case UnallocatedOperand::FIXED_DOUBLE_REGISTER: + case UnallocatedOperand::FIXED_FP_REGISTER: return os << "(=" << conf->GetDoubleRegisterName( unalloc->fixed_register_index()) @@ -126,14 +128,25 @@ std::ostream& operator<<(std::ostream& os, case InstructionOperand::ALLOCATED: { LocationOperand allocated = LocationOperand::cast(op); if (op.IsStackSlot()) { - os << "[stack:" << LocationOperand::cast(op).index(); - } else if (op.IsDoubleStackSlot()) { - os << "[double_stack:" << LocationOperand::cast(op).index(); + os << "[stack:" << allocated.index(); + } else if (op.IsFPStackSlot()) { + os << "[fp_stack:" << allocated.index(); } else if (op.IsRegister()) { - os << "[" << LocationOperand::cast(op).GetRegister().ToString() << "|R"; + os << "[" + << GetRegConfig()->GetGeneralRegisterName(allocated.register_code()) + << "|R"; + } else if (op.IsDoubleRegister()) { + os << "[" + << GetRegConfig()->GetDoubleRegisterName(allocated.register_code()) + << "|R"; + } else if (op.IsFloatRegister()) { + os << "[" + << GetRegConfig()->GetFloatRegisterName(allocated.register_code()) + << "|R"; } else { - DCHECK(op.IsDoubleRegister()); - os << "[" << LocationOperand::cast(op).GetDoubleRegister().ToString() + DCHECK(op.IsSimd128Register()); + os << "[" + << GetRegConfig()->GetSimd128RegisterName(allocated.register_code()) << "|R"; } if (allocated.IsExplicit()) { @@ -167,6 +180,12 @@ std::ostream& operator<<(std::ostream& os, case MachineRepresentation::kSimd128: os << "|s128"; break; + case MachineRepresentation::kTaggedSigned: + os << "|ts"; + break; + case MachineRepresentation::kTaggedPointer: + os << "|tp"; + break; case MachineRepresentation::kTagged: os << "|t"; break; @@ -180,7 +199,6 @@ std::ostream& operator<<(std::ostream& os, return os; } - void MoveOperands::Print(const RegisterConfiguration* config) const { OFStream os(stdout); PrintableInstructionOperand wrapper; @@ -191,13 +209,7 @@ void MoveOperands::Print(const RegisterConfiguration* config) const { os << wrapper << std::endl; } - -void MoveOperands::Print() const { - const RegisterConfiguration* config = - RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); - Print(config); -} - +void MoveOperands::Print() const { Print(GetRegConfig()); } std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& printable) { @@ -246,22 +258,23 @@ ExplicitOperand::ExplicitOperand(LocationKind kind, MachineRepresentation rep, int index) : LocationOperand(EXPLICIT, kind, rep, index) { DCHECK_IMPLIES(kind == REGISTER && !IsFloatingPoint(rep), - Register::from_code(index).IsAllocatable()); - DCHECK_IMPLIES(kind == REGISTER && IsFloatingPoint(rep), - DoubleRegister::from_code(index).IsAllocatable()); + GetRegConfig()->IsAllocatableGeneralCode(index)); + DCHECK_IMPLIES(kind == REGISTER && rep == MachineRepresentation::kFloat32, + GetRegConfig()->IsAllocatableFloatCode(index)); + DCHECK_IMPLIES(kind == REGISTER && (rep == MachineRepresentation::kFloat64), + GetRegConfig()->IsAllocatableDoubleCode(index)); } - Instruction::Instruction(InstructionCode opcode) : opcode_(opcode), bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | TempCountField::encode(0) | IsCallField::encode(false)), - reference_map_(nullptr) { + reference_map_(nullptr), + block_(nullptr) { parallel_moves_[0] = nullptr; parallel_moves_[1] = nullptr; } - Instruction::Instruction(InstructionCode opcode, size_t output_count, InstructionOperand* outputs, size_t input_count, InstructionOperand* inputs, size_t temp_count, @@ -271,7 +284,8 @@ Instruction::Instruction(InstructionCode opcode, size_t output_count, InputCountField::encode(input_count) | TempCountField::encode(temp_count) | IsCallField::encode(false)), - reference_map_(nullptr) { + reference_map_(nullptr), + block_(nullptr) { parallel_moves_[0] = nullptr; parallel_moves_[1] = nullptr; size_t offset = 0; @@ -309,13 +323,7 @@ void Instruction::Print(const RegisterConfiguration* config) const { os << wrapper << std::endl; } - -void Instruction::Print() const { - const RegisterConfiguration* config = - RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); - Print(config); -} - +void Instruction::Print() const { Print(GetRegConfig()); } std::ostream& operator<<(std::ostream& os, const PrintableParallelMove& printable) { @@ -335,7 +343,7 @@ std::ostream& operator<<(std::ostream& os, void ReferenceMap::RecordReference(const AllocatedOperand& op) { // Do not record arguments as pointers. if (op.IsStackSlot() && LocationOperand::cast(op).index() < 0) return; - DCHECK(!op.IsDoubleRegister() && !op.IsDoubleStackSlot()); + DCHECK(!op.IsFPRegister() && !op.IsFPStackSlot()); reference_operands_.push_back(op); } @@ -343,9 +351,7 @@ void ReferenceMap::RecordReference(const AllocatedOperand& op) { std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm) { os << "{"; bool first = true; - PrintableInstructionOperand poi = { - RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), - InstructionOperand()}; + PrintableInstructionOperand poi = {GetRegConfig(), InstructionOperand()}; for (const InstructionOperand& op : pm.reference_operands_) { if (!first) { os << ";"; @@ -449,6 +455,10 @@ std::ostream& operator<<(std::ostream& os, const FlagsCondition& fc) { return os << "overflow"; case kNotOverflow: return os << "not overflow"; + case kPositiveOrZero: + return os << "positive or zero"; + case kNegative: + return os << "negative"; } UNREACHABLE(); return os; @@ -504,6 +514,24 @@ std::ostream& operator<<(std::ostream& os, Constant::Constant(int32_t v) : type_(kInt32), value_(v) {} +Constant::Constant(RelocatablePtrConstantInfo info) { + if (info.type() == RelocatablePtrConstantInfo::kInt32) { + type_ = kInt32; + } else if (info.type() == RelocatablePtrConstantInfo::kInt64) { + type_ = kInt64; + } else { + UNREACHABLE(); + } + value_ = info.value(); + rmode_ = info.rmode(); +} + +Handle<HeapObject> Constant::ToHeapObject() const { + DCHECK_EQ(kHeapObject, type()); + Handle<HeapObject> value( + bit_cast<HeapObject**>(static_cast<intptr_t>(value_))); + return value; +} std::ostream& operator<<(std::ostream& os, const Constant& constant) { switch (constant.type()) { @@ -603,7 +631,6 @@ static InstructionBlock* InstructionBlockFor(Zone* zone, return instr_block; } - InstructionBlocks* InstructionSequence::InstructionBlocksFor( Zone* zone, const Schedule* schedule) { InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1); @@ -620,7 +647,7 @@ InstructionBlocks* InstructionSequence::InstructionBlocksFor( return blocks; } -void InstructionSequence::ValidateEdgeSplitForm() { +void InstructionSequence::ValidateEdgeSplitForm() const { // Validate blocks are in edge-split form: no block with multiple successors // has an edge to a block (== a successor) with more than one predecessors. for (const InstructionBlock* block : instruction_blocks()) { @@ -635,7 +662,7 @@ void InstructionSequence::ValidateEdgeSplitForm() { } } -void InstructionSequence::ValidateDeferredBlockExitPaths() { +void InstructionSequence::ValidateDeferredBlockExitPaths() const { // A deferred block with more than one successor must have all its successors // deferred. for (const InstructionBlock* block : instruction_blocks()) { @@ -646,7 +673,21 @@ void InstructionSequence::ValidateDeferredBlockExitPaths() { } } -void InstructionSequence::ValidateSSA() { +void InstructionSequence::ValidateDeferredBlockEntryPaths() const { + // If a deferred block has multiple predecessors, they have to + // all be deferred. Otherwise, we can run into a situation where a range + // that spills only in deferred blocks inserts its spill in the block, but + // other ranges need moves inserted by ResolveControlFlow in the predecessors, + // which may clobber the register of this range. + for (const InstructionBlock* block : instruction_blocks()) { + if (!block->IsDeferred() || block->PredecessorCount() <= 1) continue; + for (RpoNumber predecessor_id : block->predecessors()) { + CHECK(InstructionBlockAt(predecessor_id)->IsDeferred()); + } + } +} + +void InstructionSequence::ValidateSSA() const { // TODO(mtrofin): We could use a local zone here instead. BitVector definitions(VirtualRegisterCount(), zone()); for (const Instruction* instruction : *this) { @@ -675,7 +716,6 @@ void InstructionSequence::ComputeAssemblyOrder(InstructionBlocks* blocks) { } } - InstructionSequence::InstructionSequence(Isolate* isolate, Zone* instruction_zone, InstructionBlocks* instruction_blocks) @@ -683,7 +723,6 @@ InstructionSequence::InstructionSequence(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()), @@ -691,10 +730,8 @@ InstructionSequence::InstructionSequence(Isolate* isolate, next_virtual_register_(0), reference_maps_(zone()), representations_(zone()), - deoptimization_entries_(zone()) { - block_starts_.reserve(instruction_blocks_->size()); -} - + deoptimization_entries_(zone()), + current_block_(nullptr) {} int InstructionSequence::NextVirtualRegister() { int virtual_register = next_virtual_register_++; @@ -710,28 +747,31 @@ Instruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const { void InstructionSequence::StartBlock(RpoNumber rpo) { - DCHECK(block_starts_.size() == rpo.ToSize()); - InstructionBlock* block = InstructionBlockAt(rpo); + DCHECK_NULL(current_block_); + current_block_ = InstructionBlockAt(rpo); int code_start = static_cast<int>(instructions_.size()); - block->set_code_start(code_start); - block_starts_.push_back(code_start); + current_block_->set_code_start(code_start); } void InstructionSequence::EndBlock(RpoNumber rpo) { int end = static_cast<int>(instructions_.size()); - InstructionBlock* block = InstructionBlockAt(rpo); - if (block->code_start() == end) { // Empty block. Insert a nop. + DCHECK_EQ(current_block_->rpo_number(), rpo); + if (current_block_->code_start() == end) { // Empty block. Insert a nop. AddInstruction(Instruction::New(zone(), kArchNop)); end = static_cast<int>(instructions_.size()); } - DCHECK(block->code_start() >= 0 && block->code_start() < end); - block->set_code_end(end); + DCHECK(current_block_->code_start() >= 0 && + current_block_->code_start() < end); + current_block_->set_code_end(end); + current_block_ = nullptr; } int InstructionSequence::AddInstruction(Instruction* instr) { + DCHECK_NOT_NULL(current_block_); int index = static_cast<int>(instructions_.size()); + instr->set_block(current_block_); instructions_.push_back(instr); if (instr->NeedsReferenceMap()) { DCHECK(instr->reference_map() == nullptr); @@ -746,18 +786,7 @@ int InstructionSequence::AddInstruction(Instruction* instr) { InstructionBlock* InstructionSequence::GetInstructionBlock( int instruction_index) const { - DCHECK(instruction_blocks_->size() == block_starts_.size()); - auto begin = block_starts_.begin(); - auto end = std::lower_bound(begin, block_starts_.end(), instruction_index); - // Post condition of std::lower_bound: - DCHECK(end == block_starts_.end() || *end >= instruction_index); - if (end == block_starts_.end() || *end > instruction_index) --end; - DCHECK(*end <= instruction_index); - size_t index = std::distance(begin, end); - InstructionBlock* block = instruction_blocks_->at(index); - DCHECK(block->code_start() <= instruction_index && - instruction_index < block->code_end()); - return block; + return instructions()[instruction_index]->block(); } @@ -772,6 +801,8 @@ static MachineRepresentation FilterRepresentation(MachineRepresentation rep) { case MachineRepresentation::kFloat32: case MachineRepresentation::kFloat64: case MachineRepresentation::kSimd128: + case MachineRepresentation::kTaggedSigned: + case MachineRepresentation::kTaggedPointer: case MachineRepresentation::kTagged: return rep; case MachineRepresentation::kNone: @@ -806,22 +837,16 @@ void InstructionSequence::MarkAsRepresentation(MachineRepresentation rep, representations_[virtual_register] = rep; } - -InstructionSequence::StateId InstructionSequence::AddFrameStateDescriptor( - FrameStateDescriptor* descriptor) { +int InstructionSequence::AddDeoptimizationEntry( + FrameStateDescriptor* descriptor, DeoptimizeReason reason) { int deoptimization_id = static_cast<int>(deoptimization_entries_.size()); - deoptimization_entries_.push_back(descriptor); - return StateId::FromInt(deoptimization_id); + deoptimization_entries_.push_back(DeoptimizationEntry(descriptor, reason)); + return deoptimization_id; } -FrameStateDescriptor* InstructionSequence::GetFrameStateDescriptor( - InstructionSequence::StateId state_id) { - return deoptimization_entries_[state_id.ToInt()]; -} - - -int InstructionSequence::GetFrameStateDescriptorCount() { - return static_cast<int>(deoptimization_entries_.size()); +DeoptimizationEntry const& InstructionSequence::GetDeoptimizationEntry( + int state_id) { + return deoptimization_entries_[state_id]; } @@ -858,12 +883,7 @@ void InstructionSequence::Print(const RegisterConfiguration* config) const { os << wrapper << std::endl; } - -void InstructionSequence::Print() const { - const RegisterConfiguration* config = - RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); - Print(config); -} +void InstructionSequence::Print() const { Print(GetRegConfig()); } void InstructionSequence::PrintBlock(const RegisterConfiguration* config, int block_id) const { @@ -917,9 +937,7 @@ void InstructionSequence::PrintBlock(const RegisterConfiguration* config, } void InstructionSequence::PrintBlock(int block_id) const { - const RegisterConfiguration* config = - RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); - PrintBlock(config, block_id); + PrintBlock(GetRegConfig(), block_id); } FrameStateDescriptor::FrameStateDescriptor( |