| /* | |
| * Copyright (C) 2016 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #ifndef ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_ | |
| #define ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_ | |
| #include "arch/instruction_set.h" | |
| #include "base/array_ref.h" | |
| #include "base/arena_object.h" | |
| #include "base/macros.h" | |
| namespace art HIDDEN { | |
| class CodeGenerator; | |
| class HBasicBlock; | |
| class HGraph; | |
| class HInstruction; | |
| class HParallelMove; | |
| class LiveInterval; | |
| class Location; | |
| class SsaLivenessAnalysis; | |
| /** | |
| * Base class for any register allocator. | |
| */ | |
| class RegisterAllocator : public DeletableArenaObject<kArenaAllocRegisterAllocator> { | |
| public: | |
| enum class RegisterType { | |
| kCoreRegister, | |
| kFpRegister | |
| }; | |
| static std::unique_ptr<RegisterAllocator> Create(ScopedArenaAllocator* allocator, | |
| CodeGenerator* codegen, | |
| const SsaLivenessAnalysis& analysis); | |
| virtual ~RegisterAllocator(); | |
| // Main entry point for the register allocator. Given the liveness analysis, | |
| // allocates registers to live intervals. | |
| virtual void AllocateRegisters() = 0; | |
| // Validate that the register allocator did not allocate the same register to | |
| // intervals that intersect each other. Returns false if it failed. | |
| virtual bool Validate(bool log_fatal_on_failure) = 0; | |
| // Verifies that live intervals do not conflict. Used by unit testing. | |
| static bool ValidateIntervals(ArrayRef<LiveInterval* const> intervals, | |
| size_t number_of_spill_slots, | |
| size_t number_of_out_slots, | |
| const CodeGenerator& codegen, | |
| const SsaLivenessAnalysis* liveness, // Can be null in tests. | |
| RegisterType register_type, | |
| bool log_fatal_on_failure); | |
| static constexpr const char* kRegisterAllocatorPassName = "register"; | |
| protected: | |
| RegisterAllocator(ScopedArenaAllocator* allocator, | |
| CodeGenerator* codegen, | |
| const SsaLivenessAnalysis& analysis); | |
| // Split `interval` at the position `position`. The new interval starts at `position`. | |
| // If `position` is at the start of `interval`, returns `interval` with its | |
| // register location(s) cleared. | |
| static LiveInterval* Split(LiveInterval* interval, size_t position); | |
| // Split `interval` at a position between `from` and `to`. The method will try | |
| // to find an optimal split position. | |
| LiveInterval* SplitBetween(LiveInterval* interval, size_t from, size_t to); | |
| // Helper for calling the right typed codegen function for dumping a register. | |
| void DumpRegister(std::ostream& stream, int reg, RegisterType register_type) const { | |
| DumpRegister(stream, reg, register_type, codegen_); | |
| } | |
| static void DumpRegister( | |
| std::ostream& stream, int reg, RegisterType register_type, const CodeGenerator* codegen); | |
| // Get a mask of all registers for an interval. | |
| // Most intervals either have or do not have a register, but we're using special fixed | |
| // intervals with type `Void` to mark large sets of blocked registers for calls, catch | |
| // blocks and irreducible loop headers to save memory and improve performance. | |
| uint32_t GetRegisterMask(LiveInterval* interval, RegisterType register_type) const; | |
| ScopedArenaAllocator* const allocator_; | |
| CodeGenerator* const codegen_; | |
| const SsaLivenessAnalysis& liveness_; | |
| // Cached values calculated from codegen data. | |
| const size_t num_core_registers_; | |
| const size_t num_fp_registers_; | |
| const uint32_t core_registers_blocked_for_call_; | |
| const uint32_t fp_registers_blocked_for_call_; | |
| }; | |
| } // namespace art | |
| #endif // ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_ |