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_SPILLER_H
17 #define ES2PANDA_COMPILER_CORE_REG_SPILLER_H
18
19 #include "ir/irnode.h"
20 #include "compiler/core/regScope.h"
21
22 namespace ark::es2panda::ir {
23 class AstNode;
24 } // namespace ark::es2panda::ir
25
26 namespace ark::es2panda::compiler {
27 class CodeGen;
28
29 class RegSpiller {
30 protected:
31 class SpillInfo final {
32 public:
33 constexpr explicit SpillInfo(VReg originReg, VReg spillReg) noexcept;
34
35 [[nodiscard]] constexpr VReg OriginReg() const noexcept;
36 [[nodiscard]] constexpr VReg SpillReg() const noexcept;
37 [[nodiscard]] constexpr SpillInfo Reversed() const noexcept;
38
39 private:
40 VReg originReg_ {VReg::Invalid()};
41 VReg spillReg_ {VReg::Invalid()};
42 };
43
44 public:
45 explicit RegSpiller() = default;
46 NO_COPY_SEMANTIC(RegSpiller);
47 NO_MOVE_SEMANTIC(RegSpiller);
48 virtual ~RegSpiller() = default;
49
50 [[nodiscard]] virtual RegScope Start(CodeGen &cg) = 0;
51 [[nodiscard]] virtual SpillInfo Restore() = 0;
52 [[nodiscard]] virtual bool Restored() const = 0;
53 [[nodiscard]] virtual IRNode *MoveReg(const ir::AstNode *node, VReg vd, VReg vs, bool spillMov) = 0;
54 virtual void Finalize() noexcept = 0;
55
56 [[nodiscard]] CodeGen *GetCodeGen() const noexcept;
57 [[nodiscard]] std::pair<SpillInfo, const checker::Type *> New() noexcept;
58 void Adjust(const std::unordered_set<VReg> ®s) noexcept;
59
60 protected:
61 void SetCodeGen(CodeGen &cg) noexcept;
62 std::uint32_t SpillIndex() const noexcept;
63 std::uint32_t &SpillIndex() noexcept;
64
65 private:
66 CodeGen *cg_ {};
67 std::uint32_t spillIndex_ {0};
68 };
69
70 class DynamicRegSpiller final : public RegSpiller {
71 public:
72 explicit DynamicRegSpiller() = default;
73 NO_COPY_SEMANTIC(DynamicRegSpiller);
74 NO_MOVE_SEMANTIC(DynamicRegSpiller);
75 ~DynamicRegSpiller() override = default;
76
77 [[nodiscard]] RegScope Start(CodeGen &cg) override;
78 [[nodiscard]] SpillInfo Restore() override;
79 [[nodiscard]] bool Restored() const override;
80 [[nodiscard]] IRNode *MoveReg(const ir::AstNode *node, VReg vd, VReg vs, bool spillMov) override;
81 void Finalize() noexcept override;
82
83 private:
84 std::uint32_t regEnd_ {0};
85 };
86
87 class StaticRegSpiller final : public RegSpiller {
88 public:
89 explicit StaticRegSpiller() = default;
90 NO_COPY_SEMANTIC(StaticRegSpiller);
91 NO_MOVE_SEMANTIC(StaticRegSpiller);
92 ~StaticRegSpiller() override = default;
93
94 [[nodiscard]] RegScope Start(CodeGen &cg) override;
95 [[nodiscard]] SpillInfo Restore() override;
96 [[nodiscard]] bool Restored() const override;
97 [[nodiscard]] IRNode *MoveReg(const ir::AstNode *node, VReg vd, VReg vs, bool spillMov) override;
98 void Finalize() noexcept override;
99
100 private:
101 std::vector<SpillInfo> spills_ {};
102 };
103
SpillInfo(const VReg originReg,const VReg spillReg)104 constexpr RegSpiller::SpillInfo::SpillInfo(const VReg originReg, const VReg spillReg) noexcept
105 : originReg_(originReg), spillReg_(spillReg)
106 {
107 }
108
OriginReg()109 constexpr VReg RegSpiller::SpillInfo::OriginReg() const noexcept
110 {
111 return originReg_;
112 }
113
SpillReg()114 constexpr VReg RegSpiller::SpillInfo::SpillReg() const noexcept
115 {
116 return spillReg_;
117 }
118
Reversed()119 constexpr RegSpiller::SpillInfo RegSpiller::SpillInfo::Reversed() const noexcept
120 {
121 return SpillInfo {spillReg_, originReg_};
122 }
123
124 } // namespace ark::es2panda::compiler
125
126 #endif
127