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) {
for (int i = 0; i < input_count; ++i) {
Node* const input = node->InputAt(i);
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) {
}
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,
BasicBlock::RpoNumber rpo_number,
BasicBlock::RpoNumber loop_header,
......@@ -666,10 +682,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;
printable_op.op_ = &input;
os << " " << printable_op;
}
os << "\n";
......
......@@ -787,31 +787,17 @@ std::ostream& operator<<(std::ostream& os, const Constant& constant);
class PhiInstruction FINAL : public ZoneObject {
public:
typedef ZoneVector<InstructionOperand*> Inputs;
typedef ZoneVector<InstructionOperand> Inputs;
PhiInstruction(Zone* zone, int virtual_register, size_t reserved_input_count)
: virtual_register_(virtual_register),
operands_(zone),
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);
}
PhiInstruction(Zone* zone, int virtual_register, size_t input_count);
void SetInput(size_t offset, int virtual_register);
int virtual_register() const { return virtual_register_; }
const IntVector& operands() const { return operands_; }
void Extend(Zone* zone, int virtual_register) {
UnallocatedOperand* input = new (zone)
UnallocatedOperand(UnallocatedOperand::ANY, virtual_register);
operands_.push_back(virtual_register);
inputs_.push_back(input);
}
InstructionOperand* output() const { return output_; }
const InstructionOperand& output() const { return output_; }
InstructionOperand& output() { return output_; }
const Inputs& inputs() const { return inputs_; }
Inputs& inputs() { return inputs_; }
......@@ -819,8 +805,8 @@ class PhiInstruction FINAL : public ZoneObject {
// TODO(dcarney): some of these fields are only for verification, move them to
// verifier.
const int virtual_register_;
InstructionOperand output_;
IntVector operands_;
InstructionOperand* output_;
Inputs inputs_;
};
......
......@@ -593,7 +593,7 @@ RegisterAllocator::RegisterAllocator(const RegisterConfiguration* config,
debug_name_(debug_name),
config_(config),
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_ranges_(code->VirtualRegisterCount() * 2, nullptr, local_zone()),
fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
......@@ -1372,25 +1372,25 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
void RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
for (auto phi : block->phis()) {
auto res = phi_map_.insert(
std::make_pair(phi->virtual_register(), PhiMapValue(phi, block)));
int phi_vreg = phi->virtual_register();
auto res =
phi_map_.insert(std::make_pair(phi_vreg, PhiMapValue(phi, block)));
DCHECK(res.second);
USE(res);
auto output = phi->output();
int phi_vreg = phi->virtual_register();
auto& output = phi->output();
if (!FLAG_turbo_delay_ssa_decon) {
for (size_t i = 0; i < phi->operands().size(); ++i) {
InstructionBlock* cur_block =
code()->InstructionBlockAt(block->predecessors()[i]);
AddGapMove(cur_block->last_instruction_index() - 1, GapInstruction::END,
phi->inputs()[i], output);
&phi->inputs()[i], &output);
DCHECK(!InstructionAt(cur_block->last_instruction_index())
->HasPointerMap());
}
}
auto live_range = LiveRangeFor(phi_vreg);
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);
// We use the phi-ness of some nodes in some later heuristics.
live_range->set_is_phi(true);
......@@ -1622,7 +1622,7 @@ void RegisterAllocator::ResolveControlFlow() {
finder.ArrayFor(phi->virtual_register())->FindSucc(block);
auto phi_output =
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;
for (auto pred : block->predecessors()) {
const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
......@@ -1630,7 +1630,7 @@ void RegisterAllocator::ResolveControlFlow() {
->FindPred(pred_block);
auto pred_op =
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);
pred_index++;
}
......
......@@ -608,8 +608,7 @@ class RegisterAllocator FINAL : public ZoneObject {
PhiInstruction* const phi;
const InstructionBlock* const block;
};
typedef std::map<int, PhiMapValue, std::less<int>,
zone_allocator<std::pair<int, PhiMapValue>>> PhiMap;
typedef ZoneMap<int, PhiMapValue> PhiMap;
Zone* const local_zone_;
Frame* const frame_;
......
......@@ -155,20 +155,35 @@ PhiInstruction* InstructionSequenceTest::Phi(VReg incoming_vreg_0,
VReg incoming_vreg_1,
VReg incoming_vreg_2,
VReg incoming_vreg_3) {
auto phi = new (zone()) PhiInstruction(zone(), NewReg().value_, 10);
VReg inputs[] = {incoming_vreg_0, incoming_vreg_1, incoming_vreg_2,
incoming_vreg_3};
for (size_t i = 0; i < arraysize(inputs); ++i) {
if (inputs[i].value_ == kNoValue) break;
Extend(phi, inputs[i]);
size_t input_count = 0;
for (; input_count < arraysize(inputs); ++input_count) {
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);
return phi;
}
void InstructionSequenceTest::Extend(PhiInstruction* phi, VReg vreg) {
phi->Extend(zone(), vreg.value_);
void InstructionSequenceTest::SetInput(PhiInstruction* phi, size_t input,
VReg vreg) {
CHECK(vreg.value_ != kNoValue);
phi->SetInput(input, vreg.value_);
}
......
......@@ -138,7 +138,8 @@ class InstructionSequenceTest : public TestWithIsolateAndZone {
VReg incoming_vreg_1 = VReg(),
VReg incoming_vreg_2 = 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);
int EmitNop();
......
......@@ -42,9 +42,9 @@ TEST_F(RegisterAllocatorTest, SimpleLoop) {
StartLoop(1);
StartBlock();
auto phi = Phi(i_reg);
auto phi = Phi(i_reg, 2);
auto ipp = EmitOI(Same(), Reg(phi), Use(DefineConstant()));
Extend(phi, ipp);
SetInput(phi, 1, ipp);
EndBlock(Jump(0));
EndLoop();
......@@ -206,14 +206,14 @@ TEST_F(RegisterAllocatorTest, RegressionPhisNeedTooManyRegisters) {
StartBlock();
for (size_t i = 0; i < arraysize(parameters); ++i) {
phis[i] = Phi(parameters[i]);
phis[i] = Phi(parameters[i], 2);
}
// Perform some computations.
// something like phi[i] += const
for (size_t i = 0; i < arraysize(parameters); ++i) {
auto result = EmitOI(Same(), Reg(phis[i]), Use(constant));
Extend(phis[i], result);
SetInput(phis[i], 1, result);
}
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