1// Copyright 2022 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_MAGLEV_MAGLEV_REGALLOC_H_
6#define V8_MAGLEV_MAGLEV_REGALLOC_H_
7
8#include "src/codegen/reglist.h"
9#include "src/compiler/backend/instruction.h"
10#include "src/maglev/maglev-graph.h"
11#include "src/maglev/maglev-ir.h"
12#include "src/maglev/maglev-regalloc-data.h"
13
14namespace v8 {
15namespace internal {
16namespace maglev {
17
18class MaglevCompilationUnit;
19class MaglevPrintingVisitor;
20class MergePointRegisterState;
21
22class StraightForwardRegisterAllocator {
23 public:
24  StraightForwardRegisterAllocator(MaglevCompilationUnit* compilation_unit,
25                                   Graph* graph);
26  ~StraightForwardRegisterAllocator();
27
28  int stack_slots() const { return top_of_stack_; }
29
30 private:
31  std::vector<int> future_register_uses_[Register::kNumRegisters];
32  ValueNode* register_values_[Register::kNumRegisters];
33
34  int top_of_stack_ = 0;
35  RegList free_registers_ = kAllocatableGeneralRegisters;
36
37  RegList used_registers() const {
38    // Only allocatable registers should be free.
39    DCHECK_EQ(free_registers_, free_registers_ & kAllocatableGeneralRegisters);
40    return kAllocatableGeneralRegisters ^ free_registers_;
41  }
42
43  void ComputePostDominatingHoles(Graph* graph);
44  void AllocateRegisters(Graph* graph);
45
46  void PrintLiveRegs() const;
47
48  void UpdateUse(Input* input) { return UpdateUse(input->node(), input); }
49  void UpdateUse(ValueNode* node, InputLocation* input_location);
50  void UpdateUse(const EagerDeoptInfo& deopt_info);
51  void UpdateUse(const LazyDeoptInfo& deopt_info);
52
53  void AllocateControlNode(ControlNode* node, BasicBlock* block);
54  void AllocateNode(Node* node);
55  void AllocateNodeResult(ValueNode* node);
56  void AssignInput(Input& input);
57  void AssignTemporaries(NodeBase* node);
58  void TryAllocateToInput(Phi* phi);
59
60  void FreeRegisters(ValueNode* node) {
61    RegList list = node->ClearRegisters();
62    DCHECK_EQ(free_registers_ & list, kEmptyRegList);
63    free_registers_ |= list;
64  }
65  void FreeRegister(Register reg) { free_registers_.set(reg); }
66
67  ValueNode* GetRegisterValue(Register reg) const {
68    DCHECK(!free_registers_.has(reg));
69    ValueNode* node = register_values_[reg.code()];
70    DCHECK_NOT_NULL(node);
71    return node;
72  }
73
74  void FreeSomeRegister();
75  void AddMoveBeforeCurrentNode(compiler::AllocatedOperand source,
76                                compiler::AllocatedOperand target);
77
78  void AllocateSpillSlot(ValueNode* node);
79  void Spill(ValueNode* node);
80  void SpillAndClearRegisters();
81  void SpillRegisters();
82
83  compiler::AllocatedOperand AllocateRegister(ValueNode* node);
84  compiler::AllocatedOperand ForceAllocate(Register reg, ValueNode* node);
85  void SetRegister(Register reg, ValueNode* node);
86  void DropRegisterValue(Register reg);
87  compiler::InstructionOperand TryAllocateRegister(ValueNode* node);
88
89  void InitializeRegisterValues(MergePointRegisterState& target_state);
90  void EnsureInRegister(MergePointRegisterState& target_state,
91                        ValueNode* incoming);
92
93  void InitializeBranchTargetRegisterValues(ControlNode* source,
94                                            BasicBlock* target);
95  void InitializeConditionalBranchRegisters(ConditionalControlNode* source,
96                                            BasicBlock* target);
97  void MergeRegisterValues(ControlNode* control, BasicBlock* target,
98                           int predecessor_id);
99
100  MaglevGraphLabeller* graph_labeller() const {
101    return compilation_unit_->graph_labeller();
102  }
103
104  MaglevCompilationUnit* compilation_unit_;
105  std::unique_ptr<MaglevPrintingVisitor> printing_visitor_;
106  BlockConstIterator block_it_;
107  NodeIterator node_it_;
108};
109
110}  // namespace maglev
111}  // namespace internal
112}  // namespace v8
113
114#endif  // V8_MAGLEV_MAGLEV_REGALLOC_H_
115