Commit fac04fbb authored by Victor Gomes's avatar Victor Gomes Committed by V8 LUCI CQ

[maglev] Adds double registers to Nodes

The register allocator might be able to choose between a floating
or general registers.

Bug: v8:7700
Change-Id: Ib74b8c6cd5db12ae34b7f08cd2aeb21ffd3bac33
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3596121Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80054}
parent 14615a8d
...@@ -39,6 +39,13 @@ static constexpr RegList kAllocatableGeneralRegisters = { ...@@ -39,6 +39,13 @@ static constexpr RegList kAllocatableGeneralRegisters = {
ALLOCATABLE_GENERAL_REGISTERS(LIST_REG) Register::no_reg()}; ALLOCATABLE_GENERAL_REGISTERS(LIST_REG) Register::no_reg()};
#undef LIST_REG #undef LIST_REG
static constexpr DoubleRegList kEmptyDoubleRegList = {};
#define LIST_REG(V) V,
static constexpr DoubleRegList kAllocatableDoubleRegisters = {
ALLOCATABLE_DOUBLE_REGISTERS(LIST_REG) DoubleRegister::no_reg()};
#undef LIST_REG
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -752,14 +752,44 @@ class ValueNode : public Node { ...@@ -752,14 +752,44 @@ class ValueNode : public Node {
// A node is dead once it has no more upcoming uses. // A node is dead once it has no more upcoming uses.
bool is_dead() const { return next_use_ == kInvalidNodeId; } bool is_dead() const { return next_use_ == kInvalidNodeId; }
void AddRegister(Register reg) { registers_with_result_.set(reg); } constexpr bool use_double_register() const {
void RemoveRegister(Register reg) { registers_with_result_.clear(reg); } return (properties().value_representation() ==
RegList ClearRegisters() { ValueRepresentation::kFloat64);
return std::exchange(registers_with_result_, kEmptyRegList); }
void AddRegister(Register reg) {
DCHECK(!use_double_register());
registers_with_result_.set(reg);
}
void AddRegister(DoubleRegister reg) {
DCHECK(use_double_register());
double_registers_with_result_.set(reg);
}
void RemoveRegister(Register reg) {
DCHECK(!use_double_register());
registers_with_result_.clear(reg);
} }
void RemoveRegister(DoubleRegister reg) {
DCHECK(use_double_register());
double_registers_with_result_.clear(reg);
}
template <typename T>
inline RegListBase<T> ClearRegisters();
int num_registers() const { return registers_with_result_.Count(); } int num_registers() const {
bool has_register() const { return registers_with_result_ != kEmptyRegList; } if (use_double_register()) {
return double_registers_with_result_.Count();
}
return registers_with_result_.Count();
}
bool has_register() const {
if (use_double_register()) {
return double_registers_with_result_ != kEmptyDoubleRegList;
}
return registers_with_result_ != kEmptyRegList;
}
compiler::AllocatedOperand allocation() const { compiler::AllocatedOperand allocation() const {
if (has_register()) { if (has_register()) {
...@@ -780,6 +810,11 @@ class ValueNode : public Node { ...@@ -780,6 +810,11 @@ class ValueNode : public Node {
state_(kLastUse) state_(kLastUse)
#endif // DEBUG #endif // DEBUG
{ {
if (use_double_register()) {
double_registers_with_result_ = kEmptyDoubleRegList;
} else {
registers_with_result_ = kEmptyRegList;
}
} }
// Rename for better pairing with `end_id`. // Rename for better pairing with `end_id`.
...@@ -788,7 +823,10 @@ class ValueNode : public Node { ...@@ -788,7 +823,10 @@ class ValueNode : public Node {
NodeIdT end_id_ = kInvalidNodeId; NodeIdT end_id_ = kInvalidNodeId;
NodeIdT next_use_ = kInvalidNodeId; NodeIdT next_use_ = kInvalidNodeId;
ValueLocation result_; ValueLocation result_;
RegList registers_with_result_ = kEmptyRegList; union {
RegList registers_with_result_;
DoubleRegList double_registers_with_result_;
};
union { union {
// Pointer to the current last use's next_use_id field. Most of the time // Pointer to the current last use's next_use_id field. Most of the time
// this will be a pointer to an Input's next_use_id_ field, but it's // this will be a pointer to an Input's next_use_id_ field, but it's
...@@ -802,6 +840,18 @@ class ValueNode : public Node { ...@@ -802,6 +840,18 @@ class ValueNode : public Node {
#endif // DEBUG #endif // DEBUG
}; };
template <>
inline RegList ValueNode::ClearRegisters() {
DCHECK(!use_double_register());
return std::exchange(registers_with_result_, kEmptyRegList);
}
template <>
inline DoubleRegList ValueNode::ClearRegisters() {
DCHECK(use_double_register());
return std::exchange(double_registers_with_result_, kEmptyDoubleRegList);
}
ValueLocation& Node::result() { ValueLocation& Node::result() {
DCHECK(Is<ValueNode>()); DCHECK(Is<ValueNode>());
return Cast<ValueNode>()->result(); return Cast<ValueNode>()->result();
......
...@@ -675,6 +675,8 @@ void StraightForwardRegisterAllocator::AllocateSpillSlot(ValueNode* node) { ...@@ -675,6 +675,8 @@ void StraightForwardRegisterAllocator::AllocateSpillSlot(ValueNode* node) {
uint32_t free_slot; uint32_t free_slot;
bool is_tagged = (node->properties().value_representation() == bool is_tagged = (node->properties().value_representation() ==
ValueRepresentation::kTagged); ValueRepresentation::kTagged);
// TODO(v8:7700): We will need a new class of SpillSlots for doubles in 32-bit
// architectures.
SpillSlots& slots = is_tagged ? tagged_ : untagged_; SpillSlots& slots = is_tagged ? tagged_ : untagged_;
MachineRepresentation representation = is_tagged MachineRepresentation representation = is_tagged
? MachineRepresentation::kTagged ? MachineRepresentation::kTagged
......
...@@ -71,7 +71,7 @@ class StraightForwardRegisterAllocator { ...@@ -71,7 +71,7 @@ class StraightForwardRegisterAllocator {
void TryAllocateToInput(Phi* phi); void TryAllocateToInput(Phi* phi);
void FreeRegisters(ValueNode* node) { void FreeRegisters(ValueNode* node) {
RegList list = node->ClearRegisters(); RegList list = node->ClearRegisters<Register>();
DCHECK_EQ(free_registers_ & list, kEmptyRegList); DCHECK_EQ(free_registers_ & list, kEmptyRegList);
free_registers_ |= list; free_registers_ |= list;
} }
......
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