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

[maglev] Keep an array of free registers and a vector of stack slots

Instead of scanning the array of registers, keep an explicit list of
free registers. Stack slots are equally changed to use an std::vector of
free slots instead of a linked list. Now we only need to scan
- the list of free registers when we want to allocate a specific
  register,
- and scan the list of allocated registers to see if the free value is
  already in a different register,
- scan the list of allocated registers to free some register if we don't
  have enough registers (for input, output, or temp).

Bug: v8:7700
Change-Id: Iff41b06aae656b59e4ed25e9066671a21660a73e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3489487Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Auto-Submit: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79278}
parent 72f105fe
......@@ -525,12 +525,14 @@ void CheckMaps::GenerateCode(MaglevCodeGenState* code_gen_state,
__ Push(object);
__ Move(kContextRegister,
code_gen_state->broker()->target_native_context().object());
// TODO(verwaest): We're calling so we need to spill around it.
__ CallRuntime(Runtime::kTryMigrateInstance);
__ cmpl(kReturnRegister0, Immediate(0));
__ j(equal, &deopt);
// The migrated object is returned on success, retry the map check.
__ LoadMap(map_tmp, kReturnRegister0);
__ Move(object, kReturnRegister0);
__ LoadMap(map_tmp, object);
__ Cmp(map_tmp, node->map().object());
__ j(equal, return_label);
......
......@@ -818,7 +818,11 @@ class CheckMaps : public FixedInputNodeT<1, CheckMaps> {
explicit CheckMaps(size_t input_count, const compiler::MapRef& map)
: Base(input_count), map_(map) {}
static constexpr OpProperties kProperties = OpProperties::Deopt();
// TODO(verwaest): This just calls in deferred code, so probably we'll need to
// mark that to generate stack maps. Mark as call so we at least clear the
// registers since we currently don't properly spill either.
static constexpr OpProperties kProperties =
OpProperties::Deopt() | OpProperties::Call();
compiler::MapRef map() const { return map_; }
......
This diff is collapsed.
......@@ -5,6 +5,7 @@
#ifndef V8_MAGLEV_MAGLEV_REGALLOC_H_
#define V8_MAGLEV_MAGLEV_REGALLOC_H_
#include "src/compiler/backend/instruction.h"
#include "src/maglev/maglev-compilation-data.h"
#include "src/maglev/maglev-graph.h"
#include "src/maglev/maglev-ir.h"
......@@ -16,19 +17,11 @@ namespace maglev {
class MaglevPrintingVisitor;
struct StackSlot {
StackSlot(MachineRepresentation representation, int index)
: slot(compiler::LocationOperand::STACK_SLOT, representation, index) {}
compiler::AllocatedOperand slot;
StackSlot* next_ = nullptr;
StackSlot** next() { return &next_; }
};
struct LiveNodeInfo {
ValueNode* node;
uint32_t last_use = 0;
uint32_t next_use = 0;
StackSlot* stack_slot = nullptr;
compiler::InstructionOperand stack_slot = compiler::InstructionOperand();
Register reg = Register::no_reg();
compiler::AllocatedOperand allocation() const {
......@@ -37,8 +30,7 @@ struct LiveNodeInfo {
MachineRepresentation::kTagged,
reg.code());
}
DCHECK_NOT_NULL(stack_slot);
return stack_slot->slot;
return compiler::AllocatedOperand::cast(stack_slot);
}
};
......@@ -57,13 +49,17 @@ class StraightForwardRegisterAllocator {
using LiveNodeInfoMap = std::map<ValueNode*, LiveNodeInfo>;
LiveNodeInfoMap values_;
base::ThreadedList<StackSlot> free_slots_;
int top_of_stack_ = 0;
#define N(V) nullptr,
LiveNodeInfo* register_values_[kAllocatableGeneralRegisterCount] = {
ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(N)};
#undef N
int top_of_stack_ = 0;
// TODO(verwaest): Make this a RegList.
uint8_t free_register_size_ = kAllocatableGeneralRegisterCount;
uint8_t free_registers_[kAllocatableGeneralRegisterCount];
std::vector<uint32_t> free_slots_;
LiveNodeInfo* MakeLive(ValueNode* node) {
uint32_t last_use = node->live_range().end;
// TODO(verwaest): We don't currently have next_use info...
......@@ -85,6 +81,8 @@ class StraightForwardRegisterAllocator {
void AssignTemporaries(NodeBase* node);
void TryAllocateToInput(LiveNodeInfo* info, Phi* phi);
void FreeRegister(int i);
void FreeSomeRegister();
RegList GetFreeRegisters(int count);
void AddMoveBeforeCurrentNode(compiler::AllocatedOperand source,
compiler::AllocatedOperand target);
......@@ -96,12 +94,9 @@ class StraightForwardRegisterAllocator {
compiler::AllocatedOperand AllocateRegister(LiveNodeInfo* info);
compiler::AllocatedOperand ForceAllocate(const Register& reg,
LiveNodeInfo* info,
bool try_move = true);
compiler::AllocatedOperand DoAllocate(const Register& reg,
LiveNodeInfo* info);
LiveNodeInfo* info);
void SetRegister(Register reg, LiveNodeInfo* info);
void Free(const Register& reg, bool try_move);
void Free(const Register& reg);
compiler::InstructionOperand TryAllocateRegister(LiveNodeInfo* info);
void InitializeRegisterValues(RegisterState* target_state);
......
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