• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 - 2025 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 "util/es2pandaMacros.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 *> &registers);
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