11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_COMPILER_BACKEND_MID_TIER_REGISTER_ALLOCATOR_H_ 61cb0ef41Sopenharmony_ci#define V8_COMPILER_BACKEND_MID_TIER_REGISTER_ALLOCATOR_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/base/compiler-specific.h" 91cb0ef41Sopenharmony_ci#include "src/common/globals.h" 101cb0ef41Sopenharmony_ci#include "src/compiler/backend/instruction.h" 111cb0ef41Sopenharmony_ci#include "src/compiler/backend/register-allocation.h" 121cb0ef41Sopenharmony_ci#include "src/flags/flags.h" 131cb0ef41Sopenharmony_ci#include "src/utils/bit-vector.h" 141cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h" 151cb0ef41Sopenharmony_ci#include "src/zone/zone.h" 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_cinamespace v8 { 181cb0ef41Sopenharmony_cinamespace internal { 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ciclass TickCounter; 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_cinamespace compiler { 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ciclass BlockState; 251cb0ef41Sopenharmony_ciclass VirtualRegisterData; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci// The MidTierRegisterAllocator is a register allocator specifically designed to 281cb0ef41Sopenharmony_ci// perform register allocation as fast as possible while minimizing spill moves. 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciclass MidTierRegisterAllocationData final : public RegisterAllocationData { 311cb0ef41Sopenharmony_ci public: 321cb0ef41Sopenharmony_ci MidTierRegisterAllocationData(const RegisterConfiguration* config, 331cb0ef41Sopenharmony_ci Zone* allocation_zone, Frame* frame, 341cb0ef41Sopenharmony_ci InstructionSequence* code, 351cb0ef41Sopenharmony_ci TickCounter* tick_counter, 361cb0ef41Sopenharmony_ci const char* debug_name = nullptr); 371cb0ef41Sopenharmony_ci MidTierRegisterAllocationData(const MidTierRegisterAllocationData&) = delete; 381cb0ef41Sopenharmony_ci MidTierRegisterAllocationData& operator=( 391cb0ef41Sopenharmony_ci const MidTierRegisterAllocationData&) = delete; 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci static MidTierRegisterAllocationData* cast(RegisterAllocationData* data) { 421cb0ef41Sopenharmony_ci DCHECK_EQ(data->type(), Type::kMidTier); 431cb0ef41Sopenharmony_ci return static_cast<MidTierRegisterAllocationData*>(data); 441cb0ef41Sopenharmony_ci } 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci VirtualRegisterData& VirtualRegisterDataFor(int virtual_register); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci // Add a gap move between the given operands |from| and |to|. 491cb0ef41Sopenharmony_ci MoveOperands* AddGapMove(int instr_index, Instruction::GapPosition position, 501cb0ef41Sopenharmony_ci const InstructionOperand& from, 511cb0ef41Sopenharmony_ci const InstructionOperand& to); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci // Adds a gap move where both sides are PendingOperand operands. 541cb0ef41Sopenharmony_ci MoveOperands* AddPendingOperandGapMove(int instr_index, 551cb0ef41Sopenharmony_ci Instruction::GapPosition position); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci // Helpers to get a block from an |rpo_number| or |instr_index|. 581cb0ef41Sopenharmony_ci const InstructionBlock* GetBlock(const RpoNumber rpo_number); 591cb0ef41Sopenharmony_ci const InstructionBlock* GetBlock(int instr_index); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci // Returns a bitvector representing all the blocks that are dominated by the 621cb0ef41Sopenharmony_ci // output of the instruction in |block|. 631cb0ef41Sopenharmony_ci const BitVector* GetBlocksDominatedBy(const InstructionBlock* block); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci // List of all instruction indexs that require a reference map. 661cb0ef41Sopenharmony_ci ZoneVector<int>& reference_map_instructions() { 671cb0ef41Sopenharmony_ci return reference_map_instructions_; 681cb0ef41Sopenharmony_ci } 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci // Returns a bitvector representing the virtual registers that were spilled. 711cb0ef41Sopenharmony_ci BitVector& spilled_virtual_registers() { return spilled_virtual_registers_; } 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci // This zone is for data structures only needed during register allocation 741cb0ef41Sopenharmony_ci // phases. 751cb0ef41Sopenharmony_ci Zone* allocation_zone() const { return allocation_zone_; } 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci // This zone is for InstructionOperands and moves that live beyond register 781cb0ef41Sopenharmony_ci // allocation. 791cb0ef41Sopenharmony_ci Zone* code_zone() const { return code()->zone(); } 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci BlockState& block_state(RpoNumber rpo_number); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci InstructionSequence* code() const { return code_; } 841cb0ef41Sopenharmony_ci Frame* frame() const { return frame_; } 851cb0ef41Sopenharmony_ci const char* debug_name() const { return debug_name_; } 861cb0ef41Sopenharmony_ci const RegisterConfiguration* config() const { return config_; } 871cb0ef41Sopenharmony_ci TickCounter* tick_counter() { return tick_counter_; } 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci private: 901cb0ef41Sopenharmony_ci Zone* const allocation_zone_; 911cb0ef41Sopenharmony_ci Frame* const frame_; 921cb0ef41Sopenharmony_ci InstructionSequence* const code_; 931cb0ef41Sopenharmony_ci const char* const debug_name_; 941cb0ef41Sopenharmony_ci const RegisterConfiguration* const config_; 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci ZoneVector<VirtualRegisterData> virtual_register_data_; 971cb0ef41Sopenharmony_ci ZoneVector<BlockState> block_states_; 981cb0ef41Sopenharmony_ci ZoneVector<int> reference_map_instructions_; 991cb0ef41Sopenharmony_ci BitVector spilled_virtual_registers_; 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci TickCounter* const tick_counter_; 1021cb0ef41Sopenharmony_ci}; 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci// Phase 1: Process instruction outputs to determine how each virtual register 1051cb0ef41Sopenharmony_ci// is defined. 1061cb0ef41Sopenharmony_civoid DefineOutputs(MidTierRegisterAllocationData* data); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci// Phase 2: Allocate registers to instructions. 1091cb0ef41Sopenharmony_civoid AllocateRegisters(MidTierRegisterAllocationData* data); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci// Phase 3: assign spilled operands to specific spill slots. 1121cb0ef41Sopenharmony_civoid AllocateSpillSlots(MidTierRegisterAllocationData* data); 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci// Phase 4: Populate reference maps for spilled references. 1151cb0ef41Sopenharmony_civoid PopulateReferenceMaps(MidTierRegisterAllocationData* data); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci} // namespace compiler 1181cb0ef41Sopenharmony_ci} // namespace internal 1191cb0ef41Sopenharmony_ci} // namespace v8 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci#endif // V8_COMPILER_BACKEND_MID_TIER_REGISTER_ALLOCATOR_H_ 122