Commit 5107f1c1 authored by bbudge's avatar bbudge Committed by Commit bot

[Turbofan] Allow compiler to elide complex aliasing code.

- Add a const bool kSimpleFPAliasing variable for each platform so it's
easier for the compiler to eliminate dead code.
- Modify RegisterAllocator to use it.

LOG=N
BUG=v8:4124

Review-Url: https://codereview.chromium.org/2101473002
Cr-Commit-Position: refs/heads/master@{#37288}
parent 1deca4ba
......@@ -148,6 +148,8 @@ GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg};
static const bool kSimpleFPAliasing = false;
// Single word VFP register.
struct SwVfpRegister {
enum Code {
......
......@@ -196,6 +196,7 @@ struct Register : public CPURegister {
// End of V8 compatibility section -----------------------
};
static const bool kSimpleFPAliasing = true;
struct FPRegister : public CPURegister {
enum Code {
......
......@@ -81,13 +81,12 @@ bool IsOutputFPRegisterOf(Instruction* instr, MachineRepresentation rep,
InstructionOperand* output = instr->OutputAt(i);
if (output->IsFPRegister()) {
const LocationOperand* op = LocationOperand::cast(output);
const RegisterConfiguration* config =
RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
if (config->fp_aliasing_kind() != RegisterConfiguration::COMBINE) {
if (kSimpleFPAliasing) {
if (op->register_code() == code) return true;
} else {
if (config->AreAliases(op->representation(), op->register_code(), rep,
code)) {
if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
->AreAliases(op->representation(), op->register_code(), rep,
code)) {
return true;
}
}
......@@ -1556,7 +1555,9 @@ void RegisterAllocationData::MarkAllocated(MachineRepresentation rep,
int index) {
switch (rep) {
case MachineRepresentation::kFloat32:
if (config()->fp_aliasing_kind() == RegisterConfiguration::COMBINE) {
if (kSimpleFPAliasing) {
assigned_double_registers_->Add(index);
} else {
int alias_base_index = -1;
int aliases = config()->GetAliases(
rep, index, MachineRepresentation::kFloat64, &alias_base_index);
......@@ -2424,10 +2425,7 @@ RegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
num_allocatable_registers_(
GetAllocatableRegisterCount(data->config(), kind)),
allocatable_register_codes_(
GetAllocatableRegisterCodes(data->config(), kind)),
no_combining_(kind != FP_REGISTERS ||
data->config()->fp_aliasing_kind() !=
RegisterConfiguration::COMBINE) {}
GetAllocatableRegisterCodes(data->config(), kind)) {}
LifetimePosition RegisterAllocator::GetSplitPositionForInstruction(
const LiveRange* range, int instruction_index) {
......@@ -2823,7 +2821,7 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
int num_regs = num_registers();
int num_codes = num_allocatable_registers();
const int* codes = allocatable_register_codes();
if (!no_combining() &&
if (!kSimpleFPAliasing &&
(current->representation() == MachineRepresentation::kFloat32)) {
num_regs = data()->config()->num_float_registers();
num_codes = data()->config()->num_allocatable_float_registers();
......@@ -2836,7 +2834,7 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
for (LiveRange* cur_active : active_live_ranges()) {
int cur_reg = cur_active->assigned_register();
if (no_combining()) {
if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
free_until_pos[cur_reg] = LifetimePosition::GapFromInstructionIndex(0);
TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg),
LifetimePosition::GapFromInstructionIndex(0).value());
......@@ -2859,7 +2857,7 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
cur_inactive->FirstIntersection(current);
if (!next_intersection.IsValid()) continue;
int cur_reg = cur_inactive->assigned_register();
if (no_combining()) {
if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
Min(free_until_pos[cur_reg], next_intersection).value());
......@@ -2940,7 +2938,7 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
int num_regs = num_registers();
int num_codes = num_allocatable_registers();
const int* codes = allocatable_register_codes();
if (!no_combining() &&
if (!kSimpleFPAliasing &&
(current->representation() == MachineRepresentation::kFloat32)) {
num_regs = data()->config()->num_float_registers();
num_codes = data()->config()->num_allocatable_float_registers();
......@@ -2957,7 +2955,7 @@ 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 (no_combining()) {
if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
if (is_fixed_or_cant_spill) {
block_pos[cur_reg] = use_pos[cur_reg] =
LifetimePosition::GapFromInstructionIndex(0);
......@@ -2999,7 +2997,7 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
if (!next_intersection.IsValid()) continue;
int cur_reg = range->assigned_register();
bool is_fixed = range->TopLevel()->IsFixed();
if (no_combining()) {
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]);
......@@ -3073,7 +3071,7 @@ 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 (no_combining()) {
if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
if (range->assigned_register() != reg) continue;
} else {
if (!data()->config()->AreAliases(current->representation(), reg,
......@@ -3108,7 +3106,7 @@ void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
LiveRange* range = inactive_live_ranges()[i];
DCHECK(range->End() > current->Start());
if (range->TopLevel()->IsFixed()) continue;
if (no_combining()) {
if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) {
if (range->assigned_register() != reg) continue;
} else {
if (!data()->config()->AreAliases(current->representation(), reg,
......
......@@ -964,11 +964,6 @@ class RegisterAllocator : public ZoneObject {
const int* allocatable_register_codes() const {
return allocatable_register_codes_;
}
// Returns true if registers do not combine to form larger registers, i.e.
// no complex aliasing detection is required. This is always true for the
// general register pass, and true for the FP register pass except for arm
// and mips archs.
bool no_combining() const { return no_combining_; }
// TODO(mtrofin): explain why splitting in gap START is always OK.
LifetimePosition GetSplitPositionForInstruction(const LiveRange* range,
......
......@@ -150,6 +150,8 @@ GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg};
static const bool kSimpleFPAliasing = true;
struct XMMRegister {
enum Code {
#define REGISTER_CODE(R) kCode_##R,
......
......@@ -156,6 +156,8 @@ int ToNumber(Register reg);
Register ToRegister(int num);
static const bool kSimpleFPAliasing = true;
// Coprocessor register.
struct FPURegister {
enum Code {
......
......@@ -156,6 +156,8 @@ int ToNumber(Register reg);
Register ToRegister(int num);
static const bool kSimpleFPAliasing = true;
// Coprocessor register.
struct FPURegister {
enum Code {
......
......@@ -207,6 +207,8 @@ const Register kConstantPoolRegister = r28; // Constant pool.
const Register kRootRegister = r29; // Roots array pointer.
const Register cp = r30; // JavaScript context pointer.
static const bool kSimpleFPAliasing = true;
// Double word FP register.
struct DoubleRegister {
enum Code {
......
......@@ -57,14 +57,13 @@ class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
Register::kNumRegisters, DoubleRegister::kMaxNumRegisters,
#if V8_TARGET_ARCH_IA32
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount, AliasingKind::OVERLAP,
kMaxAllocatableDoubleRegisterCount,
#elif V8_TARGET_ARCH_X87
kMaxAllocatableGeneralRegisterCount,
compiler == TURBOFAN ? 1 : kMaxAllocatableDoubleRegisterCount,
AliasingKind::OVERLAP,
#elif V8_TARGET_ARCH_X64
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount, AliasingKind::OVERLAP,
kMaxAllocatableDoubleRegisterCount,
#elif V8_TARGET_ARCH_ARM
FLAG_enable_embedded_constant_pool
? (kMaxAllocatableGeneralRegisterCount - 1)
......@@ -72,26 +71,26 @@ class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
CpuFeatures::IsSupported(VFP32DREGS)
? kMaxAllocatableDoubleRegisterCount
: (ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(REGISTER_COUNT) 0),
AliasingKind::COMBINE,
#elif V8_TARGET_ARCH_ARM64
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount, AliasingKind::OVERLAP,
kMaxAllocatableDoubleRegisterCount,
#elif V8_TARGET_ARCH_MIPS
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount, AliasingKind::OVERLAP,
kMaxAllocatableDoubleRegisterCount,
#elif V8_TARGET_ARCH_MIPS64
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount, AliasingKind::OVERLAP,
kMaxAllocatableDoubleRegisterCount,
#elif V8_TARGET_ARCH_PPC
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount, AliasingKind::OVERLAP,
kMaxAllocatableDoubleRegisterCount,
#elif V8_TARGET_ARCH_S390
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount, AliasingKind::OVERLAP,
kMaxAllocatableDoubleRegisterCount,
#else
#error Unsupported target architecture.
#endif
kAllocatableGeneralCodes, kAllocatableDoubleCodes,
kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE,
kGeneralRegisterNames, kFloatRegisterNames, kDoubleRegisterNames) {
}
};
......@@ -128,9 +127,8 @@ const RegisterConfiguration* RegisterConfiguration::ArchDefault(
RegisterConfiguration::RegisterConfiguration(
int num_general_registers, int num_double_registers,
int num_allocatable_general_registers, int num_allocatable_double_registers,
AliasingKind fp_aliasing_kind, const int* allocatable_general_codes,
const int* allocatable_double_codes,
const char* const* general_register_names,
const int* allocatable_general_codes, const int* allocatable_double_codes,
AliasingKind fp_aliasing_kind, const char* const* general_register_names,
const char* const* float_register_names,
const char* const* double_register_names)
: num_general_registers_(num_general_registers),
......@@ -139,11 +137,11 @@ RegisterConfiguration::RegisterConfiguration(
num_allocatable_general_registers_(num_allocatable_general_registers),
num_allocatable_double_registers_(num_allocatable_double_registers),
num_allocatable_float_registers_(0),
fp_aliasing_kind_(fp_aliasing_kind),
allocatable_general_codes_mask_(0),
allocatable_double_codes_mask_(0),
allocatable_general_codes_(allocatable_general_codes),
allocatable_double_codes_(allocatable_double_codes),
fp_aliasing_kind_(fp_aliasing_kind),
general_register_names_(general_register_names),
float_register_names_(float_register_names),
double_register_names_(double_register_names) {
......
......@@ -38,9 +38,9 @@ class RegisterConfiguration {
RegisterConfiguration(int num_general_registers, int num_double_registers,
int num_allocatable_general_registers,
int num_allocatable_double_registers,
AliasingKind fp_aliasing_kind,
const int* allocatable_general_codes,
const int* allocatable_double_codes,
AliasingKind fp_aliasing_kind,
char const* const* general_names,
char const* const* float_names,
char const* const* double_names);
......@@ -111,12 +111,12 @@ class RegisterConfiguration {
int num_allocatable_general_registers_;
int num_allocatable_double_registers_;
int num_allocatable_float_registers_;
AliasingKind fp_aliasing_kind_;
int32_t allocatable_general_codes_mask_;
int32_t allocatable_double_codes_mask_;
const int* allocatable_general_codes_;
const int* allocatable_double_codes_;
int allocatable_float_codes_[kMaxFPRegisters];
AliasingKind fp_aliasing_kind_;
char const* const* general_register_names_;
char const* const* float_register_names_;
char const* const* double_register_names_;
......
......@@ -188,6 +188,8 @@ const Register kLithiumScratch = r1; // lithium scratch.
const Register kRootRegister = r10; // Roots array pointer.
const Register cp = r13; // JavaScript context pointer.
static const bool kSimpleFPAliasing = true;
// Double word FP register.
struct DoubleRegister {
enum Code {
......
......@@ -203,6 +203,8 @@ const Register arg_reg_4 = {Register::kCode_rcx};
V(xmm13) \
V(xmm14)
static const bool kSimpleFPAliasing = true;
struct XMMRegister {
enum Code {
#define REGISTER_CODE(R) kCode_##R,
......
......@@ -148,6 +148,8 @@ GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg};
static const bool kSimpleFPAliasing = true;
struct X87Register {
enum Code {
#define REGISTER_CODE(R) kCode_##R,
......
......@@ -67,8 +67,10 @@ RegisterConfiguration* InstructionSequenceTest::config() {
if (config_.is_empty()) {
config_.Reset(new RegisterConfiguration(
num_general_registers_, num_double_registers_, num_general_registers_,
num_double_registers_, RegisterConfiguration::OVERLAP,
allocatable_codes, allocatable_double_codes, general_register_names_,
num_double_registers_, allocatable_codes, allocatable_double_codes,
kSimpleFPAliasing ? RegisterConfiguration::OVERLAP
: RegisterConfiguration::COMBINE,
general_register_names_,
double_register_names_, // float register names
double_register_names_));
}
......
......@@ -29,8 +29,8 @@ TEST_F(RegisterConfigurationUnitTest, BasicProperties) {
RegisterConfiguration test(
kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs,
kNumAllocatableDoubleRegs, RegisterConfiguration::OVERLAP, general_codes,
double_codes, nullptr, nullptr, nullptr);
kNumAllocatableDoubleRegs, general_codes, double_codes,
RegisterConfiguration::OVERLAP, nullptr, nullptr, nullptr);
EXPECT_EQ(test.num_general_registers(), kNumGeneralRegs);
EXPECT_EQ(test.num_double_registers(), kNumDoubleRegs);
......@@ -59,8 +59,8 @@ TEST_F(RegisterConfigurationUnitTest, Aliasing) {
RegisterConfiguration test(
kNumGeneralRegs, kNumDoubleRegs, kNumAllocatableGeneralRegs,
kNumAllocatableDoubleRegs, RegisterConfiguration::COMBINE, general_codes,
double_codes, nullptr, nullptr, nullptr);
kNumAllocatableDoubleRegs, general_codes, double_codes,
RegisterConfiguration::COMBINE, nullptr, nullptr, nullptr);
// There are 3 allocatable double regs, but only 2 can alias float regs.
EXPECT_EQ(test.num_allocatable_float_registers(), 4);
......
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