[wasm][revec] Add YMM register in register allocation
Bug: v8:12716 Change-Id: I0a1e807f7b0c64afa7d259361c47314e9c9e30db Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3867140 Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Commit-Queue: Jie Pan <jie.pan@intel.com> Reviewed-by: Deepti Gandluri <gdeepti@chromium.org> Cr-Commit-Position: refs/heads/main@{#83091}
This commit is contained in:
parent
14d9b9a246
commit
79da7bbb93
@ -58,6 +58,10 @@ static_assert(RegisterConfiguration::kMaxFPRegisters >=
|
||||
DoubleRegister::kNumRegisters);
|
||||
static_assert(RegisterConfiguration::kMaxFPRegisters >=
|
||||
Simd128Register::kNumRegisters);
|
||||
#if V8_TARGET_ARCH_X64
|
||||
static_assert(RegisterConfiguration::kMaxFPRegisters >=
|
||||
Simd256Register::kNumRegisters);
|
||||
#endif
|
||||
|
||||
static int get_num_simd128_registers() {
|
||||
return
|
||||
@ -68,6 +72,8 @@ static int get_num_simd128_registers() {
|
||||
#endif // V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
|
||||
}
|
||||
|
||||
static int get_num_simd256_registers() { return 0; }
|
||||
|
||||
// Callers on architectures other than Arm expect this to be be constant
|
||||
// between build and runtime. Avoid adding variability on other platforms.
|
||||
static int get_num_allocatable_double_registers() {
|
||||
@ -114,6 +120,8 @@ static int get_num_allocatable_simd128_registers() {
|
||||
#endif
|
||||
}
|
||||
|
||||
static int get_num_allocatable_simd256_registers() { return 0; }
|
||||
|
||||
// Callers on architectures other than Arm expect this to be be constant
|
||||
// between build and runtime. Avoid adding variability on other platforms.
|
||||
static const int* get_allocatable_double_codes() {
|
||||
@ -140,9 +148,11 @@ class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
|
||||
ArchDefaultRegisterConfiguration()
|
||||
: RegisterConfiguration(
|
||||
kFPAliasing, Register::kNumRegisters, DoubleRegister::kNumRegisters,
|
||||
get_num_simd128_registers(), kMaxAllocatableGeneralRegisterCount,
|
||||
get_num_simd128_registers(), get_num_simd256_registers(),
|
||||
kMaxAllocatableGeneralRegisterCount,
|
||||
get_num_allocatable_double_registers(),
|
||||
get_num_allocatable_simd128_registers(), kAllocatableGeneralCodes,
|
||||
get_num_allocatable_simd128_registers(),
|
||||
get_num_allocatable_simd256_registers(), kAllocatableGeneralCodes,
|
||||
get_allocatable_double_codes(), get_allocatable_simd128_codes()) {}
|
||||
};
|
||||
|
||||
@ -160,9 +170,11 @@ class RestrictedRegisterConfiguration : public RegisterConfiguration {
|
||||
std::unique_ptr<char const*[]> allocatable_general_register_names)
|
||||
: RegisterConfiguration(
|
||||
kFPAliasing, Register::kNumRegisters, DoubleRegister::kNumRegisters,
|
||||
get_num_simd128_registers(), num_allocatable_general_registers,
|
||||
get_num_simd128_registers(), get_num_simd256_registers(),
|
||||
num_allocatable_general_registers,
|
||||
get_num_allocatable_double_registers(),
|
||||
get_num_allocatable_simd128_registers(),
|
||||
get_num_allocatable_simd256_registers(),
|
||||
allocatable_general_register_codes.get(),
|
||||
get_allocatable_double_codes(), get_allocatable_simd128_codes()),
|
||||
allocatable_general_register_codes_(
|
||||
@ -218,22 +230,26 @@ const RegisterConfiguration* RegisterConfiguration::RestrictGeneralRegisters(
|
||||
RegisterConfiguration::RegisterConfiguration(
|
||||
AliasingKind fp_aliasing_kind, int num_general_registers,
|
||||
int num_double_registers, int num_simd128_registers,
|
||||
int num_allocatable_general_registers, int num_allocatable_double_registers,
|
||||
int num_allocatable_simd128_registers, const int* allocatable_general_codes,
|
||||
int num_simd256_registers, int num_allocatable_general_registers,
|
||||
int num_allocatable_double_registers, int num_allocatable_simd128_registers,
|
||||
int num_allocatable_simd256_registers, const int* allocatable_general_codes,
|
||||
const int* allocatable_double_codes,
|
||||
const int* independent_allocatable_simd128_codes)
|
||||
: num_general_registers_(num_general_registers),
|
||||
num_float_registers_(0),
|
||||
num_double_registers_(num_double_registers),
|
||||
num_simd128_registers_(num_simd128_registers),
|
||||
num_simd256_registers_(num_simd256_registers),
|
||||
num_allocatable_general_registers_(num_allocatable_general_registers),
|
||||
num_allocatable_float_registers_(0),
|
||||
num_allocatable_double_registers_(num_allocatable_double_registers),
|
||||
num_allocatable_simd128_registers_(num_allocatable_simd128_registers),
|
||||
num_allocatable_simd256_registers_(num_allocatable_simd256_registers),
|
||||
allocatable_general_codes_mask_(0),
|
||||
allocatable_float_codes_mask_(0),
|
||||
allocatable_double_codes_mask_(0),
|
||||
allocatable_simd128_codes_mask_(0),
|
||||
allocatable_simd256_codes_mask_(0),
|
||||
allocatable_general_codes_(allocatable_general_codes),
|
||||
allocatable_double_codes_(allocatable_double_codes),
|
||||
fp_aliasing_kind_(fp_aliasing_kind) {
|
||||
@ -281,9 +297,17 @@ RegisterConfiguration::RegisterConfiguration(
|
||||
for (int i = 0; i < num_allocatable_float_registers_; ++i) {
|
||||
allocatable_float_codes_[i] = allocatable_simd128_codes_[i] =
|
||||
allocatable_double_codes_[i];
|
||||
#if V8_TARGET_ARCH_X64
|
||||
allocatable_simd256_codes_[i] = allocatable_double_codes_[i];
|
||||
#endif
|
||||
}
|
||||
allocatable_float_codes_mask_ = allocatable_simd128_codes_mask_ =
|
||||
allocatable_double_codes_mask_;
|
||||
#if V8_TARGET_ARCH_X64
|
||||
num_simd256_registers_ = num_double_registers_;
|
||||
num_allocatable_simd256_registers_ = num_allocatable_double_registers_;
|
||||
allocatable_simd256_codes_mask_ = allocatable_double_codes_mask_;
|
||||
#endif
|
||||
} else {
|
||||
DCHECK_EQ(fp_aliasing_kind_, AliasingKind::kIndependent);
|
||||
DCHECK_NE(independent_allocatable_simd128_codes, nullptr);
|
||||
@ -302,7 +326,9 @@ RegisterConfiguration::RegisterConfiguration(
|
||||
}
|
||||
}
|
||||
|
||||
// Assert that kFloat32, kFloat64, and kSimd128 are consecutive values.
|
||||
// Assert that kFloat32, kFloat64, kSimd128 and kSimd256 are consecutive values.
|
||||
static_assert(static_cast<int>(MachineRepresentation::kSimd256) ==
|
||||
static_cast<int>(MachineRepresentation::kSimd128) + 1);
|
||||
static_assert(static_cast<int>(MachineRepresentation::kSimd128) ==
|
||||
static_cast<int>(MachineRepresentation::kFloat64) + 1);
|
||||
static_assert(static_cast<int>(MachineRepresentation::kFloat64) ==
|
||||
|
@ -34,9 +34,10 @@ class V8_EXPORT_PRIVATE RegisterConfiguration {
|
||||
RegisterConfiguration(
|
||||
AliasingKind fp_aliasing_kind, int num_general_registers,
|
||||
int num_double_registers, int num_simd128_registers,
|
||||
int num_allocatable_general_registers,
|
||||
int num_simd256_registers, int num_allocatable_general_registers,
|
||||
int num_allocatable_double_registers,
|
||||
int num_allocatable_simd128_registers,
|
||||
int num_allocatable_simd256_registers,
|
||||
const int* allocatable_general_codes, const int* allocatable_double_codes,
|
||||
const int* independent_allocatable_simd128_codes = nullptr);
|
||||
|
||||
@ -44,6 +45,7 @@ class V8_EXPORT_PRIVATE RegisterConfiguration {
|
||||
int num_float_registers() const { return num_float_registers_; }
|
||||
int num_double_registers() const { return num_double_registers_; }
|
||||
int num_simd128_registers() const { return num_simd128_registers_; }
|
||||
int num_simd256_registers() const { return num_simd256_registers_; }
|
||||
int num_allocatable_general_registers() const {
|
||||
return num_allocatable_general_registers_;
|
||||
}
|
||||
@ -59,6 +61,10 @@ class V8_EXPORT_PRIVATE RegisterConfiguration {
|
||||
int num_allocatable_simd128_registers() const {
|
||||
return num_allocatable_simd128_registers_;
|
||||
}
|
||||
int num_allocatable_simd256_registers() const {
|
||||
return num_allocatable_simd256_registers_;
|
||||
}
|
||||
|
||||
AliasingKind fp_aliasing_kind() const { return fp_aliasing_kind_; }
|
||||
int32_t allocatable_general_codes_mask() const {
|
||||
return allocatable_general_codes_mask_;
|
||||
@ -97,6 +103,13 @@ class V8_EXPORT_PRIVATE RegisterConfiguration {
|
||||
bool IsAllocatableSimd128Code(int index) const {
|
||||
return ((1 << index) & allocatable_simd128_codes_mask_) != 0;
|
||||
}
|
||||
int GetAllocatableSimd256Code(int index) const {
|
||||
DCHECK(index >= 0 && index < num_allocatable_simd256_registers());
|
||||
return allocatable_simd256_codes_[index];
|
||||
}
|
||||
bool IsAllocatableSimd256Code(int index) const {
|
||||
return ((1 << index) & allocatable_simd256_codes_mask_) != 0;
|
||||
}
|
||||
|
||||
const int* allocatable_general_codes() const {
|
||||
return allocatable_general_codes_;
|
||||
@ -110,6 +123,9 @@ class V8_EXPORT_PRIVATE RegisterConfiguration {
|
||||
const int* allocatable_simd128_codes() const {
|
||||
return allocatable_simd128_codes_;
|
||||
}
|
||||
const int* allocatable_simd256_codes() const {
|
||||
return allocatable_simd256_codes_;
|
||||
}
|
||||
|
||||
// Aliasing calculations for floating point registers, when fp_aliasing_kind()
|
||||
// is COMBINE. Currently only implemented for kFloat32, kFloat64, or kSimd128
|
||||
@ -130,18 +146,22 @@ class V8_EXPORT_PRIVATE RegisterConfiguration {
|
||||
int num_float_registers_;
|
||||
const int num_double_registers_;
|
||||
int num_simd128_registers_;
|
||||
int num_simd256_registers_;
|
||||
int num_allocatable_general_registers_;
|
||||
int num_allocatable_float_registers_;
|
||||
int num_allocatable_double_registers_;
|
||||
int num_allocatable_simd128_registers_;
|
||||
int num_allocatable_simd256_registers_;
|
||||
int32_t allocatable_general_codes_mask_;
|
||||
int32_t allocatable_float_codes_mask_;
|
||||
int32_t allocatable_double_codes_mask_;
|
||||
int32_t allocatable_simd128_codes_mask_;
|
||||
int32_t allocatable_simd256_codes_mask_;
|
||||
const int* allocatable_general_codes_;
|
||||
int allocatable_float_codes_[kMaxFPRegisters];
|
||||
const int* allocatable_double_codes_;
|
||||
int allocatable_simd128_codes_[kMaxFPRegisters];
|
||||
int allocatable_simd256_codes_[kMaxFPRegisters];
|
||||
AliasingKind fp_aliasing_kind_;
|
||||
};
|
||||
|
||||
|
@ -233,6 +233,8 @@ using DoubleRegister = XMMRegister;
|
||||
|
||||
using Simd128Register = XMMRegister;
|
||||
|
||||
using Simd256Register = YMMRegister;
|
||||
|
||||
#define DECLARE_REGISTER(R) \
|
||||
constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R);
|
||||
DOUBLE_REGISTERS(DECLARE_REGISTER)
|
||||
|
@ -33,7 +33,6 @@ static constexpr int kFloat32Bit =
|
||||
static constexpr int kSimd128Bit =
|
||||
RepresentationBit(MachineRepresentation::kSimd128);
|
||||
|
||||
|
||||
const InstructionBlock* GetContainingLoop(const InstructionSequence* sequence,
|
||||
const InstructionBlock* block) {
|
||||
RpoNumber index = block->loop_header();
|
||||
@ -1493,6 +1492,7 @@ void TopTierRegisterAllocationData::MarkFixedUse(MachineRepresentation rep,
|
||||
switch (rep) {
|
||||
case MachineRepresentation::kFloat32:
|
||||
case MachineRepresentation::kSimd128:
|
||||
case MachineRepresentation::kSimd256:
|
||||
if (kFPAliasing == AliasingKind::kOverlap) {
|
||||
fixed_fp_register_use_->Add(index);
|
||||
} else if (kFPAliasing == AliasingKind::kIndependent) {
|
||||
@ -1526,7 +1526,8 @@ bool TopTierRegisterAllocationData::HasFixedUse(MachineRepresentation rep,
|
||||
int index) {
|
||||
switch (rep) {
|
||||
case MachineRepresentation::kFloat32:
|
||||
case MachineRepresentation::kSimd128: {
|
||||
case MachineRepresentation::kSimd128:
|
||||
case MachineRepresentation::kSimd256: {
|
||||
if (kFPAliasing == AliasingKind::kOverlap) {
|
||||
return fixed_fp_register_use_->Contains(index);
|
||||
} else if (kFPAliasing == AliasingKind::kIndependent) {
|
||||
@ -1561,6 +1562,7 @@ void TopTierRegisterAllocationData::MarkAllocated(MachineRepresentation rep,
|
||||
switch (rep) {
|
||||
case MachineRepresentation::kFloat32:
|
||||
case MachineRepresentation::kSimd128:
|
||||
case MachineRepresentation::kSimd256:
|
||||
if (kFPAliasing == AliasingKind::kOverlap) {
|
||||
assigned_double_registers_->Add(index);
|
||||
} else if (kFPAliasing == AliasingKind::kIndependent) {
|
||||
@ -1937,6 +1939,10 @@ void LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
|
||||
int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) {
|
||||
int result = -index - 1;
|
||||
switch (rep) {
|
||||
case MachineRepresentation::kSimd256:
|
||||
result -=
|
||||
kNumberOfFixedRangesPerRegister * config()->num_simd128_registers();
|
||||
V8_FALLTHROUGH;
|
||||
case MachineRepresentation::kSimd128:
|
||||
result -=
|
||||
kNumberOfFixedRangesPerRegister * config()->num_float_registers();
|
||||
@ -3391,7 +3397,8 @@ void LinearScanAllocator::ComputeStateFromManyPredecessors(
|
||||
const int* codes = allocatable_register_codes();
|
||||
MachineRepresentation rep = val.first->representation();
|
||||
if (check_aliasing && (rep == MachineRepresentation::kFloat32 ||
|
||||
rep == MachineRepresentation::kSimd128))
|
||||
rep == MachineRepresentation::kSimd128 ||
|
||||
rep == MachineRepresentation::kSimd256))
|
||||
GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
|
||||
for (int idx = 0; idx < num_regs; idx++) {
|
||||
int uses = val.second.used_registers[idx];
|
||||
@ -4005,6 +4012,10 @@ void LinearScanAllocator::GetFPRegisterSet(MachineRepresentation rep,
|
||||
*num_regs = data()->config()->num_simd128_registers();
|
||||
*num_codes = data()->config()->num_allocatable_simd128_registers();
|
||||
*codes = data()->config()->allocatable_simd128_codes();
|
||||
} else if (rep == MachineRepresentation::kSimd256) {
|
||||
*num_regs = data()->config()->num_simd256_registers();
|
||||
*num_codes = data()->config()->num_allocatable_simd256_registers();
|
||||
*codes = data()->config()->allocatable_simd256_codes();
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ TEST_F(RegisterConfigurationUnitTest, BasicProperties) {
|
||||
int double_codes[kNumAllocatableDoubleRegs] = {2, 3};
|
||||
|
||||
RegisterConfiguration test(AliasingKind::kOverlap, kNumGeneralRegs,
|
||||
kNumDoubleRegs, 0, kNumAllocatableGeneralRegs,
|
||||
kNumAllocatableDoubleRegs, 0, general_codes,
|
||||
kNumDoubleRegs, 0, 0, kNumAllocatableGeneralRegs,
|
||||
kNumAllocatableDoubleRegs, 0, 0, general_codes,
|
||||
double_codes);
|
||||
|
||||
EXPECT_EQ(test.num_general_registers(), kNumGeneralRegs);
|
||||
@ -39,6 +39,10 @@ TEST_F(RegisterConfigurationUnitTest, BasicProperties) {
|
||||
EXPECT_EQ(test.num_allocatable_float_registers(), kNumAllocatableDoubleRegs);
|
||||
EXPECT_EQ(test.num_allocatable_simd128_registers(),
|
||||
kNumAllocatableDoubleRegs);
|
||||
#if V8_TARGET_ARCH_X64
|
||||
EXPECT_EQ(test.num_allocatable_simd256_registers(),
|
||||
kNumAllocatableDoubleRegs);
|
||||
#endif
|
||||
|
||||
EXPECT_EQ(test.allocatable_general_codes_mask(),
|
||||
(1 << general_codes[0]) | (1 << general_codes[1]));
|
||||
@ -63,8 +67,8 @@ TEST_F(RegisterConfigurationUnitTest, CombineAliasing) {
|
||||
int double_codes[] = {2, 3, 16}; // reg 16 should not alias registers 32, 33.
|
||||
|
||||
RegisterConfiguration test(AliasingKind::kCombine, kNumGeneralRegs,
|
||||
kNumDoubleRegs, 0, kNumAllocatableGeneralRegs,
|
||||
kNumAllocatableDoubleRegs, 0, general_codes,
|
||||
kNumDoubleRegs, 0, 0, kNumAllocatableGeneralRegs,
|
||||
kNumAllocatableDoubleRegs, 0, 0, general_codes,
|
||||
double_codes);
|
||||
|
||||
// There are 3 allocatable double regs, but only 2 can alias float regs.
|
||||
|
@ -25,9 +25,15 @@ InstructionSequenceTest::InstructionSequenceTest()
|
||||
num_general_registers_(Register::kNumRegisters),
|
||||
num_double_registers_(DoubleRegister::kNumRegisters),
|
||||
num_simd128_registers_(Simd128Register::kNumRegisters),
|
||||
#if V8_TARGET_ARCH_X64
|
||||
num_simd256_registers_(Simd256Register::kNumRegisters),
|
||||
#else
|
||||
num_simd256_registers_(0),
|
||||
#endif // V8_TARGET_ARCH_X64
|
||||
instruction_blocks_(zone()),
|
||||
current_block_(nullptr),
|
||||
block_returns_(false) {}
|
||||
block_returns_(false) {
|
||||
}
|
||||
|
||||
void InstructionSequenceTest::SetNumRegs(int num_general_registers,
|
||||
int num_double_registers) {
|
||||
@ -48,6 +54,8 @@ int InstructionSequenceTest::GetNumRegs(MachineRepresentation rep) {
|
||||
return config()->num_double_registers();
|
||||
case MachineRepresentation::kSimd128:
|
||||
return config()->num_simd128_registers();
|
||||
case MachineRepresentation::kSimd256:
|
||||
return config()->num_simd256_registers();
|
||||
default:
|
||||
return config()->num_general_registers();
|
||||
}
|
||||
@ -62,6 +70,8 @@ int InstructionSequenceTest::GetAllocatableCode(int index,
|
||||
return config()->GetAllocatableDoubleCode(index);
|
||||
case MachineRepresentation::kSimd128:
|
||||
return config()->GetAllocatableSimd128Code(index);
|
||||
case MachineRepresentation::kSimd256:
|
||||
return config()->GetAllocatableSimd256Code(index);
|
||||
default:
|
||||
return config()->GetAllocatableGeneralCode(index);
|
||||
}
|
||||
@ -71,9 +81,10 @@ const RegisterConfiguration* InstructionSequenceTest::config() {
|
||||
if (!config_) {
|
||||
config_.reset(new RegisterConfiguration(
|
||||
kFPAliasing, num_general_registers_, num_double_registers_,
|
||||
num_simd128_registers_, num_general_registers_, num_double_registers_,
|
||||
num_simd128_registers_, kAllocatableCodes.data(),
|
||||
kAllocatableCodes.data(), kAllocatableCodes.data()));
|
||||
num_simd128_registers_, num_simd256_registers_, num_general_registers_,
|
||||
num_double_registers_, num_simd128_registers_, num_simd256_registers_,
|
||||
kAllocatableCodes.data(), kAllocatableCodes.data(),
|
||||
kAllocatableCodes.data()));
|
||||
}
|
||||
return config_.get();
|
||||
}
|
||||
|
@ -280,6 +280,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone {
|
||||
int num_general_registers_;
|
||||
int num_double_registers_;
|
||||
int num_simd128_registers_;
|
||||
int num_simd256_registers_;
|
||||
|
||||
// Block building state.
|
||||
InstructionBlocks instruction_blocks_;
|
||||
|
Loading…
Reference in New Issue
Block a user