1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "arch/instruction_set.h" 21*795d594fSAndroid Build Coastguard Worker #include "base/array_ref.h" 22*795d594fSAndroid Build Coastguard Worker #include "base/arena_object.h" 23*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 26*795d594fSAndroid Build Coastguard Worker 27*795d594fSAndroid Build Coastguard Worker class CodeGenerator; 28*795d594fSAndroid Build Coastguard Worker class HBasicBlock; 29*795d594fSAndroid Build Coastguard Worker class HGraph; 30*795d594fSAndroid Build Coastguard Worker class HInstruction; 31*795d594fSAndroid Build Coastguard Worker class HParallelMove; 32*795d594fSAndroid Build Coastguard Worker class LiveInterval; 33*795d594fSAndroid Build Coastguard Worker class Location; 34*795d594fSAndroid Build Coastguard Worker class SsaLivenessAnalysis; 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker /** 37*795d594fSAndroid Build Coastguard Worker * Base class for any register allocator. 38*795d594fSAndroid Build Coastguard Worker */ 39*795d594fSAndroid Build Coastguard Worker class RegisterAllocator : public DeletableArenaObject<kArenaAllocRegisterAllocator> { 40*795d594fSAndroid Build Coastguard Worker public: 41*795d594fSAndroid Build Coastguard Worker enum class RegisterType { 42*795d594fSAndroid Build Coastguard Worker kCoreRegister, 43*795d594fSAndroid Build Coastguard Worker kFpRegister 44*795d594fSAndroid Build Coastguard Worker }; 45*795d594fSAndroid Build Coastguard Worker 46*795d594fSAndroid Build Coastguard Worker static std::unique_ptr<RegisterAllocator> Create(ScopedArenaAllocator* allocator, 47*795d594fSAndroid Build Coastguard Worker CodeGenerator* codegen, 48*795d594fSAndroid Build Coastguard Worker const SsaLivenessAnalysis& analysis); 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker virtual ~RegisterAllocator(); 51*795d594fSAndroid Build Coastguard Worker 52*795d594fSAndroid Build Coastguard Worker // Main entry point for the register allocator. Given the liveness analysis, 53*795d594fSAndroid Build Coastguard Worker // allocates registers to live intervals. 54*795d594fSAndroid Build Coastguard Worker virtual void AllocateRegisters() = 0; 55*795d594fSAndroid Build Coastguard Worker 56*795d594fSAndroid Build Coastguard Worker // Validate that the register allocator did not allocate the same register to 57*795d594fSAndroid Build Coastguard Worker // intervals that intersect each other. Returns false if it failed. 58*795d594fSAndroid Build Coastguard Worker virtual bool Validate(bool log_fatal_on_failure) = 0; 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker // Verifies that live intervals do not conflict. Used by unit testing. 61*795d594fSAndroid Build Coastguard Worker static bool ValidateIntervals(ArrayRef<LiveInterval* const> intervals, 62*795d594fSAndroid Build Coastguard Worker size_t number_of_spill_slots, 63*795d594fSAndroid Build Coastguard Worker size_t number_of_out_slots, 64*795d594fSAndroid Build Coastguard Worker const CodeGenerator& codegen, 65*795d594fSAndroid Build Coastguard Worker const SsaLivenessAnalysis* liveness, // Can be null in tests. 66*795d594fSAndroid Build Coastguard Worker RegisterType register_type, 67*795d594fSAndroid Build Coastguard Worker bool log_fatal_on_failure); 68*795d594fSAndroid Build Coastguard Worker 69*795d594fSAndroid Build Coastguard Worker static constexpr const char* kRegisterAllocatorPassName = "register"; 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker protected: 72*795d594fSAndroid Build Coastguard Worker RegisterAllocator(ScopedArenaAllocator* allocator, 73*795d594fSAndroid Build Coastguard Worker CodeGenerator* codegen, 74*795d594fSAndroid Build Coastguard Worker const SsaLivenessAnalysis& analysis); 75*795d594fSAndroid Build Coastguard Worker 76*795d594fSAndroid Build Coastguard Worker // Split `interval` at the position `position`. The new interval starts at `position`. 77*795d594fSAndroid Build Coastguard Worker // If `position` is at the start of `interval`, returns `interval` with its 78*795d594fSAndroid Build Coastguard Worker // register location(s) cleared. 79*795d594fSAndroid Build Coastguard Worker static LiveInterval* Split(LiveInterval* interval, size_t position); 80*795d594fSAndroid Build Coastguard Worker 81*795d594fSAndroid Build Coastguard Worker // Split `interval` at a position between `from` and `to`. The method will try 82*795d594fSAndroid Build Coastguard Worker // to find an optimal split position. 83*795d594fSAndroid Build Coastguard Worker LiveInterval* SplitBetween(LiveInterval* interval, size_t from, size_t to); 84*795d594fSAndroid Build Coastguard Worker 85*795d594fSAndroid Build Coastguard Worker // Helper for calling the right typed codegen function for dumping a register. DumpRegister(std::ostream & stream,int reg,RegisterType register_type)86*795d594fSAndroid Build Coastguard Worker void DumpRegister(std::ostream& stream, int reg, RegisterType register_type) const { 87*795d594fSAndroid Build Coastguard Worker DumpRegister(stream, reg, register_type, codegen_); 88*795d594fSAndroid Build Coastguard Worker } 89*795d594fSAndroid Build Coastguard Worker static void DumpRegister( 90*795d594fSAndroid Build Coastguard Worker std::ostream& stream, int reg, RegisterType register_type, const CodeGenerator* codegen); 91*795d594fSAndroid Build Coastguard Worker 92*795d594fSAndroid Build Coastguard Worker // Get a mask of all registers for an interval. 93*795d594fSAndroid Build Coastguard Worker // Most intervals either have or do not have a register, but we're using special fixed 94*795d594fSAndroid Build Coastguard Worker // intervals with type `Void` to mark large sets of blocked registers for calls, catch 95*795d594fSAndroid Build Coastguard Worker // blocks and irreducible loop headers to save memory and improve performance. 96*795d594fSAndroid Build Coastguard Worker uint32_t GetRegisterMask(LiveInterval* interval, RegisterType register_type) const; 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker ScopedArenaAllocator* const allocator_; 99*795d594fSAndroid Build Coastguard Worker CodeGenerator* const codegen_; 100*795d594fSAndroid Build Coastguard Worker const SsaLivenessAnalysis& liveness_; 101*795d594fSAndroid Build Coastguard Worker 102*795d594fSAndroid Build Coastguard Worker // Cached values calculated from codegen data. 103*795d594fSAndroid Build Coastguard Worker const size_t num_core_registers_; 104*795d594fSAndroid Build Coastguard Worker const size_t num_fp_registers_; 105*795d594fSAndroid Build Coastguard Worker const uint32_t core_registers_blocked_for_call_; 106*795d594fSAndroid Build Coastguard Worker const uint32_t fp_registers_blocked_for_call_; 107*795d594fSAndroid Build Coastguard Worker }; 108*795d594fSAndroid Build Coastguard Worker 109*795d594fSAndroid Build Coastguard Worker } // namespace art 110*795d594fSAndroid Build Coastguard Worker 111*795d594fSAndroid Build Coastguard Worker #endif // ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_ 112