Commit 6a7cb78c authored by dcarney's avatar dcarney Committed by Commit bot

[turbofan] Split ConstraintBuilder off of LiveRangeBuilder.

Plus some driveby cleanup.

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

Cr-Commit-Position: refs/heads/master@{#27961}
parent 636cb4f3
......@@ -716,7 +716,7 @@ struct MeetRegisterConstraintsPhase {
static const char* phase_name() { return "meet register constraints"; }
void Run(PipelineData* data, Zone* temp_zone) {
LiveRangeBuilder builder(data->register_allocation_data());
ConstraintBuilder builder(data->register_allocation_data());
builder.MeetRegisterConstraints();
}
};
......@@ -726,7 +726,7 @@ struct ResolvePhisPhase {
static const char* phase_name() { return "resolve phis"; }
void Run(PipelineData* data, Zone* temp_zone) {
LiveRangeBuilder builder(data->register_allocation_data());
ConstraintBuilder builder(data->register_allocation_data());
builder.ResolvePhis();
}
};
......
......@@ -69,6 +69,11 @@ bool IsBlockBoundary(const InstructionSequence* code, LifetimePosition pos) {
}
Instruction* GetLastInstruction(InstructionSequence* code,
const InstructionBlock* block) {
return code->InstructionAt(block->last_instruction_index());
}
} // namespace
......@@ -833,67 +838,12 @@ void RegisterAllocationData::SetLiveRangeAssignedRegister(LiveRange* range,
}
LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data)
ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data)
: data_(data) {}
BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block) {
// Compute live out for the given block, except not including backward
// successor edges.
auto live_out = new (allocation_zone())
BitVector(code()->VirtualRegisterCount(), allocation_zone());
// Process all successor blocks.
for (auto succ : block->successors()) {
// Add values live on entry to the successor. Note the successor's
// live_in will not be computed yet for backwards edges.
auto live_in = live_in_sets()[succ.ToSize()];
if (live_in != nullptr) live_out->Union(*live_in);
// All phi input operands corresponding to this successor edge are live
// out from this block.
auto successor = code()->InstructionBlockAt(succ);
size_t index = successor->PredecessorIndexOf(block->rpo_number());
DCHECK(index < successor->PredecessorCount());
for (auto phi : successor->phis()) {
live_out->Add(phi->operands()[index]);
}
}
return live_out;
}
void LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
BitVector* live_out) {
// Add an interval that includes the entire block to the live range for
// each live_out value.
auto start = LifetimePosition::GapFromInstructionIndex(
block->first_instruction_index());
auto end = LifetimePosition::InstructionFromInstructionIndex(
block->last_instruction_index()).NextStart();
BitVector::Iterator iterator(live_out);
while (!iterator.Done()) {
int operand_index = iterator.Current();
auto range = LiveRangeFor(operand_index);
range->AddUseInterval(start, end, allocation_zone());
iterator.Advance();
}
}
Instruction* LiveRangeBuilder::GetLastInstruction(
const InstructionBlock* block) {
return code()->InstructionAt(block->last_instruction_index());
}
int LiveRangeBuilder::FixedDoubleLiveRangeID(int index) {
return -index - 1 - config()->num_general_registers();
}
InstructionOperand* LiveRangeBuilder::AllocateFixed(UnallocatedOperand* operand,
int pos, bool is_tagged) {
InstructionOperand* ConstraintBuilder::AllocateFixed(
UnallocatedOperand* operand, int pos, bool is_tagged) {
TRACE("Allocating fixed reg for op %d\n", operand->virtual_register());
DCHECK(operand->HasFixedPolicy());
InstructionOperand allocated;
......@@ -921,87 +871,14 @@ InstructionOperand* LiveRangeBuilder::AllocateFixed(UnallocatedOperand* operand,
}
LiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
DCHECK(index < config()->num_general_registers());
auto result = fixed_live_ranges()[index];
if (result == nullptr) {
result = data()->NewLiveRange(FixedLiveRangeID(index));
DCHECK(result->IsFixed());
result->set_kind(GENERAL_REGISTERS);
data()->SetLiveRangeAssignedRegister(result, index);
fixed_live_ranges()[index] = result;
}
return result;
}
LiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) {
DCHECK(index < config()->num_aliased_double_registers());
auto result = fixed_double_live_ranges()[index];
if (result == nullptr) {
result = data()->NewLiveRange(FixedDoubleLiveRangeID(index));
DCHECK(result->IsFixed());
result->set_kind(DOUBLE_REGISTERS);
data()->SetLiveRangeAssignedRegister(result, index);
fixed_double_live_ranges()[index] = result;
}
return result;
}
LiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
if (operand->IsUnallocated()) {
return LiveRangeFor(UnallocatedOperand::cast(operand)->virtual_register());
} else if (operand->IsConstant()) {
return LiveRangeFor(ConstantOperand::cast(operand)->virtual_register());
} else if (operand->IsRegister()) {
return FixedLiveRangeFor(RegisterOperand::cast(operand)->index());
} else if (operand->IsDoubleRegister()) {
return FixedDoubleLiveRangeFor(
DoubleRegisterOperand::cast(operand)->index());
} else {
return nullptr;
}
}
void LiveRangeBuilder::Define(LifetimePosition position,
InstructionOperand* operand,
InstructionOperand* hint) {
auto range = LiveRangeFor(operand);
if (range == nullptr) return;
if (range->IsEmpty() || range->Start().Value() > position.Value()) {
// Can happen if there is a definition without use.
range->AddUseInterval(position, position.NextStart(), allocation_zone());
range->AddUsePosition(position.NextStart(), nullptr, nullptr,
allocation_zone());
} else {
range->ShortenTo(position);
}
if (operand->IsUnallocated()) {
auto unalloc_operand = UnallocatedOperand::cast(operand);
range->AddUsePosition(position, unalloc_operand, hint, allocation_zone());
}
}
void LiveRangeBuilder::Use(LifetimePosition block_start,
LifetimePosition position,
InstructionOperand* operand,
InstructionOperand* hint) {
auto range = LiveRangeFor(operand);
if (range == nullptr) return;
if (operand->IsUnallocated()) {
UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
range->AddUsePosition(position, unalloc_operand, hint, allocation_zone());
void ConstraintBuilder::MeetRegisterConstraints() {
for (auto block : code()->instruction_blocks()) {
MeetRegisterConstraints(block);
}
range->AddUseInterval(block_start, position, allocation_zone());
}
void LiveRangeBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
void ConstraintBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
int start = block->first_instruction_index();
int end = block->last_instruction_index();
DCHECK_NE(-1, start);
......@@ -1014,7 +891,7 @@ void LiveRangeBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
}
void LiveRangeBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
void ConstraintBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
const InstructionBlock* block) {
int end = block->last_instruction_index();
auto last_instruction = InstructionAt(end);
......@@ -1060,7 +937,7 @@ void LiveRangeBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
}
void LiveRangeBuilder::MeetConstraintsAfter(int instr_index) {
void ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
auto first = InstructionAt(instr_index);
// Handle fixed temporaries.
for (size_t i = 0; i < first->TempCount(); i++) {
......@@ -1108,7 +985,7 @@ void LiveRangeBuilder::MeetConstraintsAfter(int instr_index) {
}
void LiveRangeBuilder::MeetConstraintsBefore(int instr_index) {
void ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
auto second = InstructionAt(instr_index);
// Handle fixed input operands of second instruction.
for (size_t i = 0; i < second->InputCount(); i++) {
......@@ -1153,6 +1030,177 @@ void LiveRangeBuilder::MeetConstraintsBefore(int instr_index) {
}
void ConstraintBuilder::ResolvePhis() {
// Process the blocks in reverse order.
for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
ResolvePhis(block);
}
}
void ConstraintBuilder::ResolvePhis(const InstructionBlock* block) {
for (auto phi : block->phis()) {
int phi_vreg = phi->virtual_register();
auto map_value = new (allocation_zone())
RegisterAllocationData::PhiMapValue(phi, block, allocation_zone());
auto res = data()->phi_map().insert(std::make_pair(phi_vreg, map_value));
DCHECK(res.second);
USE(res);
auto& output = phi->output();
for (size_t i = 0; i < phi->operands().size(); ++i) {
InstructionBlock* cur_block =
code()->InstructionBlockAt(block->predecessors()[i]);
UnallocatedOperand input(UnallocatedOperand::ANY, phi->operands()[i]);
auto move = data()->AddGapMove(cur_block->last_instruction_index(),
Instruction::END, input, output);
map_value->incoming_moves.push_back(move);
DCHECK(!InstructionAt(cur_block->last_instruction_index())
->HasReferenceMap());
}
auto live_range = LiveRangeFor(phi_vreg);
int gap_index = block->first_instruction_index();
live_range->SpillAtDefinition(allocation_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);
live_range->set_is_non_loop_phi(!block->IsLoopHeader());
}
}
LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data)
: data_(data) {}
BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block) {
// Compute live out for the given block, except not including backward
// successor edges.
auto live_out = new (allocation_zone())
BitVector(code()->VirtualRegisterCount(), allocation_zone());
// Process all successor blocks.
for (auto succ : block->successors()) {
// Add values live on entry to the successor. Note the successor's
// live_in will not be computed yet for backwards edges.
auto live_in = live_in_sets()[succ.ToSize()];
if (live_in != nullptr) live_out->Union(*live_in);
// All phi input operands corresponding to this successor edge are live
// out from this block.
auto successor = code()->InstructionBlockAt(succ);
size_t index = successor->PredecessorIndexOf(block->rpo_number());
DCHECK(index < successor->PredecessorCount());
for (auto phi : successor->phis()) {
live_out->Add(phi->operands()[index]);
}
}
return live_out;
}
void LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
BitVector* live_out) {
// Add an interval that includes the entire block to the live range for
// each live_out value.
auto start = LifetimePosition::GapFromInstructionIndex(
block->first_instruction_index());
auto end = LifetimePosition::InstructionFromInstructionIndex(
block->last_instruction_index()).NextStart();
BitVector::Iterator iterator(live_out);
while (!iterator.Done()) {
int operand_index = iterator.Current();
auto range = LiveRangeFor(operand_index);
range->AddUseInterval(start, end, allocation_zone());
iterator.Advance();
}
}
int LiveRangeBuilder::FixedDoubleLiveRangeID(int index) {
return -index - 1 - config()->num_general_registers();
}
LiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
DCHECK(index < config()->num_general_registers());
auto result = data()->fixed_live_ranges()[index];
if (result == nullptr) {
result = data()->NewLiveRange(FixedLiveRangeID(index));
DCHECK(result->IsFixed());
result->set_kind(GENERAL_REGISTERS);
data()->SetLiveRangeAssignedRegister(result, index);
data()->fixed_live_ranges()[index] = result;
}
return result;
}
LiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) {
DCHECK(index < config()->num_aliased_double_registers());
auto result = data()->fixed_double_live_ranges()[index];
if (result == nullptr) {
result = data()->NewLiveRange(FixedDoubleLiveRangeID(index));
DCHECK(result->IsFixed());
result->set_kind(DOUBLE_REGISTERS);
data()->SetLiveRangeAssignedRegister(result, index);
data()->fixed_double_live_ranges()[index] = result;
}
return result;
}
LiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
if (operand->IsUnallocated()) {
return LiveRangeFor(UnallocatedOperand::cast(operand)->virtual_register());
} else if (operand->IsConstant()) {
return LiveRangeFor(ConstantOperand::cast(operand)->virtual_register());
} else if (operand->IsRegister()) {
return FixedLiveRangeFor(RegisterOperand::cast(operand)->index());
} else if (operand->IsDoubleRegister()) {
return FixedDoubleLiveRangeFor(
DoubleRegisterOperand::cast(operand)->index());
} else {
return nullptr;
}
}
void LiveRangeBuilder::Define(LifetimePosition position,
InstructionOperand* operand,
InstructionOperand* hint) {
auto range = LiveRangeFor(operand);
if (range == nullptr) return;
if (range->IsEmpty() || range->Start().Value() > position.Value()) {
// Can happen if there is a definition without use.
range->AddUseInterval(position, position.NextStart(), allocation_zone());
range->AddUsePosition(position.NextStart(), nullptr, nullptr,
allocation_zone());
} else {
range->ShortenTo(position);
}
if (operand->IsUnallocated()) {
auto unalloc_operand = UnallocatedOperand::cast(operand);
range->AddUsePosition(position, unalloc_operand, hint, allocation_zone());
}
}
void LiveRangeBuilder::Use(LifetimePosition block_start,
LifetimePosition position,
InstructionOperand* operand,
InstructionOperand* hint) {
auto range = LiveRangeFor(operand);
if (range == nullptr) return;
if (operand->IsUnallocated()) {
UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
range->AddUsePosition(position, unalloc_operand, hint, allocation_zone());
}
range->AddUseInterval(block_start, position, allocation_zone());
}
bool LiveRangeBuilder::IsOutputRegisterOf(Instruction* instr, int index) {
for (size_t i = 0; i < instr->OutputCount(); i++) {
auto output = instr->OutputAt(i);
......@@ -1184,7 +1232,7 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
index--) {
auto curr_position =
LifetimePosition::InstructionFromInstructionIndex(index);
auto instr = InstructionAt(index);
auto instr = code()->InstructionAt(index);
DCHECK(instr != nullptr);
DCHECK(curr_position.IsInstructionPosition());
// Process output, inputs, and temps of this instruction.
......@@ -1308,51 +1356,6 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
}
void LiveRangeBuilder::ResolvePhis(const InstructionBlock* block) {
for (auto phi : block->phis()) {
int phi_vreg = phi->virtual_register();
auto map_value = new (allocation_zone())
RegisterAllocationData::PhiMapValue(phi, block, allocation_zone());
auto res = phi_map().insert(std::make_pair(phi_vreg, map_value));
DCHECK(res.second);
USE(res);
auto& output = phi->output();
for (size_t i = 0; i < phi->operands().size(); ++i) {
InstructionBlock* cur_block =
code()->InstructionBlockAt(block->predecessors()[i]);
UnallocatedOperand input(UnallocatedOperand::ANY, phi->operands()[i]);
auto move = data()->AddGapMove(cur_block->last_instruction_index(),
Instruction::END, input, output);
map_value->incoming_moves.push_back(move);
DCHECK(!InstructionAt(cur_block->last_instruction_index())
->HasReferenceMap());
}
auto live_range = LiveRangeFor(phi_vreg);
int gap_index = block->first_instruction_index();
live_range->SpillAtDefinition(allocation_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);
live_range->set_is_non_loop_phi(!block->IsLoopHeader());
}
}
void LiveRangeBuilder::MeetRegisterConstraints() {
for (auto block : code()->instruction_blocks()) {
MeetRegisterConstraints(block);
}
}
void LiveRangeBuilder::ResolvePhis() {
// Process the blocks in reverse order.
for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
ResolvePhis(block);
}
}
void LiveRangeBuilder::BuildLiveRanges() {
// Process the blocks in reverse order.
for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
......@@ -1374,7 +1377,7 @@ void LiveRangeBuilder::BuildLiveRanges() {
live->Remove(phi_vreg);
InstructionOperand* hint = nullptr;
auto instr = GetLastInstruction(
code()->InstructionBlockAt(block->predecessors()[0]));
code(), code()->InstructionBlockAt(block->predecessors()[0]));
for (auto move : *instr->GetParallelMove(Instruction::END)) {
auto& to = move->destination();
if (to.IsUnallocated() &&
......@@ -1415,7 +1418,7 @@ void LiveRangeBuilder::BuildLiveRanges() {
}
}
for (auto range : live_ranges()) {
for (auto range : data()->live_ranges()) {
if (range == nullptr) continue;
range->set_kind(RequiredRegisterKind(range->id()));
// Give slots to all ranges with a non fixed slot use.
......@@ -1474,14 +1477,16 @@ LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
// TryAllocateFreeReg and AllocateBlockedReg assume this
// when allocating local arrays.
DCHECK(RegisterConfiguration::kMaxDoubleRegisters >=
config()->num_general_registers());
this->data()->config()->num_general_registers());
}
void LinearScanAllocator::AllocateRegisters() {
DCHECK(unhandled_live_ranges().empty());
DCHECK(active_live_ranges().empty());
DCHECK(inactive_live_ranges().empty());
for (auto range : live_ranges()) {
for (auto range : data()->live_ranges()) {
if (range == nullptr) continue;
if (range->Kind() == mode_) {
AddToUnhandledUnsorted(range);
......@@ -1490,9 +1495,6 @@ void LinearScanAllocator::AllocateRegisters() {
SortUnhandled();
DCHECK(UnhandledIsSorted());
DCHECK(active_live_ranges().empty());
DCHECK(inactive_live_ranges().empty());
auto& fixed_ranges = GetFixedRegisters(data(), mode_);
for (auto current : fixed_ranges) {
if (current != nullptr) {
......@@ -1565,17 +1567,14 @@ void LinearScanAllocator::AllocateRegisters() {
AddToActive(current);
}
}
active_live_ranges().clear();
inactive_live_ranges().clear();
}
const char* LinearScanAllocator::RegisterName(int allocation_index) const {
if (mode_ == GENERAL_REGISTERS) {
return config()->general_register_name(allocation_index);
return data()->config()->general_register_name(allocation_index);
} else {
return config()->double_register_name(allocation_index);
return data()->config()->double_register_name(allocation_index);
}
}
......@@ -1910,8 +1909,8 @@ bool LinearScanAllocator::TryReuseSpillForPhi(LiveRange* range) {
if (range->IsChild() || !range->is_phi()) return false;
DCHECK(!range->HasSpillOperand());
auto lookup = phi_map().find(range->id());
DCHECK(lookup != phi_map().end());
auto lookup = data()->phi_map().find(range->id());
DCHECK(lookup != data()->phi_map().end());
auto phi = lookup->second->phi;
auto block = lookup->second->block;
// Count the number of spilled operands.
......@@ -2190,7 +2189,7 @@ void ReferenceMapPopulator::PopulateReferenceMaps() {
// Iterate over the first parts of multi-part live ranges.
if (range->IsChild()) continue;
// Skip non-reference values.
if (!IsReference(range->id())) continue;
if (!data()->IsReference(range->id())) continue;
// Skip empty live ranges.
if (range->IsEmpty()) continue;
......@@ -2444,7 +2443,7 @@ void LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block,
position = Instruction::START;
} else {
DCHECK(pred->SuccessorCount() == 1);
DCHECK(!data()
DCHECK(!code()
->InstructionAt(pred->last_instruction_index())
->HasReferenceMap());
gap_index = pred->last_instruction_index();
......
......@@ -444,10 +444,8 @@ class RegisterAllocationData final : public ZoneObject {
const ZoneVector<LiveRange*>& fixed_double_live_ranges() const {
return fixed_double_live_ranges_;
}
const ZoneVector<BitVector*>& live_in_sets() const { return live_in_sets_; }
ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; }
ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
const ZoneVector<SpillRange*>& spill_ranges() const { return spill_ranges_; }
InstructionSequence* code() const { return code_; }
// This zone is for datastructures only needed during register allocation
// phases.
......@@ -463,9 +461,6 @@ class RegisterAllocationData final : public ZoneObject {
void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
LiveRange* LiveRangeFor(int index);
Instruction* InstructionAt(int index) const {
return code()->InstructionAt(index);
}
void AssignPhiInput(LiveRange* range, const InstructionOperand& assignment);
SpillRange* AssignSpillRangeToLiveRange(LiveRange* range);
......@@ -502,9 +497,9 @@ class RegisterAllocationData final : public ZoneObject {
};
class LiveRangeBuilder final : public ZoneObject {
class ConstraintBuilder final : public ZoneObject {
public:
explicit LiveRangeBuilder(RegisterAllocationData* data);
explicit ConstraintBuilder(RegisterAllocationData* data);
// Phase 1 : insert moves to account for fixed register operands.
void MeetRegisterConstraints();
......@@ -513,6 +508,36 @@ class LiveRangeBuilder final : public ZoneObject {
// of blocks containing phis.
void ResolvePhis();
private:
RegisterAllocationData* data() const { return data_; }
InstructionSequence* code() const { return data()->code(); }
Zone* allocation_zone() const { return data()->allocation_zone(); }
Instruction* InstructionAt(int index) { return code()->InstructionAt(index); }
bool IsReference(int virtual_register) const {
return data()->IsReference(virtual_register);
}
LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); }
InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos,
bool is_tagged);
void MeetRegisterConstraints(const InstructionBlock* block);
void MeetConstraintsBefore(int index);
void MeetConstraintsAfter(int index);
void MeetRegisterConstraintsForLastInstructionInBlock(
const InstructionBlock* block);
void ResolvePhis(const InstructionBlock* block);
RegisterAllocationData* const data_;
DISALLOW_COPY_AND_ASSIGN(ConstraintBuilder);
};
class LiveRangeBuilder final : public ZoneObject {
public:
explicit LiveRangeBuilder(RegisterAllocationData* data);
// Phase 3: compute liveness of all virtual register.
void BuildLiveRanges();
......@@ -525,20 +550,8 @@ class LiveRangeBuilder final : public ZoneObject {
ZoneVector<BitVector*>& live_in_sets() const {
return data()->live_in_sets();
}
ZoneVector<LiveRange*>& live_ranges() { return data()->live_ranges(); }
ZoneVector<LiveRange*>& fixed_live_ranges() {
return data()->fixed_live_ranges();
}
ZoneVector<LiveRange*>& fixed_double_live_ranges() {
return data()->fixed_double_live_ranges();
}
ZoneVector<SpillRange*>& spill_ranges() { return data()->spill_ranges(); }
RegisterAllocationData::PhiMap& phi_map() { return data()->phi_map(); }
Instruction* InstructionAt(int index) { return code()->InstructionAt(index); }
bool IsReference(int virtual_register) const {
return data()->IsReference(virtual_register);
}
LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); }
void Verify() const;
......@@ -548,26 +561,16 @@ class LiveRangeBuilder final : public ZoneObject {
bool IsOutputRegisterOf(Instruction* instr, int index);
bool IsOutputDoubleRegisterOf(Instruction* instr, int index);
void ProcessInstructions(const InstructionBlock* block, BitVector* live);
void MeetRegisterConstraints(const InstructionBlock* block);
void MeetConstraintsBefore(int index);
void MeetConstraintsAfter(int index);
void MeetRegisterConstraintsForLastInstructionInBlock(
const InstructionBlock* block);
void ResolvePhis(const InstructionBlock* block);
LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); }
static int FixedLiveRangeID(int index) { return -index - 1; }
int FixedDoubleLiveRangeID(int index);
LiveRange* FixedLiveRangeFor(int index);
LiveRange* FixedDoubleLiveRangeFor(int index);
Instruction* GetLastInstruction(const InstructionBlock* block);
// Returns the register kind required by the given virtual register.
RegisterKind RequiredRegisterKind(int virtual_register) const;
// Helper methods for building intervals.
InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos,
bool is_tagged);
LiveRange* LiveRangeFor(InstructionOperand* operand);
void Define(LifetimePosition position, InstructionOperand* operand,
InstructionOperand* hint);
......@@ -592,12 +595,9 @@ class LinearScanAllocator final : public ZoneObject {
RegisterAllocationData* data() const { return data_; }
InstructionSequence* code() const { return data()->code(); }
Zone* allocation_zone() const { return data()->allocation_zone(); }
Zone* code_zone() const { return code()->zone(); }
const RegisterConfiguration* config() const { return data()->config(); }
int num_registers() const { return num_registers_; }
const char* RegisterName(int allocation_index) const;
ZoneVector<LiveRange*>& live_ranges() { return data()->live_ranges(); }
ZoneVector<LiveRange*>& unhandled_live_ranges() {
return unhandled_live_ranges_;
}
......@@ -605,13 +605,7 @@ class LinearScanAllocator final : public ZoneObject {
ZoneVector<LiveRange*>& inactive_live_ranges() {
return inactive_live_ranges_;
}
ZoneVector<SpillRange*>& spill_ranges() { return data()->spill_ranges(); }
RegisterAllocationData::PhiMap& phi_map() { return data()->phi_map(); }
Instruction* InstructionAt(int index) { return code()->InstructionAt(index); }
bool IsReference(int virtual_register) const {
return data()->IsReference(virtual_register);
}
LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); }
// Helper methods for updating the life range lists.
......@@ -715,14 +709,10 @@ class ReferenceMapPopulator final : public ZoneObject {
void PopulateReferenceMaps();
private:
bool SafePointsAreInOrder() const;
bool IsReference(int virtual_register) const {
return data()->IsReference(virtual_register);
}
RegisterAllocationData* data() const { return data_; }
bool SafePointsAreInOrder() const;
RegisterAllocationData* const data_;
DISALLOW_COPY_AND_ASSIGN(ReferenceMapPopulator);
......@@ -740,14 +730,15 @@ class LiveRangeConnector final : public ZoneObject {
void ResolveControlFlow(Zone* local_zone);
private:
RegisterAllocationData* data() const { return data_; }
InstructionSequence* code() const { return data()->code(); }
Zone* code_zone() const { return code()->zone(); }
bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const;
void ResolveControlFlow(const InstructionBlock* block,
const InstructionOperand& cur_op,
const InstructionBlock* pred,
const InstructionOperand& pred_op);
InstructionSequence* code() const { return data()->code(); }
Zone* code_zone() const { return code()->zone(); }
RegisterAllocationData* data() const { return data_; }
RegisterAllocationData* const data_;
......
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