Commit e1d3e0ab authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[TurboFan] Use SparseBitVector in mid-tier register allocator

This uses a SparseBitVector instead of a BitVector for storing sets of
blocks. As we only use the mid-tier register allocator for huge
functions, this should generally be a win in both compile time and
memory usage.

R=mslekova@chromium.org

Bug: chromium:1313379, v8:12780
Change-Id: Icf5b50c62f1c5fd69877cd54833d9dea8d1c37e1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3634781Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80554}
parent 0598bb38
...@@ -13,12 +13,9 @@ ...@@ -13,12 +13,9 @@
#include "src/codegen/machine-type.h" #include "src/codegen/machine-type.h"
#include "src/codegen/register-configuration.h" #include "src/codegen/register-configuration.h"
#include "src/codegen/tick-counter.h" #include "src/codegen/tick-counter.h"
#include "src/common/globals.h"
#include "src/compiler/backend/instruction.h" #include "src/compiler/backend/instruction.h"
#include "src/compiler/linkage.h" #include "src/compiler/linkage.h"
#include "src/logging/counters.h" #include "src/logging/counters.h"
#include "src/utils/bit-vector.h"
#include "src/zone/zone-containers.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -30,13 +27,9 @@ class DeferredBlocksRegion; ...@@ -30,13 +27,9 @@ class DeferredBlocksRegion;
// BlockState stores details associated with a particular basic block. // BlockState stores details associated with a particular basic block.
class BlockState final { class BlockState final {
public: public:
BlockState(int block_count, Zone* zone) MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(BlockState);
: general_registers_in_state_(nullptr),
double_registers_in_state_(nullptr), explicit BlockState(Zone* zone) : dominated_blocks_(zone) {}
deferred_blocks_region_(nullptr),
dominated_blocks_(block_count, zone),
successors_phi_index_(-1),
is_deferred_block_boundary_(false) {}
// Returns the RegisterState that applies to the input of this block. Can be // Returns the RegisterState that applies to the input of this block. Can be
// |nullptr| if the no registers of |kind| have been allocated up to this // |nullptr| if the no registers of |kind| have been allocated up to this
...@@ -46,7 +39,7 @@ class BlockState final { ...@@ -46,7 +39,7 @@ class BlockState final {
// Returns a bitvector representing all the basic blocks that are dominated // Returns a bitvector representing all the basic blocks that are dominated
// by this basic block. // by this basic block.
BitVector* dominated_blocks() { return &dominated_blocks_; } SparseBitVector* dominated_blocks() { return &dominated_blocks_; }
// Set / get this block's index for successor's phi operations. Will return // Set / get this block's index for successor's phi operations. Will return
// -1 if this block has no successor's with phi operations. // -1 if this block has no successor's with phi operations.
...@@ -73,18 +66,16 @@ class BlockState final { ...@@ -73,18 +66,16 @@ class BlockState final {
} }
void MarkAsDeferredBlockBoundary() { is_deferred_block_boundary_ = true; } void MarkAsDeferredBlockBoundary() { is_deferred_block_boundary_ = true; }
MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(BlockState);
private: private:
RegisterState* general_registers_in_state_; RegisterState* general_registers_in_state_ = nullptr;
RegisterState* double_registers_in_state_; RegisterState* double_registers_in_state_ = nullptr;
RegisterState* simd128_registers_in_state_; RegisterState* simd128_registers_in_state_ = nullptr;
DeferredBlocksRegion* deferred_blocks_region_; DeferredBlocksRegion* deferred_blocks_region_ = nullptr;
BitVector dominated_blocks_; SparseBitVector dominated_blocks_;
int successors_phi_index_; int successors_phi_index_ = -1;
bool is_deferred_block_boundary_; bool is_deferred_block_boundary_ = false;
}; };
RegisterState* BlockState::register_in_state(RegisterKind kind) { RegisterState* BlockState::register_in_state(RegisterKind kind) {
...@@ -126,16 +117,15 @@ MidTierRegisterAllocationData::MidTierRegisterAllocationData( ...@@ -126,16 +117,15 @@ MidTierRegisterAllocationData::MidTierRegisterAllocationData(
code_(code), code_(code),
debug_name_(debug_name), debug_name_(debug_name),
config_(config), config_(config),
virtual_register_data_(code->VirtualRegisterCount(), allocation_zone()), virtual_register_data_(code->VirtualRegisterCount(), zone),
block_states_(allocation_zone()), block_states_(zone),
reference_map_instructions_(allocation_zone()), reference_map_instructions_(zone),
spilled_virtual_registers_(code->VirtualRegisterCount(), spilled_virtual_registers_(code->VirtualRegisterCount(), zone),
allocation_zone()),
tick_counter_(tick_counter) { tick_counter_(tick_counter) {
int basic_block_count = code->InstructionBlockCount(); int basic_block_count = code->InstructionBlockCount();
block_states_.reserve(basic_block_count); block_states_.reserve(basic_block_count);
for (int i = 0; i < basic_block_count; i++) { for (int i = 0; i < basic_block_count; i++) {
block_states_.emplace_back(basic_block_count, allocation_zone()); block_states_.emplace_back(zone);
} }
} }
...@@ -166,7 +156,7 @@ const InstructionBlock* MidTierRegisterAllocationData::GetBlock( ...@@ -166,7 +156,7 @@ const InstructionBlock* MidTierRegisterAllocationData::GetBlock(
return code()->InstructionAt(instr_index)->block(); return code()->InstructionAt(instr_index)->block();
} }
const BitVector* MidTierRegisterAllocationData::GetBlocksDominatedBy( const SparseBitVector* MidTierRegisterAllocationData::GetBlocksDominatedBy(
const InstructionBlock* block) { const InstructionBlock* block) {
return block_state(block->rpo_number()).dominated_blocks(); return block_state(block->rpo_number()).dominated_blocks();
} }
...@@ -250,10 +240,8 @@ class Range { ...@@ -250,10 +240,8 @@ class Range {
// Represents a connected region of deferred basic blocks. // Represents a connected region of deferred basic blocks.
class DeferredBlocksRegion final { class DeferredBlocksRegion final {
public: public:
explicit DeferredBlocksRegion(Zone* zone, int number_of_blocks) explicit DeferredBlocksRegion(Zone* zone)
: spilled_vregs_(zone), : spilled_vregs_(zone), blocks_covered_(zone) {}
blocks_covered_(number_of_blocks, zone),
is_frozen_(false) {}
void AddBlock(RpoNumber block, MidTierRegisterAllocationData* data) { void AddBlock(RpoNumber block, MidTierRegisterAllocationData* data) {
DCHECK(data->GetBlock(block)->IsDeferred()); DCHECK(data->GetBlock(block)->IsDeferred());
...@@ -276,12 +264,12 @@ class DeferredBlocksRegion final { ...@@ -276,12 +264,12 @@ class DeferredBlocksRegion final {
ZoneSet<int>::const_iterator begin() const { return spilled_vregs_.begin(); } ZoneSet<int>::const_iterator begin() const { return spilled_vregs_.begin(); }
ZoneSet<int>::const_iterator end() const { return spilled_vregs_.end(); } ZoneSet<int>::const_iterator end() const { return spilled_vregs_.end(); }
const BitVector* blocks_covered() const { return &blocks_covered_; } const SparseBitVector* blocks_covered() const { return &blocks_covered_; }
private: private:
ZoneSet<int> spilled_vregs_; ZoneSet<int> spilled_vregs_;
BitVector blocks_covered_; SparseBitVector blocks_covered_;
bool is_frozen_; bool is_frozen_ = false;
}; };
// VirtualRegisterData stores data specific to a particular virtual register, // VirtualRegisterData stores data specific to a particular virtual register,
...@@ -388,12 +376,12 @@ class VirtualRegisterData final { ...@@ -388,12 +376,12 @@ class VirtualRegisterData final {
struct DeferredSpillSlotOutput { struct DeferredSpillSlotOutput {
public: public:
explicit DeferredSpillSlotOutput(int instr, AllocatedOperand op, explicit DeferredSpillSlotOutput(int instr, AllocatedOperand op,
const BitVector* blocks) const SparseBitVector* blocks)
: instr_index(instr), operand(op), live_blocks(blocks) {} : instr_index(instr), operand(op), live_blocks(blocks) {}
int instr_index; int instr_index;
AllocatedOperand operand; AllocatedOperand operand;
const BitVector* live_blocks; const SparseBitVector* live_blocks;
}; };
// Represents the range of instructions for which this virtual register needs // Represents the range of instructions for which this virtual register needs
...@@ -459,7 +447,7 @@ class VirtualRegisterData final { ...@@ -459,7 +447,7 @@ class VirtualRegisterData final {
const InstructionBlock* block = data->GetBlock(instr_index); const InstructionBlock* block = data->GetBlock(instr_index);
DCHECK_EQ(block->first_instruction_index(), instr_index); DCHECK_EQ(block->first_instruction_index(), instr_index);
BlockState& block_state = data->block_state(block->rpo_number()); BlockState& block_state = data->block_state(block->rpo_number());
const BitVector* deferred_blocks = const SparseBitVector* deferred_blocks =
block_state.deferred_blocks_region()->blocks_covered(); block_state.deferred_blocks_region()->blocks_covered();
deferred_spill_outputs_->emplace_back(instr_index, allocated_op, deferred_spill_outputs_->emplace_back(instr_index, allocated_op,
deferred_blocks); deferred_blocks);
...@@ -478,7 +466,7 @@ class VirtualRegisterData final { ...@@ -478,7 +466,7 @@ class VirtualRegisterData final {
private: private:
Range live_range_; Range live_range_;
const BitVector* live_blocks_; const SparseBitVector* live_blocks_;
ZoneVector<DeferredSpillSlotOutput>* deferred_spill_outputs_; ZoneVector<DeferredSpillSlotOutput>* deferred_spill_outputs_;
}; };
...@@ -2798,8 +2786,7 @@ MidTierOutputProcessor::MidTierOutputProcessor( ...@@ -2798,8 +2786,7 @@ MidTierOutputProcessor::MidTierOutputProcessor(
void MidTierOutputProcessor::PopulateDeferredBlockRegion( void MidTierOutputProcessor::PopulateDeferredBlockRegion(
RpoNumber initial_block) { RpoNumber initial_block) {
DeferredBlocksRegion* deferred_blocks_region = DeferredBlocksRegion* deferred_blocks_region =
zone()->New<DeferredBlocksRegion>(zone(), zone()->New<DeferredBlocksRegion>(zone());
code()->InstructionBlockCount());
DCHECK(deferred_blocks_worklist_.empty()); DCHECK(deferred_blocks_worklist_.empty());
deferred_blocks_worklist_.push(initial_block); deferred_blocks_worklist_.push(initial_block);
deferred_blocks_processed_.insert(initial_block); deferred_blocks_processed_.insert(initial_block);
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/compiler/backend/instruction.h" #include "src/compiler/backend/instruction.h"
#include "src/compiler/backend/register-allocation.h" #include "src/compiler/backend/register-allocation.h"
#include "src/flags/flags.h"
#include "src/utils/bit-vector.h" #include "src/utils/bit-vector.h"
#include "src/utils/sparse-bit-vector.h"
#include "src/zone/zone-containers.h" #include "src/zone/zone-containers.h"
#include "src/zone/zone.h" #include "src/zone/zone.h"
...@@ -60,7 +60,7 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData { ...@@ -60,7 +60,7 @@ class MidTierRegisterAllocationData final : public RegisterAllocationData {
// Returns a bitvector representing all the blocks that are dominated by the // Returns a bitvector representing all the blocks that are dominated by the
// output of the instruction in |block|. // output of the instruction in |block|.
const BitVector* GetBlocksDominatedBy(const InstructionBlock* block); const SparseBitVector* GetBlocksDominatedBy(const InstructionBlock* block);
// 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() {
......
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