aboutsummaryrefslogtreecommitdiff
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.cc333
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";
}