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 14 namespace v8 { 15 namespace internal { 16 namespace maglev { 17 18 class MaglevCompilationUnit; 19 class MaglevPrintingVisitor; 20 class MergePointRegisterState; 21 22 class StraightForwardRegisterAllocator { 23 public: 24 StraightForwardRegisterAllocator(MaglevCompilationUnit* compilation_unit, 25 Graph* graph); 26 ~StraightForwardRegisterAllocator(); 27 stack_slots()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 used_registers()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 UpdateUse(Input * input)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 FreeRegisters(ValueNode * node)60 void FreeRegisters(ValueNode* node) { 61 RegList list = node->ClearRegisters(); 62 DCHECK_EQ(free_registers_ & list, kEmptyRegList); 63 free_registers_ |= list; 64 } FreeRegister(Register reg)65 void FreeRegister(Register reg) { free_registers_.set(reg); } 66 GetRegisterValue(Register reg)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 graph_labeller()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