Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1568)

Unified Diff: src/compiler/register-allocator.cc

Issue 1087983007: [turbofan] Cleanup register allocator a little after split. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/register-allocator.cc
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
index 924a53e7bd7421bc20a51bff0817530d797224ce..c96a7e94f7fe333ecb78d546b27d90a40f012ba6 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -34,6 +34,41 @@ void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
v->erase(it);
}
+
+int GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) {
+ return kind == DOUBLE_REGISTERS ? cfg->num_aliased_double_registers()
+ : cfg->num_general_registers();
+}
+
+
+const ZoneVector<LiveRange*>& GetFixedRegisters(
+ const RegisterAllocationData* data, RegisterKind kind) {
+ return kind == DOUBLE_REGISTERS ? data->fixed_double_live_ranges()
+ : data->fixed_live_ranges();
+}
+
+
+const InstructionBlock* GetContainingLoop(const InstructionSequence* sequence,
+ const InstructionBlock* block) {
+ auto index = block->loop_header();
+ if (!index.IsValid()) return nullptr;
+ return sequence->InstructionBlockAt(index);
+}
+
+
+const InstructionBlock* GetInstructionBlock(const InstructionSequence* code,
+ LifetimePosition pos) {
+ return code->GetInstructionBlock(pos.ToInstructionIndex());
+}
+
+
+bool IsBlockBoundary(const InstructionSequence* code, LifetimePosition pos) {
+ return pos.IsFullStart() &&
+ code->GetInstructionBlock(pos.ToInstructionIndex())->code_start() ==
+ pos.ToInstructionIndex();
+}
+
+
} // namespace
@@ -90,7 +125,7 @@ struct LiveRange::SpillAtDefinitionList : ZoneObject {
};
-LiveRange::LiveRange(int id, Zone* zone)
+LiveRange::LiveRange(int id)
: id_(id),
spilled_(false),
has_slot_use_(false),
@@ -369,7 +404,7 @@ void LiveRange::SplitAt(LifetimePosition position, LiveRange* result,
// Partition original use positions to the two live ranges.
if (use_before != nullptr) {
- use_before->next_ = nullptr;
+ use_before->set_next(nullptr);
} else {
first_pos_ = nullptr;
}
@@ -436,7 +471,7 @@ void LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end,
}
auto new_interval = new (zone) UseInterval(start, new_end);
- new_interval->next_ = first_interval_;
+ new_interval->set_next(first_interval_);
first_interval_ = new_interval;
if (new_interval->next() == nullptr) {
last_interval_ = new_interval;
@@ -464,8 +499,8 @@ void LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end,
// that each new use interval either precedes or intersects with
// last added interval.
DCHECK(start.Value() < first_interval_->end().Value());
- first_interval_->start_ = Min(start, first_interval_->start_);
- first_interval_->end_ = Max(end, first_interval_->end_);
+ first_interval_->set_start(Min(start, first_interval_->start()));
+ first_interval_->set_end(Max(end, first_interval_->end()));
}
}
}
@@ -489,8 +524,8 @@ void LiveRange::AddUsePosition(LifetimePosition pos,
use_pos->set_next(first_pos_);
first_pos_ = use_pos;
} else {
- use_pos->next_ = prev->next_;
- prev->next_ = use_pos;
+ use_pos->set_next(prev->next());
+ prev->set_next(use_pos);
}
if (prev_hint == nullptr && use_pos->HasHint()) {
@@ -748,10 +783,7 @@ void RegisterAllocationData::AssignPhiInput(
LiveRange* RegisterAllocationData::NewLiveRange(int index) {
- // The LiveRange object itself can go in the local zone, but the
- // InstructionOperand needs to go in the code zone, since it may survive
- // register allocation.
- return new (allocation_zone()) LiveRange(index, code_zone());
+ return new (allocation_zone()) LiveRange(index);
}
@@ -1395,7 +1427,7 @@ void LiveRangeBuilder::BuildLiveRanges() {
// Without this hack, all uses with "any" policy would get the constant
// operand assigned.
if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
- for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next_) {
+ for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next()) {
if (pos->type() == UsePositionType::kRequiresSlot) continue;
UsePositionType new_type = UsePositionType::kAny;
// Can't mark phis as needing a register.
@@ -1428,15 +1460,13 @@ void LiveRangeBuilder::Verify() const {
LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
- RegisterKind kind)
+ RegisterKind kind, Zone* local_zone)
: data_(data),
mode_(kind),
- num_registers_(kind == DOUBLE_REGISTERS
- ? config()->num_aliased_double_registers()
- : config()->num_general_registers()),
- unhandled_live_ranges_(allocation_zone()),
- active_live_ranges_(allocation_zone()),
- inactive_live_ranges_(allocation_zone()) {
+ num_registers_(GetRegisterCount(data->config(), kind)),
+ unhandled_live_ranges_(local_zone),
+ active_live_ranges_(local_zone),
+ inactive_live_ranges_(local_zone) {
unhandled_live_ranges().reserve(
static_cast<size_t>(code()->VirtualRegisterCount() * 2));
active_live_ranges().reserve(8);
@@ -1463,14 +1493,11 @@ void LinearScanAllocator::AllocateRegisters() {
DCHECK(active_live_ranges().empty());
DCHECK(inactive_live_ranges().empty());
- if (mode_ == DOUBLE_REGISTERS) {
- for (auto current : fixed_double_live_ranges()) {
- if (current != nullptr) AddToInactive(current);
- }
- } else {
- DCHECK(mode_ == GENERAL_REGISTERS);
- for (auto current : fixed_live_ranges()) {
- if (current != nullptr) AddToInactive(current);
+ auto& fixed_ranges = GetFixedRegisters(data(), mode_);
+ for (auto current : fixed_ranges) {
+ if (current != nullptr) {
+ DCHECK_EQ(mode_, current->Kind());
+ AddToInactive(current);
}
}
@@ -1544,7 +1571,7 @@ void LinearScanAllocator::AllocateRegisters() {
}
-const char* LinearScanAllocator::RegisterName(int allocation_index) {
+const char* LinearScanAllocator::RegisterName(int allocation_index) const {
if (mode_ == GENERAL_REGISTERS) {
return config()->general_register_name(allocation_index);
} else {
@@ -1651,7 +1678,7 @@ void LinearScanAllocator::InactiveToActive(LiveRange* range) {
bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters];
- for (int i = 0; i < num_registers_; i++) {
+ for (int i = 0; i < num_registers(); i++) {
free_until_pos[i] = LifetimePosition::MaxPosition();
}
@@ -1679,14 +1706,14 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
if (free_until_pos[register_index].Value() >= current->End().Value()) {
TRACE("Assigning preferred reg %s to live range %d\n",
RegisterName(register_index), current->id());
- SetLiveRangeAssignedRegister(current, register_index);
+ data()->SetLiveRangeAssignedRegister(current, register_index);
return true;
}
}
// Find the register which stays free for the longest time.
int reg = 0;
- for (int i = 1; i < RegisterCount(); ++i) {
+ for (int i = 1; i < num_registers(); ++i) {
if (free_until_pos[i].Value() > free_until_pos[reg].Value()) {
reg = i;
}
@@ -1711,7 +1738,7 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
DCHECK(pos.Value() >= current->End().Value());
TRACE("Assigning free reg %s to live range %d\n", RegisterName(reg),
current->id());
- SetLiveRangeAssignedRegister(current, reg);
+ data()->SetLiveRangeAssignedRegister(current, reg);
return true;
}
@@ -1729,7 +1756,7 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
LifetimePosition use_pos[RegisterConfiguration::kMaxDoubleRegisters];
LifetimePosition block_pos[RegisterConfiguration::kMaxDoubleRegisters];
- for (int i = 0; i < num_registers_; i++) {
+ for (int i = 0; i < num_registers(); i++) {
use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
}
@@ -1763,7 +1790,7 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
}
int reg = 0;
- for (int i = 1; i < RegisterCount(); ++i) {
+ for (int i = 1; i < num_registers(); ++i) {
if (use_pos[i].Value() > use_pos[reg].Value()) {
reg = i;
}
@@ -1790,7 +1817,7 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
DCHECK(block_pos[reg].Value() >= current->End().Value());
TRACE("Assigning blocked reg %s to live range %d\n", RegisterName(reg),
current->id());
- SetLiveRangeAssignedRegister(current, reg);
+ data()->SetLiveRangeAssignedRegister(current, reg);
// This register was not free. Thus we need to find and spill
// parts of active and inactive live regions that use the same register
@@ -1799,17 +1826,9 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
}
-static const InstructionBlock* GetContainingLoop(
- const InstructionSequence* sequence, const InstructionBlock* block) {
- auto index = block->loop_header();
- if (!index.IsValid()) return nullptr;
- return sequence->InstructionBlockAt(index);
-}
-
-
LifetimePosition LinearScanAllocator::FindOptimalSpillingPos(
LiveRange* range, LifetimePosition pos) {
- auto block = GetInstructionBlock(pos.Start());
+ auto block = GetInstructionBlock(code(), pos.Start());
auto loop_header =
block->IsLoopHeader() ? block : GetContainingLoop(code(), block);
@@ -1901,7 +1920,7 @@ bool LinearScanAllocator::TryReuseSpillForPhi(LiveRange* range) {
for (size_t i = 0; i < phi->operands().size(); i++) {
int op = phi->operands()[i];
LiveRange* op_range = LiveRangeFor(op);
- if (op_range->GetSpillRange() == nullptr) continue;
+ if (!op_range->HasSpillRange()) continue;
auto pred = code()->InstructionBlockAt(block->predecessors()[i]);
auto pred_end = LifetimePosition::InstructionFromInstructionIndex(
pred->last_instruction_index());
@@ -1929,9 +1948,9 @@ bool LinearScanAllocator::TryReuseSpillForPhi(LiveRange* range) {
for (size_t i = 1; i < phi->operands().size(); i++) {
int op = phi->operands()[i];
auto op_range = LiveRangeFor(op);
+ if (!op_range->HasSpillRange()) continue;
auto op_spill = op_range->GetSpillRange();
- if (op_spill != nullptr &&
- (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill))) {
+ if (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill)) {
num_merged++;
}
}
@@ -1983,10 +2002,10 @@ LiveRange* LinearScanAllocator::SplitRangeAt(LiveRange* range,
// We can't properly connect liveranges if splitting occurred at the end
// a block.
DCHECK(pos.IsStart() || pos.IsGapPosition() ||
- (code()->GetInstructionBlock(pos.ToInstructionIndex()))
- ->last_instruction_index() != pos.ToInstructionIndex());
+ (GetInstructionBlock(code(), pos)->last_instruction_index() !=
+ pos.ToInstructionIndex()));
- int vreg = GetVirtualRegister();
+ int vreg = code()->NextVirtualRegister();
auto result = LiveRangeFor(vreg);
range->SplitAt(pos, result, allocation_zone());
return result;
@@ -2015,8 +2034,8 @@ LifetimePosition LinearScanAllocator::FindOptimalSplitPos(
// We have no choice
if (start_instr == end_instr) return end;
- auto start_block = GetInstructionBlock(start);
- auto end_block = GetInstructionBlock(end);
+ auto start_block = GetInstructionBlock(code(), start);
+ auto end_block = GetInstructionBlock(code(), end);
if (end_block == start_block) {
// The interval is split in the same basic block. Split at the latest
@@ -2066,7 +2085,7 @@ void LinearScanAllocator::SpillBetweenUntil(LiveRange* range,
// Split it at position between ]start+1, end[, spill the middle part
// and put the rest to unhandled.
auto third_part_end = end.PrevStart().End();
- if (data()->IsBlockBoundary(end.Start())) {
+ if (IsBlockBoundary(code(), end.Start())) {
third_part_end = end.Start();
}
auto third_part = SplitBetween(
@@ -2341,11 +2360,11 @@ class LiveRangeBoundArray {
class LiveRangeFinder {
public:
- explicit LiveRangeFinder(const RegisterAllocationData* data)
+ explicit LiveRangeFinder(const RegisterAllocationData* data, Zone* zone)
: data_(data),
bounds_length_(static_cast<int>(data_->live_ranges().size())),
- bounds_(data_->allocation_zone()->NewArray<LiveRangeBoundArray>(
- bounds_length_)) {
+ bounds_(zone->NewArray<LiveRangeBoundArray>(bounds_length_)),
+ zone_(zone) {
for (int i = 0; i < bounds_length_; ++i) {
new (&bounds_[i]) LiveRangeBoundArray();
}
@@ -2357,7 +2376,7 @@ class LiveRangeFinder {
DCHECK(range != nullptr && !range->IsEmpty());
auto array = &bounds_[operand_index];
if (array->ShouldInitialize()) {
- array->Initialize(data_->allocation_zone(), range);
+ array->Initialize(zone_, range);
}
return array;
}
@@ -2366,6 +2385,7 @@ class LiveRangeFinder {
const RegisterAllocationData* const data_;
const int bounds_length_;
LiveRangeBoundArray* const bounds_;
+ Zone* const zone_;
DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder);
};
@@ -2384,9 +2404,9 @@ bool LiveRangeConnector::CanEagerlyResolveControlFlow(
}
-void LiveRangeConnector::ResolveControlFlow() {
+void LiveRangeConnector::ResolveControlFlow(Zone* local_zone) {
// Lazily linearize live ranges in memory for fast lookup.
- LiveRangeFinder finder(data());
+ LiveRangeFinder finder(data(), local_zone);
auto& live_in_sets = data()->live_in_sets();
for (auto block : code()->instruction_blocks()) {
if (CanEagerlyResolveControlFlow(block)) continue;
@@ -2434,9 +2454,9 @@ void LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block,
}
-void LiveRangeConnector::ConnectRanges(Zone* temp_zone) {
+void LiveRangeConnector::ConnectRanges(Zone* local_zone) {
ZoneMap<std::pair<ParallelMove*, InstructionOperand>, InstructionOperand>
- delayed_insertion_map(temp_zone);
+ delayed_insertion_map(local_zone);
for (auto first_range : data()->live_ranges()) {
if (first_range == nullptr || first_range->IsChild()) continue;
for (auto second_range = first_range->next(); second_range != nullptr;
@@ -2446,8 +2466,8 @@ void LiveRangeConnector::ConnectRanges(Zone* temp_zone) {
// boundary.
if (second_range->IsSpilled()) continue;
if (first_range->End().Value() != pos.Value()) continue;
- if (data()->IsBlockBoundary(pos) &&
- !CanEagerlyResolveControlFlow(GetInstructionBlock(pos))) {
+ if (IsBlockBoundary(code(), pos) &&
+ !CanEagerlyResolveControlFlow(GetInstructionBlock(code(), pos))) {
continue;
}
auto prev_operand = first_range->GetAssignedOperand();
@@ -2478,8 +2498,8 @@ void LiveRangeConnector::ConnectRanges(Zone* temp_zone) {
}
if (delayed_insertion_map.empty()) return;
// Insert all the moves which should occur after the stored move.
- ZoneVector<MoveOperands*> to_insert(temp_zone);
- ZoneVector<MoveOperands*> to_eliminate(temp_zone);
+ ZoneVector<MoveOperands*> to_insert(local_zone);
+ ZoneVector<MoveOperands*> to_eliminate(local_zone);
to_insert.reserve(4);
to_eliminate.reserve(4);
auto moves = delayed_insertion_map.begin()->first.first;
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698