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

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

Issue 2410673002: [Turbofan] Add concept of FP register aliasing on ARM 32. (Closed)
Patch Set: Add a TODO. Created 4 years, 2 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') | src/compiler/wasm-linkage.cc » ('j') | 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 f3d558f964d6a9d8aaad79187f46327ef7d99e92..977953509a02b49b71ea65a89ad4c4109e40b671 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -33,7 +33,7 @@ int GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) {
int GetAllocatableRegisterCount(const RegisterConfiguration* cfg,
RegisterKind kind) {
- return kind == FP_REGISTERS ? cfg->num_allocatable_aliased_double_registers()
+ return kind == FP_REGISTERS ? cfg->num_allocatable_double_registers()
: cfg->num_allocatable_general_registers();
}
@@ -74,14 +74,8 @@ int GetByteWidth(MachineRepresentation rep) {
case MachineRepresentation::kTaggedSigned:
case MachineRepresentation::kTaggedPointer:
case MachineRepresentation::kTagged:
- return kPointerSize;
case MachineRepresentation::kFloat32:
-// TODO(bbudge) Eliminate this when FP register aliasing works.
-#if V8_TARGET_ARCH_ARM
- return kDoubleSize;
-#else
return kPointerSize;
-#endif
case MachineRepresentation::kWord64:
case MachineRepresentation::kFloat64:
return kDoubleSize;
@@ -498,6 +492,12 @@ UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial(
return pos;
}
+LifetimePosition LiveRange::NextLifetimePositionRegisterIsBeneficial(
+ const LifetimePosition& start) const {
+ UsePosition* next_use = NextUsePositionRegisterIsBeneficial(start);
+ if (next_use == nullptr) return End();
+ return next_use->pos();
+}
UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
LifetimePosition start) const {
@@ -1360,8 +1360,12 @@ RegisterAllocationData::RegisterAllocationData(
allocation_zone()),
fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
allocation_zone()),
+ fixed_float_live_ranges_(this->config()->num_float_registers(), nullptr,
+ allocation_zone()),
fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
allocation_zone()),
+ fixed_simd128_live_ranges_(this->config()->num_simd128_registers(),
+ nullptr, allocation_zone()),
spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
delayed_references_(allocation_zone()),
assigned_registers_(nullptr),
@@ -1539,8 +1543,21 @@ void RegisterAllocationData::MarkAllocated(MachineRepresentation rep,
int index) {
switch (rep) {
case MachineRepresentation::kFloat32:
- case MachineRepresentation::kFloat64:
case MachineRepresentation::kSimd128:
+ if (kSimpleFPAliasing) {
+ assigned_double_registers_->Add(index);
+ } else {
+ int alias_base_index = -1;
+ int aliases = config()->GetAliases(
+ rep, index, MachineRepresentation::kFloat64, &alias_base_index);
+ DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
+ while (aliases--) {
+ int aliased_reg = alias_base_index + aliases;
+ assigned_double_registers_->Add(aliased_reg);
+ }
+ }
+ break;
+ case MachineRepresentation::kFloat64:
assigned_double_registers_->Add(index);
break;
default:
@@ -1867,7 +1884,11 @@ int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) {
int result = -index - 1;
switch (rep) {
case MachineRepresentation::kSimd128:
+ result -= config()->num_float_registers();
+ // Fall through.
case MachineRepresentation::kFloat32:
+ result -= config()->num_double_registers();
+ // Fall through.
case MachineRepresentation::kFloat64:
result -= config()->num_general_registers();
break;
@@ -1894,25 +1915,35 @@ TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
TopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor(
int index, MachineRepresentation rep) {
- TopLevelLiveRange* result = nullptr;
+ int num_regs = -1;
+ ZoneVector<TopLevelLiveRange*>* live_ranges = nullptr;
switch (rep) {
case MachineRepresentation::kFloat32:
+ num_regs = config()->num_float_registers();
+ live_ranges = &data()->fixed_float_live_ranges();
+ break;
case MachineRepresentation::kFloat64:
+ num_regs = config()->num_double_registers();
+ live_ranges = &data()->fixed_double_live_ranges();
+ break;
case MachineRepresentation::kSimd128:
- DCHECK(index < config()->num_double_registers());
- result = data()->fixed_double_live_ranges()[index];
- if (result == nullptr) {
- result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep);
- DCHECK(result->IsFixed());
- result->set_assigned_register(index);
- data()->MarkAllocated(rep, index);
- data()->fixed_double_live_ranges()[index] = result;
- }
+ num_regs = config()->num_simd128_registers();
+ live_ranges = &data()->fixed_simd128_live_ranges();
break;
default:
UNREACHABLE();
break;
}
+
+ DCHECK(index < num_regs);
+ TopLevelLiveRange* result = (*live_ranges)[index];
+ if (result == nullptr) {
+ result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep);
+ DCHECK(result->IsFixed());
+ result->set_assigned_register(index);
+ data()->MarkAllocated(rep, index);
+ (*live_ranges)[index] = result;
+ }
return result;
}
@@ -2035,8 +2066,7 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
}
if (instr->ClobbersDoubleRegisters()) {
- for (int i = 0; i < config()->num_allocatable_aliased_double_registers();
- ++i) {
+ for (int i = 0; i < config()->num_allocatable_double_registers(); ++i) {
// Add a UseInterval for all DoubleRegisters. See comment above for
// general registers.
int code = config()->GetAllocatableDoubleCode(i);
@@ -2045,6 +2075,26 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
range->AddUseInterval(curr_position, curr_position.End(),
allocation_zone());
}
+ // Clobber fixed float registers on archs with non-simple aliasing.
+ if (!kSimpleFPAliasing) {
+ for (int i = 0; i < config()->num_allocatable_float_registers(); ++i) {
+ // Add a UseInterval for all FloatRegisters. See comment above for
+ // general registers.
+ int code = config()->GetAllocatableFloatCode(i);
+ TopLevelLiveRange* range =
+ FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32);
+ range->AddUseInterval(curr_position, curr_position.End(),
+ allocation_zone());
+ }
+ for (int i = 0; i < config()->num_allocatable_simd128_registers();
+ ++i) {
+ int code = config()->GetAllocatableSimd128Code(i);
+ TopLevelLiveRange* range =
+ FixedFPLiveRangeFor(code, MachineRepresentation::kSimd128);
+ range->AddUseInterval(curr_position, curr_position.End(),
+ allocation_zone());
+ }
+ }
}
for (size_t i = 0; i < instr->InputCount(); i++) {
@@ -2690,9 +2740,15 @@ void LinearScanAllocator::AllocateRegisters() {
if (current != nullptr) AddToInactive(current);
}
} else {
+ for (TopLevelLiveRange* current : data()->fixed_float_live_ranges()) {
+ if (current != nullptr) AddToInactive(current);
+ }
for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) {
if (current != nullptr) AddToInactive(current);
}
+ for (TopLevelLiveRange* current : data()->fixed_simd128_live_ranges()) {
+ if (current != nullptr) AddToInactive(current);
+ }
}
while (!unhandled_live_ranges().empty()) {
@@ -2873,9 +2929,32 @@ void LinearScanAllocator::InactiveToActive(LiveRange* range) {
range->TopLevel()->vreg(), range->relative_id());
}
+void LinearScanAllocator::GetFPRegisterSet(MachineRepresentation rep,
+ int* num_regs, int* num_codes,
+ const int** codes) const {
+ DCHECK(!kSimpleFPAliasing);
+ if (rep == MachineRepresentation::kFloat32) {
+ *num_regs = data()->config()->num_float_registers();
+ *num_codes = data()->config()->num_allocatable_float_registers();
+ *codes = data()->config()->allocatable_float_codes();
+ } else if (rep == MachineRepresentation::kSimd128) {
+ *num_regs = data()->config()->num_simd128_registers();
+ *num_codes = data()->config()->num_allocatable_simd128_registers();
+ *codes = data()->config()->allocatable_simd128_codes();
+ } else {
+ UNREACHABLE();
+ }
+}
+
void LinearScanAllocator::FindFreeRegistersForRange(
LiveRange* range, Vector<LifetimePosition> positions) {
int num_regs = num_registers();
+ int num_codes = num_allocatable_registers();
+ const int* codes = allocatable_register_codes();
+ MachineRepresentation rep = range->representation();
+ if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 ||
+ rep == MachineRepresentation::kSimd128))
+ GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
DCHECK_GE(positions.length(), num_regs);
for (int i = 0; i < num_regs; i++) {
@@ -2884,9 +2963,20 @@ void LinearScanAllocator::FindFreeRegistersForRange(
for (LiveRange* cur_active : active_live_ranges()) {
int cur_reg = cur_active->assigned_register();
- positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0);
- TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg),
- LifetimePosition::GapFromInstructionIndex(0).value());
+ if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
+ positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0);
+ TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg),
+ LifetimePosition::GapFromInstructionIndex(0).value());
+ } else {
+ int alias_base_index = -1;
+ int aliases = data()->config()->GetAliases(
+ cur_active->representation(), cur_reg, rep, &alias_base_index);
+ DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
+ while (aliases--) {
+ int aliased_reg = alias_base_index + aliases;
+ positions[aliased_reg] = LifetimePosition::GapFromInstructionIndex(0);
+ }
+ }
}
for (LiveRange* cur_inactive : inactive_live_ranges()) {
@@ -2894,9 +2984,20 @@ void LinearScanAllocator::FindFreeRegistersForRange(
LifetimePosition next_intersection = cur_inactive->FirstIntersection(range);
if (!next_intersection.IsValid()) continue;
int cur_reg = cur_inactive->assigned_register();
- positions[cur_reg] = Min(positions[cur_reg], next_intersection);
- TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
- Min(positions[cur_reg], next_intersection).value());
+ if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
+ positions[cur_reg] = Min(positions[cur_reg], next_intersection);
+ TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
+ Min(positions[cur_reg], next_intersection).value());
+ } else {
+ int alias_base_index = -1;
+ int aliases = data()->config()->GetAliases(
+ cur_inactive->representation(), cur_reg, rep, &alias_base_index);
+ DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
+ while (aliases--) {
+ int aliased_reg = alias_base_index + aliases;
+ positions[aliased_reg] = Min(positions[aliased_reg], next_intersection);
+ }
+ }
}
}
@@ -2977,8 +3078,14 @@ bool LinearScanAllocator::TryAllocatePreferredReg(
bool LinearScanAllocator::TryAllocateFreeReg(
LiveRange* current, const Vector<LifetimePosition>& free_until_pos) {
+ int num_regs = 0; // used only for the call to GetFPRegisterSet.
int num_codes = num_allocatable_registers();
const int* codes = allocatable_register_codes();
+ MachineRepresentation rep = current->representation();
+ if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 ||
+ rep == MachineRepresentation::kSimd128))
+ GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
+
DCHECK_GE(free_until_pos.length(), num_codes);
// Find the register which stays free for the longest time.
@@ -3026,6 +3133,10 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
int num_regs = num_registers();
int num_codes = num_allocatable_registers();
const int* codes = allocatable_register_codes();
+ MachineRepresentation rep = current->representation();
+ if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 ||
+ rep == MachineRepresentation::kSimd128))
+ GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters];
LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters];
@@ -3037,16 +3148,28 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
int cur_reg = range->assigned_register();
bool is_fixed_or_cant_spill =
range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start());
- if (is_fixed_or_cant_spill) {
- block_pos[cur_reg] = use_pos[cur_reg] =
- LifetimePosition::GapFromInstructionIndex(0);
- } else {
- UsePosition* next_use =
- range->NextUsePositionRegisterIsBeneficial(current->Start());
- if (next_use == nullptr) {
- use_pos[cur_reg] = range->End();
+ if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
+ if (is_fixed_or_cant_spill) {
+ block_pos[cur_reg] = use_pos[cur_reg] =
+ LifetimePosition::GapFromInstructionIndex(0);
} else {
- use_pos[cur_reg] = next_use->pos();
+ use_pos[cur_reg] =
+ range->NextLifetimePositionRegisterIsBeneficial(current->Start());
+ }
+ } else {
+ int alias_base_index = -1;
+ int aliases = data()->config()->GetAliases(
+ range->representation(), cur_reg, rep, &alias_base_index);
+ DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
+ while (aliases--) {
+ int aliased_reg = alias_base_index + aliases;
+ if (is_fixed_or_cant_spill) {
+ block_pos[aliased_reg] = use_pos[aliased_reg] =
+ LifetimePosition::GapFromInstructionIndex(0);
+ } else {
+ use_pos[aliased_reg] =
+ range->NextLifetimePositionRegisterIsBeneficial(current->Start());
+ }
}
}
}
@@ -3057,11 +3180,29 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
if (!next_intersection.IsValid()) continue;
int cur_reg = range->assigned_register();
bool is_fixed = range->TopLevel()->IsFixed();
- if (is_fixed) {
- block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
- use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
+ if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
+ if (is_fixed) {
+ block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
+ use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
+ } else {
+ use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
+ }
} else {
- use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
+ int alias_base_index = -1;
+ int aliases = data()->config()->GetAliases(
+ range->representation(), cur_reg, rep, &alias_base_index);
+ DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
+ while (aliases--) {
+ int aliased_reg = alias_base_index + aliases;
+ if (is_fixed) {
+ block_pos[aliased_reg] =
+ Min(block_pos[aliased_reg], next_intersection);
+ use_pos[aliased_reg] =
+ Min(block_pos[aliased_reg], use_pos[aliased_reg]);
+ } else {
+ use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection);
+ }
+ }
}
}
@@ -3113,7 +3254,15 @@ void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
LifetimePosition split_pos = current->Start();
for (size_t i = 0; i < active_live_ranges().size(); ++i) {
LiveRange* range = active_live_ranges()[i];
- if (range->assigned_register() != reg) continue;
+ if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
+ if (range->assigned_register() != reg) continue;
+ } else {
+ if (!data()->config()->AreAliases(current->representation(), reg,
+ range->representation(),
+ range->assigned_register())) {
+ continue;
+ }
+ }
UsePosition* next_pos = range->NextRegisterPosition(current->Start());
LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
@@ -3140,7 +3289,14 @@ void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
LiveRange* range = inactive_live_ranges()[i];
DCHECK(range->End() > current->Start());
if (range->TopLevel()->IsFixed()) continue;
- if (range->assigned_register() != reg) continue;
+ if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
+ if (range->assigned_register() != reg) continue;
+ } else {
+ if (!data()->config()->AreAliases(current->representation(), reg,
+ range->representation(),
+ range->assigned_register()))
+ continue;
+ }
LifetimePosition next_intersection = range->FirstIntersection(current);
if (next_intersection.IsValid()) {
@@ -3631,7 +3787,6 @@ int LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block,
return gap_index;
}
-
void LiveRangeConnector::ConnectRanges(Zone* local_zone) {
DelayedInsertionMap delayed_insertion_map(local_zone);
for (TopLevelLiveRange* top_range : data()->live_ranges()) {
@@ -3719,9 +3874,8 @@ void LiveRangeConnector::ConnectRanges(Zone* local_zone) {
// Gather all MoveOperands for a single ParallelMove.
MoveOperands* move =
new (code_zone()) MoveOperands(it->first.second, it->second);
- MoveOperands* eliminate = moves->PrepareInsertAfter(move);
+ moves->PrepareInsertAfter(move, &to_eliminate);
to_insert.push_back(move);
- if (eliminate != nullptr) to_eliminate.push_back(eliminate);
}
}
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/wasm-linkage.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698