Commit 4045b72c authored by dcarney's avatar dcarney Committed by Commit bot

[turbofan] remove one level of indirection in phi inputs

BUG=

Review URL: https://codereview.chromium.org/910753002

Cr-Commit-Position: refs/heads/master@{#26524}
parent 4c302ca2
...@@ -1019,7 +1019,7 @@ void InstructionSelector::VisitPhi(Node* node) { ...@@ -1019,7 +1019,7 @@ void InstructionSelector::VisitPhi(Node* node) {
for (int i = 0; i < input_count; ++i) { for (int i = 0; i < input_count; ++i) {
Node* const input = node->InputAt(i); Node* const input = node->InputAt(i);
MarkAsUsed(input); MarkAsUsed(input);
phi->Extend(instruction_zone(), GetVirtualRegister(input)); phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input));
} }
} }
......
...@@ -337,6 +337,22 @@ std::ostream& operator<<(std::ostream& os, const Constant& constant) { ...@@ -337,6 +337,22 @@ std::ostream& operator<<(std::ostream& os, const Constant& constant) {
} }
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) {}
void PhiInstruction::SetInput(size_t offset, int virtual_register) {
DCHECK(inputs_[offset].IsInvalid());
auto input = UnallocatedOperand(UnallocatedOperand::ANY, virtual_register);
inputs_[offset] = input;
operands_[offset] = virtual_register;
}
InstructionBlock::InstructionBlock(Zone* zone, BasicBlock::Id id, InstructionBlock::InstructionBlock(Zone* zone, BasicBlock::Id id,
BasicBlock::RpoNumber rpo_number, BasicBlock::RpoNumber rpo_number,
BasicBlock::RpoNumber loop_header, BasicBlock::RpoNumber loop_header,
...@@ -666,10 +682,10 @@ std::ostream& operator<<(std::ostream& os, ...@@ -666,10 +682,10 @@ std::ostream& operator<<(std::ostream& os,
for (auto phi : block->phis()) { for (auto phi : block->phis()) {
PrintableInstructionOperand printable_op = { PrintableInstructionOperand printable_op = {
printable.register_configuration_, phi->output()}; printable.register_configuration_, &phi->output()};
os << " phi: " << printable_op << " ="; os << " phi: " << printable_op << " =";
for (auto input : phi->inputs()) { for (auto input : phi->inputs()) {
printable_op.op_ = input; printable_op.op_ = &input;
os << " " << printable_op; os << " " << printable_op;
} }
os << "\n"; os << "\n";
......
...@@ -787,31 +787,17 @@ std::ostream& operator<<(std::ostream& os, const Constant& constant); ...@@ -787,31 +787,17 @@ std::ostream& operator<<(std::ostream& os, const Constant& constant);
class PhiInstruction FINAL : public ZoneObject { class PhiInstruction FINAL : public ZoneObject {
public: public:
typedef ZoneVector<InstructionOperand*> Inputs; typedef ZoneVector<InstructionOperand> Inputs;
PhiInstruction(Zone* zone, int virtual_register, size_t reserved_input_count) PhiInstruction(Zone* zone, int virtual_register, size_t input_count);
: virtual_register_(virtual_register),
operands_(zone), void SetInput(size_t offset, int virtual_register);
output_(nullptr),
inputs_(zone) {
UnallocatedOperand* output = new (zone)
UnallocatedOperand(UnallocatedOperand::NONE, virtual_register);
output_ = output;
inputs_.reserve(reserved_input_count);
operands_.reserve(reserved_input_count);
}
int virtual_register() const { return virtual_register_; } int virtual_register() const { return virtual_register_; }
const IntVector& operands() const { return operands_; } const IntVector& operands() const { return operands_; }
void Extend(Zone* zone, int virtual_register) { const InstructionOperand& output() const { return output_; }
UnallocatedOperand* input = new (zone) InstructionOperand& output() { return output_; }
UnallocatedOperand(UnallocatedOperand::ANY, virtual_register);
operands_.push_back(virtual_register);
inputs_.push_back(input);
}
InstructionOperand* output() const { return output_; }
const Inputs& inputs() const { return inputs_; } const Inputs& inputs() const { return inputs_; }
Inputs& inputs() { return inputs_; } Inputs& inputs() { return inputs_; }
...@@ -819,8 +805,8 @@ class PhiInstruction FINAL : public ZoneObject { ...@@ -819,8 +805,8 @@ class PhiInstruction FINAL : public ZoneObject {
// TODO(dcarney): some of these fields are only for verification, move them to // TODO(dcarney): some of these fields are only for verification, move them to
// verifier. // verifier.
const int virtual_register_; const int virtual_register_;
InstructionOperand output_;
IntVector operands_; IntVector operands_;
InstructionOperand* output_;
Inputs inputs_; Inputs inputs_;
}; };
......
...@@ -593,7 +593,7 @@ RegisterAllocator::RegisterAllocator(const RegisterConfiguration* config, ...@@ -593,7 +593,7 @@ RegisterAllocator::RegisterAllocator(const RegisterConfiguration* config,
debug_name_(debug_name), debug_name_(debug_name),
config_(config), config_(config),
operand_cache_(new (code_zone()) InstructionOperandCache()), operand_cache_(new (code_zone()) InstructionOperandCache()),
phi_map_(PhiMap::key_compare(), PhiMap::allocator_type(local_zone())), phi_map_(local_zone()),
live_in_sets_(code->InstructionBlockCount(), nullptr, local_zone()), live_in_sets_(code->InstructionBlockCount(), nullptr, local_zone()),
live_ranges_(code->VirtualRegisterCount() * 2, nullptr, local_zone()), live_ranges_(code->VirtualRegisterCount() * 2, nullptr, local_zone()),
fixed_live_ranges_(this->config()->num_general_registers(), nullptr, fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
...@@ -1372,25 +1372,25 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block, ...@@ -1372,25 +1372,25 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
void RegisterAllocator::ResolvePhis(const InstructionBlock* block) { void RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
for (auto phi : block->phis()) { for (auto phi : block->phis()) {
auto res = phi_map_.insert( int phi_vreg = phi->virtual_register();
std::make_pair(phi->virtual_register(), PhiMapValue(phi, block))); auto res =
phi_map_.insert(std::make_pair(phi_vreg, PhiMapValue(phi, block)));
DCHECK(res.second); DCHECK(res.second);
USE(res); USE(res);
auto output = phi->output(); auto& output = phi->output();
int phi_vreg = phi->virtual_register();
if (!FLAG_turbo_delay_ssa_decon) { if (!FLAG_turbo_delay_ssa_decon) {
for (size_t i = 0; i < phi->operands().size(); ++i) { for (size_t i = 0; i < phi->operands().size(); ++i) {
InstructionBlock* cur_block = InstructionBlock* cur_block =
code()->InstructionBlockAt(block->predecessors()[i]); code()->InstructionBlockAt(block->predecessors()[i]);
AddGapMove(cur_block->last_instruction_index() - 1, GapInstruction::END, AddGapMove(cur_block->last_instruction_index() - 1, GapInstruction::END,
phi->inputs()[i], output); &phi->inputs()[i], &output);
DCHECK(!InstructionAt(cur_block->last_instruction_index()) DCHECK(!InstructionAt(cur_block->last_instruction_index())
->HasPointerMap()); ->HasPointerMap());
} }
} }
auto live_range = LiveRangeFor(phi_vreg); auto live_range = LiveRangeFor(phi_vreg);
int gap_index = block->first_instruction_index(); int gap_index = block->first_instruction_index();
live_range->SpillAtDefinition(local_zone(), gap_index, output); live_range->SpillAtDefinition(local_zone(), gap_index, &output);
live_range->SetSpillStartIndex(gap_index); live_range->SetSpillStartIndex(gap_index);
// We use the phi-ness of some nodes in some later heuristics. // We use the phi-ness of some nodes in some later heuristics.
live_range->set_is_phi(true); live_range->set_is_phi(true);
...@@ -1622,7 +1622,7 @@ void RegisterAllocator::ResolveControlFlow() { ...@@ -1622,7 +1622,7 @@ void RegisterAllocator::ResolveControlFlow() {
finder.ArrayFor(phi->virtual_register())->FindSucc(block); finder.ArrayFor(phi->virtual_register())->FindSucc(block);
auto phi_output = auto phi_output =
block_bound->range_->GetAssignedOperand(operand_cache()); block_bound->range_->GetAssignedOperand(operand_cache());
phi->output()->ConvertTo(phi_output->kind(), phi_output->index()); phi->output().ConvertTo(phi_output->kind(), phi_output->index());
size_t pred_index = 0; size_t pred_index = 0;
for (auto pred : block->predecessors()) { for (auto pred : block->predecessors()) {
const InstructionBlock* pred_block = code()->InstructionBlockAt(pred); const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
...@@ -1630,7 +1630,7 @@ void RegisterAllocator::ResolveControlFlow() { ...@@ -1630,7 +1630,7 @@ void RegisterAllocator::ResolveControlFlow() {
->FindPred(pred_block); ->FindPred(pred_block);
auto pred_op = auto pred_op =
pred_bound->range_->GetAssignedOperand(operand_cache()); pred_bound->range_->GetAssignedOperand(operand_cache());
phi->inputs()[pred_index] = pred_op; phi->inputs()[pred_index] = *pred_op;
ResolveControlFlow(block, phi_output, pred_block, pred_op); ResolveControlFlow(block, phi_output, pred_block, pred_op);
pred_index++; pred_index++;
} }
......
...@@ -608,8 +608,7 @@ class RegisterAllocator FINAL : public ZoneObject { ...@@ -608,8 +608,7 @@ class RegisterAllocator FINAL : public ZoneObject {
PhiInstruction* const phi; PhiInstruction* const phi;
const InstructionBlock* const block; const InstructionBlock* const block;
}; };
typedef std::map<int, PhiMapValue, std::less<int>, typedef ZoneMap<int, PhiMapValue> PhiMap;
zone_allocator<std::pair<int, PhiMapValue>>> PhiMap;
Zone* const local_zone_; Zone* const local_zone_;
Frame* const frame_; Frame* const frame_;
......
...@@ -155,20 +155,35 @@ PhiInstruction* InstructionSequenceTest::Phi(VReg incoming_vreg_0, ...@@ -155,20 +155,35 @@ PhiInstruction* InstructionSequenceTest::Phi(VReg incoming_vreg_0,
VReg incoming_vreg_1, VReg incoming_vreg_1,
VReg incoming_vreg_2, VReg incoming_vreg_2,
VReg incoming_vreg_3) { VReg incoming_vreg_3) {
auto phi = new (zone()) PhiInstruction(zone(), NewReg().value_, 10);
VReg inputs[] = {incoming_vreg_0, incoming_vreg_1, incoming_vreg_2, VReg inputs[] = {incoming_vreg_0, incoming_vreg_1, incoming_vreg_2,
incoming_vreg_3}; incoming_vreg_3};
for (size_t i = 0; i < arraysize(inputs); ++i) { size_t input_count = 0;
if (inputs[i].value_ == kNoValue) break; for (; input_count < arraysize(inputs); ++input_count) {
Extend(phi, inputs[i]); if (inputs[input_count].value_ == kNoValue) break;
} }
CHECK(input_count > 0);
auto phi = new (zone()) PhiInstruction(zone(), NewReg().value_, input_count);
for (size_t i = 0; i < input_count; ++i) {
SetInput(phi, i, inputs[i]);
}
current_block_->AddPhi(phi);
return phi;
}
PhiInstruction* InstructionSequenceTest::Phi(VReg incoming_vreg_0,
size_t input_count) {
auto phi = new (zone()) PhiInstruction(zone(), NewReg().value_, input_count);
SetInput(phi, 0, incoming_vreg_0);
current_block_->AddPhi(phi); current_block_->AddPhi(phi);
return phi; return phi;
} }
void InstructionSequenceTest::Extend(PhiInstruction* phi, VReg vreg) { void InstructionSequenceTest::SetInput(PhiInstruction* phi, size_t input,
phi->Extend(zone(), vreg.value_); VReg vreg) {
CHECK(vreg.value_ != kNoValue);
phi->SetInput(input, vreg.value_);
} }
......
...@@ -138,7 +138,8 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { ...@@ -138,7 +138,8 @@ class InstructionSequenceTest : public TestWithIsolateAndZone {
VReg incoming_vreg_1 = VReg(), VReg incoming_vreg_1 = VReg(),
VReg incoming_vreg_2 = VReg(), VReg incoming_vreg_2 = VReg(),
VReg incoming_vreg_3 = VReg()); VReg incoming_vreg_3 = VReg());
void Extend(PhiInstruction* phi, VReg vreg); PhiInstruction* Phi(VReg incoming_vreg_0, size_t input_count);
void SetInput(PhiInstruction* phi, size_t input, VReg vreg);
VReg DefineConstant(int32_t imm = 0); VReg DefineConstant(int32_t imm = 0);
int EmitNop(); int EmitNop();
......
...@@ -42,9 +42,9 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) { ...@@ -42,9 +42,9 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) {
StartLoop(1); StartLoop(1);
StartBlock(); StartBlock();
auto phi = Phi(i_reg); auto phi = Phi(i_reg, 2);
auto ipp = EmitOI(Same(), Reg(phi), Use(DefineConstant())); auto ipp = EmitOI(Same(), Reg(phi), Use(DefineConstant()));
Extend(phi, ipp); SetInput(phi, 1, ipp);
EndBlock(Jump(0)); EndBlock(Jump(0));
EndLoop(); EndLoop();
...@@ -206,14 +206,14 @@ TEST_F(RegisterAllocatorTest, RegressionPhisNeedTooManyRegisters) { ...@@ -206,14 +206,14 @@ TEST_F(RegisterAllocatorTest, RegressionPhisNeedTooManyRegisters) {
StartBlock(); StartBlock();
for (size_t i = 0; i < arraysize(parameters); ++i) { for (size_t i = 0; i < arraysize(parameters); ++i) {
phis[i] = Phi(parameters[i]); phis[i] = Phi(parameters[i], 2);
} }
// Perform some computations. // Perform some computations.
// something like phi[i] += const // something like phi[i] += const
for (size_t i = 0; i < arraysize(parameters); ++i) { for (size_t i = 0; i < arraysize(parameters); ++i) {
auto result = EmitOI(Same(), Reg(phis[i]), Use(constant)); auto result = EmitOI(Same(), Reg(phis[i]), Use(constant));
Extend(phis[i], result); SetInput(phis[i], 1, result);
} }
EndBlock(Branch(Reg(DefineConstant()), 1, 2)); EndBlock(Branch(Reg(DefineConstant()), 1, 2));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment