summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/instruction.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/instruction.cc')
-rw-r--r--deps/v8/src/compiler/instruction.cc202
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(