Commit e9a37bf8 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[TurboProp] Add reference map population to fast reg alloc.

Adds support for populating reference maps to the fast
register allocator. In order to calculate whether a stack slot
is live at a given instruction, we use the dominator tree to
build a bitmap of blocks which are dominated by each block.
A variable's spill operand is classed as alive for any blocks that are
dominated by the block it was defined in, until the instruction index
of the spill operand's last use. As such, it may be classified as live
down a branch where the spill operand is never used, however it is safe
since the spill slot won't be re-allocated until after it's last-use
instruction index in any case.

BUG=v8:9684

Change-Id: I772374599ef916f57d82d468f66429e32c712ddf
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2298008
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69108}
parent 5b0c6cde
...@@ -583,7 +583,8 @@ void PhiInstruction::RenameInput(size_t offset, int virtual_register) { ...@@ -583,7 +583,8 @@ void PhiInstruction::RenameInput(size_t offset, int virtual_register) {
InstructionBlock::InstructionBlock(Zone* zone, RpoNumber rpo_number, InstructionBlock::InstructionBlock(Zone* zone, RpoNumber rpo_number,
RpoNumber loop_header, RpoNumber loop_end, RpoNumber loop_header, RpoNumber loop_end,
bool deferred, bool handler) RpoNumber dominator, bool deferred,
bool handler)
: successors_(zone), : successors_(zone),
predecessors_(zone), predecessors_(zone),
phis_(zone), phis_(zone),
...@@ -591,6 +592,7 @@ InstructionBlock::InstructionBlock(Zone* zone, RpoNumber rpo_number, ...@@ -591,6 +592,7 @@ InstructionBlock::InstructionBlock(Zone* zone, RpoNumber rpo_number,
rpo_number_(rpo_number), rpo_number_(rpo_number),
loop_header_(loop_header), loop_header_(loop_header),
loop_end_(loop_end), loop_end_(loop_end),
dominator_(dominator),
deferred_(deferred), deferred_(deferred),
handler_(handler) {} handler_(handler) {}
...@@ -619,7 +621,7 @@ static InstructionBlock* InstructionBlockFor(Zone* zone, ...@@ -619,7 +621,7 @@ static InstructionBlock* InstructionBlockFor(Zone* zone,
!block->empty() && block->front()->opcode() == IrOpcode::kIfException; !block->empty() && block->front()->opcode() == IrOpcode::kIfException;
InstructionBlock* instr_block = zone->New<InstructionBlock>( InstructionBlock* instr_block = zone->New<InstructionBlock>(
zone, GetRpo(block), GetRpo(block->loop_header()), GetLoopEndRpo(block), zone, GetRpo(block), GetRpo(block->loop_header()), GetLoopEndRpo(block),
block->deferred(), is_handler); GetRpo(block->dominator()), block->deferred(), is_handler);
// Map successors and precessors // Map successors and precessors
instr_block->successors().reserve(block->SuccessorCount()); instr_block->successors().reserve(block->SuccessorCount());
for (BasicBlock* successor : block->successors()) { for (BasicBlock* successor : block->successors()) {
......
...@@ -1025,7 +1025,7 @@ class RpoNumber final { ...@@ -1025,7 +1025,7 @@ class RpoNumber final {
int32_t index_; int32_t index_;
}; };
std::ostream& operator<<(std::ostream&, const RpoNumber&); V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, const RpoNumber&);
class V8_EXPORT_PRIVATE Constant final { class V8_EXPORT_PRIVATE Constant final {
public: public:
...@@ -1388,7 +1388,8 @@ class V8_EXPORT_PRIVATE InstructionBlock final ...@@ -1388,7 +1388,8 @@ class V8_EXPORT_PRIVATE InstructionBlock final
: public NON_EXPORTED_BASE(ZoneObject) { : public NON_EXPORTED_BASE(ZoneObject) {
public: public:
InstructionBlock(Zone* zone, RpoNumber rpo_number, RpoNumber loop_header, InstructionBlock(Zone* zone, RpoNumber rpo_number, RpoNumber loop_header,
RpoNumber loop_end, bool deferred, bool handler); RpoNumber loop_end, RpoNumber dominator, bool deferred,
bool handler);
// Instruction indexes (used by the register allocator). // Instruction indexes (used by the register allocator).
int first_instruction_index() const { int first_instruction_index() const {
...@@ -1437,6 +1438,9 @@ class V8_EXPORT_PRIVATE InstructionBlock final ...@@ -1437,6 +1438,9 @@ class V8_EXPORT_PRIVATE InstructionBlock final
const Successors& successors() const { return successors_; } const Successors& successors() const { return successors_; }
size_t SuccessorCount() const { return successors_.size(); } size_t SuccessorCount() const { return successors_.size(); }
RpoNumber dominator() const { return dominator_; }
void set_dominator(RpoNumber dominator) { dominator_ = dominator; }
using PhiInstructions = ZoneVector<PhiInstruction*>; using PhiInstructions = ZoneVector<PhiInstruction*>;
const PhiInstructions& phis() const { return phis_; } const PhiInstructions& phis() const { return phis_; }
PhiInstruction* PhiAt(size_t i) const { return phis_[i]; } PhiInstruction* PhiAt(size_t i) const { return phis_[i]; }
...@@ -1465,6 +1469,7 @@ class V8_EXPORT_PRIVATE InstructionBlock final ...@@ -1465,6 +1469,7 @@ class V8_EXPORT_PRIVATE InstructionBlock final
const RpoNumber rpo_number_; const RpoNumber rpo_number_;
const RpoNumber loop_header_; const RpoNumber loop_header_;
const RpoNumber loop_end_; const RpoNumber loop_end_;
RpoNumber dominator_;
int32_t code_start_; // start index of arch-specific code. int32_t code_start_; // start index of arch-specific code.
int32_t code_end_ = -1; // end index of arch-specific code. int32_t code_end_ = -1; // end index of arch-specific code.
const bool deferred_; // Block contains deferred code. const bool deferred_; // Block contains deferred code.
......
...@@ -24,6 +24,20 @@ namespace compiler { ...@@ -24,6 +24,20 @@ namespace compiler {
class RegisterState; class RegisterState;
// BlockState stores details associated with a particular basic block.
class BlockState final {
public:
BlockState(int block_count, Zone* zone)
: dominated_blocks_(block_count, zone) {}
// Returns a bitvector representing all the basic blocks that are dominated
// by this basic block.
BitVector* dominated_blocks() { return &dominated_blocks_; }
private:
BitVector dominated_blocks_;
};
MidTierRegisterAllocationData::MidTierRegisterAllocationData( MidTierRegisterAllocationData::MidTierRegisterAllocationData(
const RegisterConfiguration* config, Zone* zone, Frame* frame, const RegisterConfiguration* config, Zone* zone, Frame* frame,
InstructionSequence* code, TickCounter* tick_counter, InstructionSequence* code, TickCounter* tick_counter,
...@@ -35,10 +49,17 @@ MidTierRegisterAllocationData::MidTierRegisterAllocationData( ...@@ -35,10 +49,17 @@ MidTierRegisterAllocationData::MidTierRegisterAllocationData(
debug_name_(debug_name), debug_name_(debug_name),
config_(config), config_(config),
virtual_register_data_(code->VirtualRegisterCount(), allocation_zone()), virtual_register_data_(code->VirtualRegisterCount(), allocation_zone()),
block_states_(allocation_zone()),
reference_map_instructions_(allocation_zone()), reference_map_instructions_(allocation_zone()),
spilled_virtual_registers_(code->VirtualRegisterCount(), spilled_virtual_registers_(code->VirtualRegisterCount(),
allocation_zone()), allocation_zone()),
tick_counter_(tick_counter) {} tick_counter_(tick_counter) {
int basic_block_count = code->InstructionBlockCount();
block_states_.reserve(basic_block_count);
for (int i = 0; i < basic_block_count; i++) {
block_states_.emplace_back(basic_block_count, allocation_zone());
}
}
MoveOperands* MidTierRegisterAllocationData::AddGapMove( MoveOperands* MidTierRegisterAllocationData::AddGapMove(
int instr_index, Instruction::GapPosition position, int instr_index, Instruction::GapPosition position,
...@@ -63,6 +84,10 @@ MachineRepresentation MidTierRegisterAllocationData::RepresentationFor( ...@@ -63,6 +84,10 @@ MachineRepresentation MidTierRegisterAllocationData::RepresentationFor(
} }
} }
BlockState& MidTierRegisterAllocationData::block_state(RpoNumber rpo_number) {
return block_states_[rpo_number.ToInt()];
}
const InstructionBlock* MidTierRegisterAllocationData::GetBlock( const InstructionBlock* MidTierRegisterAllocationData::GetBlock(
RpoNumber rpo_number) { RpoNumber rpo_number) {
return code()->InstructionBlockAt(rpo_number); return code()->InstructionBlockAt(rpo_number);
...@@ -73,6 +98,12 @@ const InstructionBlock* MidTierRegisterAllocationData::GetBlock( ...@@ -73,6 +98,12 @@ const InstructionBlock* MidTierRegisterAllocationData::GetBlock(
return code()->InstructionAt(instr_index)->block(); return code()->InstructionAt(instr_index)->block();
} }
const BitVector* MidTierRegisterAllocationData::GetBlocksDominatedBy(
int instr_index) {
const InstructionBlock* block = GetBlock(instr_index);
return block_state(block->rpo_number()).dominated_blocks();
}
// RegisterIndex represents a particular register of a given kind (depending // RegisterIndex represents a particular register of a given kind (depending
// on the RegisterKind of the allocator). // on the RegisterKind of the allocator).
class RegisterIndex final { class RegisterIndex final {
...@@ -204,13 +235,16 @@ class VirtualRegisterData final { ...@@ -204,13 +235,16 @@ class VirtualRegisterData final {
public: public:
// Defines a spill range for an output operand. // Defines a spill range for an output operand.
SpillRange(int definition_instr_index, MidTierRegisterAllocationData* data) SpillRange(int definition_instr_index, MidTierRegisterAllocationData* data)
: live_range_(definition_instr_index, definition_instr_index) {} : live_range_(definition_instr_index, definition_instr_index),
live_blocks_(data->GetBlocksDominatedBy(definition_instr_index)) {}
// Defines a spill range for a Phi variable. // Defines a spill range for a Phi variable.
SpillRange(const InstructionBlock* phi_block, SpillRange(const InstructionBlock* phi_block,
MidTierRegisterAllocationData* data) MidTierRegisterAllocationData* data)
: live_range_(phi_block->first_instruction_index(), : live_range_(phi_block->first_instruction_index(),
phi_block->first_instruction_index()) { phi_block->first_instruction_index()),
live_blocks_(data->GetBlocksDominatedBy(
phi_block->first_instruction_index())) {
// For phis, add the gap move instructions in the predecssor blocks to // For phis, add the gap move instructions in the predecssor blocks to
// the live range. // the live range.
for (RpoNumber pred_rpo : phi_block->predecessors()) { for (RpoNumber pred_rpo : phi_block->predecessors()) {
...@@ -220,8 +254,8 @@ class VirtualRegisterData final { ...@@ -220,8 +254,8 @@ class VirtualRegisterData final {
} }
bool IsLiveAt(int instr_index, InstructionBlock* block) { bool IsLiveAt(int instr_index, InstructionBlock* block) {
// TODO(rmcilroy): Only include basic blocks dominated by the variable. return live_range_.Contains(instr_index) &&
return live_range_.Contains(instr_index); live_blocks_->Contains(block->rpo_number().ToInt());
} }
void ExtendRangeTo(int instr_index) { live_range_.AddInstr(instr_index); } void ExtendRangeTo(int instr_index) { live_range_.AddInstr(instr_index); }
...@@ -230,6 +264,7 @@ class VirtualRegisterData final { ...@@ -230,6 +264,7 @@ class VirtualRegisterData final {
private: private:
Range live_range_; Range live_range_;
const BitVector* live_blocks_;
DISALLOW_COPY_AND_ASSIGN(SpillRange); DISALLOW_COPY_AND_ASSIGN(SpillRange);
}; };
...@@ -1458,10 +1493,28 @@ void MidTierRegisterAllocator::DefineOutputs() { ...@@ -1458,10 +1493,28 @@ void MidTierRegisterAllocator::DefineOutputs() {
base::Reversed(code()->instruction_blocks())) { base::Reversed(code()->instruction_blocks())) {
data_->tick_counter()->DoTick(); data_->tick_counter()->DoTick();
InitializeBlockState(block);
DefineOutputs(block); DefineOutputs(block);
} }
} }
void MidTierRegisterAllocator::InitializeBlockState(
const InstructionBlock* block) {
// Mark this block as dominating itself.
BlockState& block_state = data()->block_state(block->rpo_number());
block_state.dominated_blocks()->Add(block->rpo_number().ToInt());
if (block->dominator().IsValid()) {
// Add all the blocks this block dominates to its dominator.
BlockState& dominator_block_state = data()->block_state(block->dominator());
dominator_block_state.dominated_blocks()->Union(
*block_state.dominated_blocks());
} else {
// Only the first block shouldn't have a dominator.
DCHECK_EQ(block, code()->instruction_blocks().front());
}
}
void MidTierRegisterAllocator::DefineOutputs(const InstructionBlock* block) { void MidTierRegisterAllocator::DefineOutputs(const InstructionBlock* block) {
int block_start = block->first_instruction_index(); int block_start = block->first_instruction_index();
for (int index = block->last_instruction_index(); index >= block_start; for (int index = block->last_instruction_index(); index >= block_start;
...@@ -1707,6 +1760,36 @@ void MidTierRegisterAllocator::UpdateSpillRangesForLoops() { ...@@ -1707,6 +1760,36 @@ void MidTierRegisterAllocator::UpdateSpillRangesForLoops() {
} }
} }
// Spill slot allocator for mid-tier register allocation.
class MidTierSpillSlotAllocator final {
public:
explicit MidTierSpillSlotAllocator(MidTierRegisterAllocationData* data);
void Allocate(VirtualRegisterData* virtual_register);
private:
class SpillSlot;
void AdvanceTo(int instr_index);
SpillSlot* GetFreeSpillSlot(int byte_width);
MidTierRegisterAllocationData* data() const { return data_; }
InstructionSequence* code() const { return data()->code(); }
Frame* frame() const { return data()->frame(); }
Zone* zone() const { return data()->allocation_zone(); }
struct OrderByLastUse {
bool operator()(const SpillSlot* a, const SpillSlot* b) const;
};
MidTierRegisterAllocationData* data_;
ZonePriorityQueue<SpillSlot*, OrderByLastUse> allocated_slots_;
ZoneLinkedList<SpillSlot*> free_slots_;
int position_;
DISALLOW_COPY_AND_ASSIGN(MidTierSpillSlotAllocator);
};
class MidTierSpillSlotAllocator::SpillSlot : public ZoneObject { class MidTierSpillSlotAllocator::SpillSlot : public ZoneObject {
public: public:
SpillSlot(int stack_slot, int byte_width) SpillSlot(int stack_slot, int byte_width)
...@@ -1791,12 +1874,12 @@ void MidTierSpillSlotAllocator::Allocate( ...@@ -1791,12 +1874,12 @@ void MidTierSpillSlotAllocator::Allocate(
allocated_slots_.push(slot); allocated_slots_.push(slot);
} }
void MidTierSpillSlotAllocator::AllocateSpillSlots() { void AllocateSpillSlots(MidTierRegisterAllocationData* data) {
ZoneVector<VirtualRegisterData*> spilled(zone()); ZoneVector<VirtualRegisterData*> spilled(data->allocation_zone());
BitVector::Iterator iterator(&data()->spilled_virtual_registers()); BitVector::Iterator iterator(&data->spilled_virtual_registers());
for (; !iterator.Done(); iterator.Advance()) { for (; !iterator.Done(); iterator.Advance()) {
VirtualRegisterData& vreg_data = VirtualRegisterData& vreg_data =
data()->VirtualRegisterDataFor(iterator.Current()); data->VirtualRegisterDataFor(iterator.Current());
if (vreg_data.HasPendingSpillOperand()) { if (vreg_data.HasPendingSpillOperand()) {
spilled.push_back(&vreg_data); spilled.push_back(&vreg_data);
} }
...@@ -1811,8 +1894,59 @@ void MidTierSpillSlotAllocator::AllocateSpillSlots() { ...@@ -1811,8 +1894,59 @@ void MidTierSpillSlotAllocator::AllocateSpillSlots() {
}); });
// Allocate a spill slot for each virtual register with a spill range. // Allocate a spill slot for each virtual register with a spill range.
MidTierSpillSlotAllocator allocator(data);
for (VirtualRegisterData* spill : spilled) { for (VirtualRegisterData* spill : spilled) {
Allocate(spill); allocator.Allocate(spill);
}
}
// Populates reference maps for mid-tier register allocation.
class MidTierReferenceMapPopulator final {
public:
explicit MidTierReferenceMapPopulator(MidTierRegisterAllocationData* data);
void RecordReferences(const VirtualRegisterData& virtual_register);
private:
MidTierRegisterAllocationData* data() const { return data_; }
InstructionSequence* code() const { return data()->code(); }
MidTierRegisterAllocationData* data_;
DISALLOW_COPY_AND_ASSIGN(MidTierReferenceMapPopulator);
};
MidTierReferenceMapPopulator::MidTierReferenceMapPopulator(
MidTierRegisterAllocationData* data)
: data_(data) {}
void MidTierReferenceMapPopulator::RecordReferences(
const VirtualRegisterData& virtual_register) {
if (!virtual_register.HasAllocatedSpillOperand()) return;
if (!code()->IsReference(virtual_register.vreg())) return;
VirtualRegisterData::SpillRange* spill_range = virtual_register.spill_range();
Range& live_range = spill_range->live_range();
AllocatedOperand allocated =
*AllocatedOperand::cast(virtual_register.spill_operand());
for (int instr_index : data()->reference_map_instructions()) {
if (instr_index > live_range.end() || instr_index < live_range.start())
continue;
Instruction* instr = data()->code()->InstructionAt(instr_index);
DCHECK(instr->HasReferenceMap());
if (spill_range->IsLiveAt(instr_index, instr->block())) {
instr->reference_map()->RecordReference(allocated);
}
}
}
void PopulateReferenceMaps(MidTierRegisterAllocationData* data) {
MidTierReferenceMapPopulator populator(data);
BitVector::Iterator iterator(&data->spilled_virtual_registers());
for (; !iterator.Done(); iterator.Advance()) {
populator.RecordReferences(
data->VirtualRegisterDataFor(iterator.Current()));
} }
} }
......
...@@ -21,6 +21,7 @@ class TickCounter; ...@@ -21,6 +21,7 @@ class TickCounter;
namespace compiler { namespace compiler {
class BlockState;
class SinglePassRegisterAllocator; class SinglePassRegisterAllocator;
class VirtualRegisterData; class VirtualRegisterData;
...@@ -56,6 +57,10 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData { ...@@ -56,6 +57,10 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData {
const InstructionBlock* GetBlock(const RpoNumber rpo_number); const InstructionBlock* GetBlock(const RpoNumber rpo_number);
const InstructionBlock* GetBlock(int instr_index); const InstructionBlock* GetBlock(int instr_index);
// Returns a bitvector representing all the blocks that are dominated by the
// output of the instruction at |instr_index|.
const BitVector* GetBlocksDominatedBy(int instr_index);
// List of all instruction indexs that require a reference map. // List of all instruction indexs that require a reference map.
ZoneVector<int>& reference_map_instructions() { ZoneVector<int>& reference_map_instructions() {
return reference_map_instructions_; return reference_map_instructions_;
...@@ -72,6 +77,8 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData { ...@@ -72,6 +77,8 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData {
// allocation. // allocation.
Zone* code_zone() const { return code()->zone(); } Zone* code_zone() const { return code()->zone(); }
BlockState& block_state(RpoNumber rpo_number);
InstructionSequence* code() const { return code_; } InstructionSequence* code() const { return code_; }
Frame* frame() const { return frame_; } Frame* frame() const { return frame_; }
const char* debug_name() const { return debug_name_; } const char* debug_name() const { return debug_name_; }
...@@ -86,6 +93,7 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData { ...@@ -86,6 +93,7 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData {
const RegisterConfiguration* const config_; const RegisterConfiguration* const config_;
ZoneVector<VirtualRegisterData> virtual_register_data_; ZoneVector<VirtualRegisterData> virtual_register_data_;
ZoneVector<BlockState> block_states_;
ZoneVector<int> reference_map_instructions_; ZoneVector<int> reference_map_instructions_;
BitVector spilled_virtual_registers_; BitVector spilled_virtual_registers_;
...@@ -146,38 +154,11 @@ class MidTierRegisterAllocator final { ...@@ -146,38 +154,11 @@ class MidTierRegisterAllocator final {
DISALLOW_COPY_AND_ASSIGN(MidTierRegisterAllocator); DISALLOW_COPY_AND_ASSIGN(MidTierRegisterAllocator);
}; };
// Spill slot allocator for mid-tier register allocation. // Phase 3: assign spilled operands to specific spill slots.
class MidTierSpillSlotAllocator final { void AllocateSpillSlots(MidTierRegisterAllocationData* data);
public:
explicit MidTierSpillSlotAllocator(MidTierRegisterAllocationData* data);
// Phase 3: assign spilled operands to specific spill slots.
void AllocateSpillSlots();
private:
class SpillSlot;
void Allocate(VirtualRegisterData* virtual_register);
void AdvanceTo(int instr_index);
SpillSlot* GetFreeSpillSlot(int byte_width);
MidTierRegisterAllocationData* data() const { return data_; } // Phase 4: Populate reference maps for spilled references.
InstructionSequence* code() const { return data()->code(); } void PopulateReferenceMaps(MidTierRegisterAllocationData* data);
Frame* frame() const { return data()->frame(); }
Zone* zone() const { return data()->allocation_zone(); }
struct OrderByLastUse {
bool operator()(const SpillSlot* a, const SpillSlot* b) const;
};
MidTierRegisterAllocationData* data_;
ZonePriorityQueue<SpillSlot*, OrderByLastUse> allocated_slots_;
ZoneLinkedList<SpillSlot*> free_slots_;
int position_;
DISALLOW_COPY_AND_ASSIGN(MidTierSpillSlotAllocator);
};
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
......
...@@ -1957,7 +1957,7 @@ struct ScheduledMachineLoweringPhase { ...@@ -1957,7 +1957,7 @@ struct ScheduledMachineLoweringPhase {
// TODO(rmcilroy) Avoid having to rebuild rpo_order on schedule each time. // TODO(rmcilroy) Avoid having to rebuild rpo_order on schedule each time.
Scheduler::ComputeSpecialRPO(temp_zone, data->schedule()); Scheduler::ComputeSpecialRPO(temp_zone, data->schedule());
if (FLAG_turbo_verify) Scheduler::GenerateDominatorTree(data->schedule()); Scheduler::GenerateDominatorTree(data->schedule());
TraceScheduleAndVerify(data->info(), data, data->schedule(), TraceScheduleAndVerify(data->info(), data, data->schedule(),
"machine lowered schedule"); "machine lowered schedule");
} }
...@@ -2295,9 +2295,15 @@ struct MidTierSpillSlotAllocatorPhase { ...@@ -2295,9 +2295,15 @@ struct MidTierSpillSlotAllocatorPhase {
DECL_PIPELINE_PHASE_CONSTANTS(MidTierSpillSlotAllocator) DECL_PIPELINE_PHASE_CONSTANTS(MidTierSpillSlotAllocator)
void Run(PipelineData* data, Zone* temp_zone) { void Run(PipelineData* data, Zone* temp_zone) {
MidTierSpillSlotAllocator spill_allocator( AllocateSpillSlots(data->mid_tier_register_allocator_data());
data->mid_tier_register_allocator_data()); }
spill_allocator.AllocateSpillSlots(); };
struct MidTierPopulateReferenceMapsPhase {
DECL_PIPELINE_PHASE_CONSTANTS(MidTierPopulateReferenceMaps)
void Run(PipelineData* data, Zone* temp_zone) {
PopulateReferenceMaps(data->mid_tier_register_allocator_data());
} }
}; };
...@@ -3671,7 +3677,7 @@ void PipelineImpl::AllocateRegistersForMidTier( ...@@ -3671,7 +3677,7 @@ void PipelineImpl::AllocateRegistersForMidTier(
Run<MidTierSpillSlotAllocatorPhase>(); Run<MidTierSpillSlotAllocatorPhase>();
// TODO(rmcilroy): Run reference map population phase. Run<MidTierPopulateReferenceMapsPhase>();
TraceSequence(info(), data, "after register allocation"); TraceSequence(info(), data, "after register allocation");
......
...@@ -907,6 +907,7 @@ class RuntimeCallTimer final { ...@@ -907,6 +907,7 @@ class RuntimeCallTimer final {
ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, EarlyTrimming) \ ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, EarlyTrimming) \
ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, EffectLinearization) \ ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, EffectLinearization) \
ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, EscapeAnalysis) \ ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, EscapeAnalysis) \
ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, MidTierPopulateReferenceMaps) \
ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, MidTierRegisterAllocator) \ ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, MidTierRegisterAllocator) \
ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, MidTierSpillSlotAllocator) \ ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, MidTierSpillSlotAllocator) \
ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, FinalizeCode) \ ADD_THREAD_SPECIFIC_COUNTER(V, Optimize, FinalizeCode) \
......
...@@ -280,6 +280,8 @@ class V8_EXPORT_PRIVATE BitVector : public ZoneObject { ...@@ -280,6 +280,8 @@ class V8_EXPORT_PRIVATE BitVector : public ZoneObject {
void Print(); void Print();
#endif #endif
MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(BitVector);
private: private:
int length_; int length_;
int data_length_; int data_length_;
...@@ -307,8 +309,6 @@ class V8_EXPORT_PRIVATE BitVector : public ZoneObject { ...@@ -307,8 +309,6 @@ class V8_EXPORT_PRIVATE BitVector : public ZoneObject {
} }
} }
} }
DISALLOW_COPY_AND_ASSIGN(BitVector);
}; };
class GrowableBitVector { class GrowableBitVector {
......
...@@ -918,6 +918,7 @@ class TestEnvironment : public HandleAndZoneScope { ...@@ -918,6 +918,7 @@ class TestEnvironment : public HandleAndZoneScope {
static InstructionBlock* NewBlock(Zone* zone, RpoNumber rpo) { static InstructionBlock* NewBlock(Zone* zone, RpoNumber rpo) {
return zone->New<InstructionBlock>(zone, rpo, RpoNumber::Invalid(), return zone->New<InstructionBlock>(zone, rpo, RpoNumber::Invalid(),
RpoNumber::Invalid(),
RpoNumber::Invalid(), false, false); RpoNumber::Invalid(), false, false);
} }
......
...@@ -16,7 +16,7 @@ namespace compiler { ...@@ -16,7 +16,7 @@ namespace compiler {
InstructionBlocks* CreateSingleBlock(Zone* zone) { InstructionBlocks* CreateSingleBlock(Zone* zone) {
InstructionBlock* block = zone->New<InstructionBlock>( InstructionBlock* block = zone->New<InstructionBlock>(
zone, RpoNumber::FromInt(0), RpoNumber::Invalid(), RpoNumber::Invalid(), zone, RpoNumber::FromInt(0), RpoNumber::Invalid(), RpoNumber::Invalid(),
false, false); RpoNumber::Invalid(), false, false);
InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1); InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1);
new (blocks) InstructionBlocks(1, block, zone); new (blocks) InstructionBlocks(1, block, zone);
return blocks; return blocks;
......
...@@ -92,7 +92,7 @@ class TestCode : public HandleAndZoneScope { ...@@ -92,7 +92,7 @@ class TestCode : public HandleAndZoneScope {
if (current_ == nullptr) { if (current_ == nullptr) {
current_ = main_zone()->New<InstructionBlock>( current_ = main_zone()->New<InstructionBlock>(
main_zone(), rpo_number_, RpoNumber::Invalid(), RpoNumber::Invalid(), main_zone(), rpo_number_, RpoNumber::Invalid(), RpoNumber::Invalid(),
deferred, false); RpoNumber::Invalid(), deferred, false);
blocks_.push_back(current_); blocks_.push_back(current_);
sequence_.StartBlock(rpo_number_); sequence_.StartBlock(rpo_number_);
} }
......
...@@ -442,7 +442,7 @@ InstructionBlock* InstructionSequenceTest::NewBlock(bool deferred) { ...@@ -442,7 +442,7 @@ InstructionBlock* InstructionSequenceTest::NewBlock(bool deferred) {
} }
// Construct instruction block. // Construct instruction block.
auto instruction_block = zone()->New<InstructionBlock>( auto instruction_block = zone()->New<InstructionBlock>(
zone(), rpo, loop_header, loop_end, deferred, false); zone(), rpo, loop_header, loop_end, Rpo::Invalid(), deferred, false);
instruction_blocks_.push_back(instruction_block); instruction_blocks_.push_back(instruction_block);
current_block_ = instruction_block; current_block_ = instruction_block;
sequence()->StartBlock(rpo); sequence()->StartBlock(rpo);
...@@ -478,6 +478,7 @@ void InstructionSequenceTest::WireBlocks() { ...@@ -478,6 +478,7 @@ void InstructionSequenceTest::WireBlocks() {
} }
++offset; ++offset;
} }
CalculateDominators();
} }
void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) { void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) {
...@@ -490,6 +491,42 @@ void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) { ...@@ -490,6 +491,42 @@ void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) {
target->predecessors().push_back(block->rpo_number()); target->predecessors().push_back(block->rpo_number());
} }
void InstructionSequenceTest::CalculateDominators() {
CHECK_GT(instruction_blocks_.size(), 0);
ZoneVector<int> dominator_depth(instruction_blocks_.size(), -1, zone());
CHECK_EQ(instruction_blocks_[0]->rpo_number(), RpoNumber::FromInt(0));
dominator_depth[0] = 0;
instruction_blocks_[0]->set_dominator(RpoNumber::FromInt(0));
for (size_t i = 1; i < instruction_blocks_.size(); i++) {
InstructionBlock* block = instruction_blocks_[i];
auto pred = block->predecessors().begin();
auto end = block->predecessors().end();
DCHECK(pred != end); // All blocks except start have predecessors.
RpoNumber dominator = *pred;
// For multiple predecessors, walk up the dominator tree until a common
// dominator is found. Visitation order guarantees that all predecessors
// except for backwards edges have been visited.
for (++pred; pred != end; ++pred) {
// Don't examine backwards edges.
if (dominator_depth[pred->ToInt()] < 0) continue;
RpoNumber other = *pred;
while (dominator != other) {
if (dominator_depth[dominator.ToInt()] <
dominator_depth[other.ToInt()]) {
other = instruction_blocks_[other.ToInt()]->dominator();
} else {
dominator = instruction_blocks_[dominator.ToInt()]->dominator();
}
}
}
block->set_dominator(dominator);
dominator_depth[i] = dominator_depth[dominator.ToInt()] + 1;
}
}
Instruction* InstructionSequenceTest::Emit( Instruction* InstructionSequenceTest::Emit(
InstructionCode code, size_t outputs_size, InstructionOperand* outputs, InstructionCode code, size_t outputs_size, InstructionOperand* outputs,
size_t inputs_size, InstructionOperand* inputs, size_t temps_size, size_t inputs_size, InstructionOperand* inputs, size_t temps_size,
......
...@@ -246,6 +246,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { ...@@ -246,6 +246,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone {
InstructionOperand ConvertOutputOp(VReg vreg, TestOperand op); InstructionOperand ConvertOutputOp(VReg vreg, TestOperand op);
InstructionBlock* NewBlock(bool deferred = false); InstructionBlock* NewBlock(bool deferred = false);
void WireBlock(size_t block_offset, int jump_offset); void WireBlock(size_t block_offset, int jump_offset);
void CalculateDominators();
Instruction* Emit(InstructionCode code, size_t outputs_size = 0, Instruction* Emit(InstructionCode code, size_t outputs_size = 0,
InstructionOperand* outputs = nullptr, InstructionOperand* outputs = nullptr,
......
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