Commit 79da7bbb authored by jiepan's avatar jiepan Committed by V8 LUCI CQ

[wasm][revec] Add YMM register in register allocation

Bug: v8:12716
Change-Id: I0a1e807f7b0c64afa7d259361c47314e9c9e30db
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3867140Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Jie Pan <jie.pan@intel.com>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83091}
parent 14d9b9a2
......@@ -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_;
......
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