}
+Instruction* GetLastInstruction(InstructionSequence* code,
+ const InstructionBlock* block) {
+ return code->InstructionAt(block->last_instruction_index());
+}
+
} // namespace
}
-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;
}
-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);
}
-void LiveRangeBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
+void ConstraintBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
const InstructionBlock* block) {
int end = block->last_instruction_index();
auto last_instruction = InstructionAt(end);
}
-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++) {
}
-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++) {
}
+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);
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.
}
-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;
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() &&
}
}
- 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.
// 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);
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) {
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);
}
}
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.
// 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;
position = Instruction::START;
} else {
DCHECK(pred->SuccessorCount() == 1);
- DCHECK(!data()
+ DCHECK(!code()
->InstructionAt(pred->last_instruction_index())
->HasReferenceMap());
gap_index = pred->last_instruction_index();
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.
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);
};
-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();
// 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();
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;
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);
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_;
}
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.
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);
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_;