1 /* 2 * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ES2PANDA_COMPILER_CORE_REG_ALLOCATOR_H 17 #define ES2PANDA_COMPILER_CORE_REG_ALLOCATOR_H 18 19 #include "generated/isa.h" 20 #include "compiler/core/regSpiller.h" 21 #include "macros.h" 22 23 namespace ark::es2panda::ir { 24 class AstNode; 25 } // namespace ark::es2panda::ir 26 27 namespace ark::es2panda::compiler { 28 class CodeGen; 29 30 class AllocatorBase { 31 public: 32 explicit AllocatorBase(CodeGen *const cg) noexcept; 33 NO_COPY_SEMANTIC(AllocatorBase); 34 NO_MOVE_SEMANTIC(AllocatorBase); 35 ~AllocatorBase() = default; 36 37 protected: 38 void PushBack(IRNode *ins) const; 39 [[nodiscard]] CodeGen &GetCodeGen() noexcept; 40 [[nodiscard]] const CodeGen &GetCodeGen() const noexcept; 41 42 template <typename T, typename... Args> Alloc(const ir::AstNode * const node,Args &&...args)43 [[nodiscard]] T *Alloc(const ir::AstNode *const node, Args &&...args) 44 { 45 return Allocator().New<T>(node, std::forward<Args>(args)...); 46 } 47 48 template <typename T, typename... Args> Add(const ir::AstNode * const node,Args &&...args)49 void Add(const ir::AstNode *const node, Args &&...args) 50 { 51 return PushBack(Alloc<T>(node, std::forward<Args>(args)...)); 52 } 53 54 private: 55 [[nodiscard]] ArenaAllocator &Allocator() noexcept; 56 [[nodiscard]] const ArenaAllocator &Allocator() const noexcept; 57 58 CodeGen *cg_; 59 }; 60 61 class SimpleAllocator final : public AllocatorBase { 62 public: 63 explicit SimpleAllocator(CodeGen *const cg) noexcept; 64 NO_COPY_SEMANTIC(SimpleAllocator); 65 NO_MOVE_SEMANTIC(SimpleAllocator); 66 ~SimpleAllocator() = default; 67 68 Label *AllocLabel(std::string &&id); 69 void AddLabel(Label *label) const; 70 71 template <typename T, typename... Args> Emit(const ir::AstNode * const node,Args &&...args)72 void Emit(const ir::AstNode *const node, Args &&...args) 73 { 74 Add<T>(node, std::forward<Args>(args)...); 75 } 76 }; 77 78 class RegAllocatorBase : public AllocatorBase { 79 public: 80 explicit RegAllocatorBase(CodeGen *cg, RegSpiller *spiller) noexcept; 81 NO_COPY_SEMANTIC(RegAllocatorBase); 82 NO_MOVE_SEMANTIC(RegAllocatorBase); 83 ~RegAllocatorBase() = default; 84 85 protected: 86 [[nodiscard]] RegSpiller &Spiller() noexcept; 87 [[nodiscard]] const RegSpiller &Spiller() const noexcept; 88 VReg Spill(IRNode *ins, VReg reg) const; 89 void Restore(const IRNode *ins) const; 90 91 [[nodiscard]] static std::pair<bool, std::size_t> RegIndicesValid(const IRNode *ins, const Span<VReg *> ®isters); 92 93 private: 94 RegSpiller *spiller_; 95 }; 96 97 class RegAllocator final : public RegAllocatorBase { 98 public: 99 explicit RegAllocator(CodeGen *cg, RegSpiller *spiller) noexcept; 100 NO_COPY_SEMANTIC(RegAllocator); 101 NO_MOVE_SEMANTIC(RegAllocator); 102 ~RegAllocator() = default; 103 104 template <typename T, int32_t VALID_VREGS = std::numeric_limits<int32_t>::max(), typename... Args> Emit(const ir::AstNode * const node,Args &&...args)105 void Emit(const ir::AstNode *const node, Args &&...args) 106 { 107 auto *const ins = Alloc<T>(node, std::forward<Args>(args)...); 108 Run(ins, VALID_VREGS); 109 } 110 111 private: 112 void Run(IRNode *ins, int32_t spillMax); 113 }; 114 115 class RangeRegAllocator final : public RegAllocatorBase { 116 public: 117 explicit RangeRegAllocator(CodeGen *cg, RegSpiller *spiller) noexcept; 118 NO_COPY_SEMANTIC(RangeRegAllocator); 119 NO_MOVE_SEMANTIC(RangeRegAllocator); 120 ~RangeRegAllocator() = default; 121 122 template <typename T, typename... Args> Emit(const ir::AstNode * const node,const VReg rangeStart,const std::size_t argCount,Args &&...args)123 void Emit(const ir::AstNode *const node, const VReg rangeStart, const std::size_t argCount, Args &&...args) 124 { 125 auto *const ins = Alloc<T>(node, std::forward<Args>(args)...); 126 Run(ins, rangeStart, argCount); 127 } 128 129 private: 130 void Run(IRNode *ins, VReg rangeStart, size_t argCount); 131 }; 132 } // namespace ark::es2panda::compiler 133 134 #endif 135