Commit f260308d authored by Toon Verwaest's avatar Toon Verwaest Committed by V8 LUCI CQ

[maglev] Prefer already block reg as input

When picking an arbitrary register for an input, prefer picking a
register that's already used as input. If there's no such register,
block the newly picked register.

Bug: v8:7700
Change-Id: I5926ae33482aa615060fef3500c1d2d6079090a4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3716476
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Auto-Submit: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81276}
parent 0e0dc80c
......@@ -895,13 +895,15 @@ class ValueNode : public Node {
return double_registers_with_result_.has(reg);
}
RegList result_registers() {
DCHECK(!use_double_register());
return registers_with_result_;
}
DoubleRegList result_double_registers() {
DCHECK(use_double_register());
return double_registers_with_result_;
template <typename T>
RegListBase<T> result_registers() {
if constexpr (std::is_same<T, DoubleRegister>::value) {
DCHECK(use_double_register());
return double_registers_with_result_;
} else {
DCHECK(!use_double_register());
return registers_with_result_;
}
}
compiler::InstructionOperand allocation() const {
......
......@@ -890,7 +890,11 @@ void StraightForwardRegisterAllocator::AssignArbitraryRegisterInput(
compiler::UnallocatedOperand::MUST_HAVE_REGISTER);
if (location.IsAnyRegister()) {
input.SetAllocated(compiler::AllocatedOperand::cast(location));
compiler::AllocatedOperand location =
node->use_double_register()
? double_registers_.ChooseInputRegister(node)
: general_registers_.ChooseInputRegister(node);
input.SetAllocated(location);
} else {
compiler::AllocatedOperand allocation =
AllocateRegister(node, AllocationStage::kAtStart);
......@@ -960,7 +964,7 @@ void StraightForwardRegisterAllocator::VerifyRegisterState() {
auto ValidateValueNode = [this](ValueNode* node) {
if (node->use_double_register()) {
for (DoubleRegister reg : node->result_double_registers()) {
for (DoubleRegister reg : node->result_registers<DoubleRegister>()) {
if (double_registers_.free().has(reg)) {
FATAL("Node n%d thinks it's in register %s but it's free",
graph_labeller()->NodeId(node), RegisterName(reg));
......@@ -971,7 +975,7 @@ void StraightForwardRegisterAllocator::VerifyRegisterState() {
}
}
} else {
for (Register reg : node->result_registers()) {
for (Register reg : node->result_registers<Register>()) {
if (general_registers_.free().has(reg)) {
FATAL("Node n%d thinks it's in register %s but it's free",
graph_labeller()->NodeId(node), RegisterName(reg));
......@@ -1173,6 +1177,25 @@ compiler::AllocatedOperand StraightForwardRegisterAllocator::ForceAllocate(
}
}
template <typename RegisterT>
compiler::AllocatedOperand RegisterFrameState<RegisterT>::ChooseInputRegister(
ValueNode* node) {
RegTList blocked = node->result_registers<RegisterT>() & blocked_;
if (blocked.Count() > 0) {
return compiler::AllocatedOperand(compiler::LocationOperand::REGISTER,
node->GetMachineRepresentation(),
blocked.first().code());
}
compiler::AllocatedOperand allocation =
compiler::AllocatedOperand::cast(node->allocation());
if constexpr (std::is_same<RegisterT, DoubleRegister>::value) {
block(allocation.GetDoubleRegister());
} else {
block(allocation.GetRegister());
}
return allocation;
}
template <typename RegisterT>
compiler::InstructionOperand RegisterFrameState<RegisterT>::TryAllocateRegister(
ValueNode* node) {
......
......@@ -83,6 +83,7 @@ class RegisterFrameState {
bool is_blocked(RegisterT reg) { return blocked_.has(reg); }
void clear_blocked() { blocked_ = kEmptyRegList; }
compiler::AllocatedOperand ChooseInputRegister(ValueNode* node);
compiler::InstructionOperand TryAllocateRegister(ValueNode* node);
private:
......
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