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 22namespace ark::es2panda::ir { 23class AstNode; 24} // namespace ark::es2panda::ir 25 26namespace ark::es2panda::compiler { 27class CodeGen; 28 29class RegSpiller { 30protected: 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 44public: 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 60protected: 61 void SetCodeGen(CodeGen &cg) noexcept; 62 std::uint32_t SpillIndex() const noexcept; 63 std::uint32_t &SpillIndex() noexcept; 64 65private: 66 CodeGen *cg_ {}; 67 std::uint32_t spillIndex_ {0}; 68}; 69 70class DynamicRegSpiller final : public RegSpiller { 71public: 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 83private: 84 std::uint32_t regEnd_ {0}; 85}; 86 87class StaticRegSpiller final : public RegSpiller { 88public: 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 100private: 101 std::vector<SpillInfo> spills_ {}; 102}; 103 104constexpr RegSpiller::SpillInfo::SpillInfo(const VReg originReg, const VReg spillReg) noexcept 105 : originReg_(originReg), spillReg_(spillReg) 106{ 107} 108 109constexpr VReg RegSpiller::SpillInfo::OriginReg() const noexcept 110{ 111 return originReg_; 112} 113 114constexpr VReg RegSpiller::SpillInfo::SpillReg() const noexcept 115{ 116 return spillReg_; 117} 118 119constexpr RegSpiller::SpillInfo RegSpiller::SpillInfo::Reversed() const noexcept 120{ 121 return SpillInfo {spillReg_, originReg_}; 122} 123 124} // namespace ark::es2panda::compiler 125 126#endif 127