• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "regSpiller.h"
17 #include "compiler/core/codeGen.h"
18 #include "checker/types/type.h"
19 
20 namespace ark::es2panda::compiler {
21 
GetCodeGen() const22 CodeGen *RegSpiller::GetCodeGen() const noexcept
23 {
24     return cg_;
25 }
26 
New()27 std::pair<RegSpiller::SpillInfo, const checker::Type *> RegSpiller::New() noexcept
28 {
29     const VReg origin {VReg::REG_START - spillIndex_++};
30     const auto *const originType = cg_->GetVRegType(origin);
31     const SpillInfo spillInfo {origin, cg_->AllocRegWithType(originType)};
32     return std::make_pair(spillInfo, originType);
33 }
34 
Adjust(const std::unordered_set<VReg> & regs)35 void RegSpiller::Adjust(const std::unordered_set<VReg> &regs) noexcept
36 {
37     while (true) {
38         const VReg origin {VReg::REG_START - spillIndex_};
39 
40         if (regs.count(origin) == 0) {
41             break;
42         }
43 
44         ++spillIndex_;
45     }
46 }
47 
SetCodeGen(CodeGen & cg)48 void RegSpiller::SetCodeGen(CodeGen &cg) noexcept
49 {
50     cg_ = &cg;
51 }
52 
SpillIndex() const53 std::uint32_t RegSpiller::SpillIndex() const noexcept
54 {
55     return spillIndex_;
56 }
57 
SpillIndex()58 std::uint32_t &RegSpiller::SpillIndex() noexcept
59 {
60     return spillIndex_;
61 }
62 
Start(CodeGen & cg)63 RegScope DynamicRegSpiller::Start(CodeGen &cg)
64 {
65     SetCodeGen(cg);
66     regEnd_ = GetCodeGen()->NextReg().GetIndex();
67     return RegScope {&cg};
68 }
69 
Restore()70 RegSpiller::SpillInfo DynamicRegSpiller::Restore()
71 {
72     const auto newSpillIndex = --SpillIndex();
73     return RegSpiller::SpillInfo(VReg {VReg::REG_START - newSpillIndex}, VReg {regEnd_ - SpillIndex()});
74 }
75 
Restored() const76 bool DynamicRegSpiller::Restored() const
77 {
78     return SpillIndex() == 0;
79 }
80 
MoveReg(const ir::AstNode * const node,const VReg vd,const VReg vs,const bool spillMov)81 IRNode *DynamicRegSpiller::MoveReg(const ir::AstNode *const node, const VReg vd, const VReg vs,
82                                    [[maybe_unused]] const bool spillMov)
83 {
84     return GetCodeGen()->AllocMov(node, vd, vs);
85 }
86 
Finalize()87 void DynamicRegSpiller::Finalize() noexcept
88 {
89     ASSERT(SpillIndex() == 0);
90 }
91 
Start(CodeGen & cg)92 RegScope StaticRegSpiller::Start(CodeGen &cg)
93 {
94     SetCodeGen(cg);
95     return RegScope {&cg};
96 }
97 
Restore()98 RegSpiller::SpillInfo StaticRegSpiller::Restore()
99 {
100     ASSERT(spills_.size() <= VReg::REG_START);
101     ASSERT(!spills_.empty());
102     const auto last = spills_.back().Reversed();
103     spills_.pop_back();
104     return last;
105 }
106 
Restored() const107 bool StaticRegSpiller::Restored() const
108 {
109     return spills_.empty();
110 }
111 
MoveReg(const ir::AstNode * const node,const VReg vd,const VReg vs,const bool spillMov)112 IRNode *StaticRegSpiller::MoveReg(const ir::AstNode *const node, const VReg vd, const VReg vs, const bool spillMov)
113 {
114     if (vd == vs) {
115         return nullptr;
116     }
117 
118     const auto *const sourceType = GetCodeGen()->GetVRegType(vs);
119     if (sourceType == nullptr) {
120         return nullptr;
121     }
122 
123     GetCodeGen()->SetVRegType(vd, sourceType);
124     if (spillMov) {
125         spills_.emplace_back(vd, vs);
126     }
127 
128     return GetCodeGen()->AllocMov(node, vd, vs);
129 }
130 
Finalize()131 void StaticRegSpiller::Finalize() noexcept
132 {
133     SpillIndex() = 0;
134 }
135 
136 }  // namespace ark::es2panda::compiler
137