• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 MAPLE_ME_INCLUDE_SSA_H
17 #define MAPLE_ME_INCLUDE_SSA_H
18 #include <iostream>
19 #include "mir_module.h"
20 #include "mir_nodes.h"
21 #include "orig_symbol.h"
22 
23 namespace maple {
24 class BB;               // circular dependency exists, no other choice
25 class MeCFG;            // circular dependency exists, no other choice
26 class VersionSt;        // circular dependency exists, no other choice
27 class OriginalStTable;  // circular dependency exists, no other choice
28 class VersionStTable;   // circular dependency exists, no other choice
29 class SSATab;           // circular dependency exists, no other choice
30 class Dominance;        // circular dependency exists, no other choice
31 bool IsLocalTopLevelOst(const OriginalSt &ost);
32 class PhiNode {
33 public:
PhiNode(MapleAllocator & alloc,VersionSt & vsym)34     PhiNode(MapleAllocator &alloc, VersionSt &vsym) : result(&vsym), phiOpnds(kNumOpnds, nullptr, alloc.Adapter())
35     {
36         phiOpnds.pop_back();
37         phiOpnds.pop_back();
38     }
39 
40     ~PhiNode() = default;
41 
GetResult()42     VersionSt *GetResult()
43     {
44         return result;
45     }
GetResult()46     const VersionSt *GetResult() const
47     {
48         return result;
49     }
50 
SetResult(VersionSt & resultPara)51     void SetResult(VersionSt &resultPara)
52     {
53         result = &resultPara;
54     }
55 
GetPhiOpnds()56     MapleVector<VersionSt *> &GetPhiOpnds()
57     {
58         return phiOpnds;
59     }
GetPhiOpnds()60     const MapleVector<VersionSt *> &GetPhiOpnds() const
61     {
62         return phiOpnds;
63     }
64 
GetPhiOpnd(size_t index)65     VersionSt *GetPhiOpnd(size_t index)
66     {
67         DEBUG_ASSERT(index < phiOpnds.size(), "out of range in PhiNode::GetPhiOpnd");
68         return phiOpnds.at(index);
69     }
GetPhiOpnd(size_t index)70     const VersionSt *GetPhiOpnd(size_t index) const
71     {
72         DEBUG_ASSERT(index < phiOpnds.size(), "out of range in PhiNode::GetPhiOpnd");
73         return phiOpnds.at(index);
74     }
75 
SetPhiOpnd(size_t index,VersionSt & opnd)76     void SetPhiOpnd(size_t index, VersionSt &opnd)
77     {
78         DEBUG_ASSERT(index < phiOpnds.size(), "out of range in PhiNode::SetPhiOpnd");
79         phiOpnds[index] = &opnd;
80     }
81 
SetPhiOpnds(const MapleVector<VersionSt * > & phiOpndsPara)82     void SetPhiOpnds(const MapleVector<VersionSt *> &phiOpndsPara)
83     {
84         phiOpnds = phiOpndsPara;
85     }
86 
87 private:
88     VersionSt *result;
89     static constexpr uint32 kNumOpnds = 2;
90     MapleVector<VersionSt *> phiOpnds;
91 };
92 
93 class SSA {
94 public:
95     SSA(SSATab &stab, MapleVector<BB *> &bbvec, Dominance *dm, SSALevel level = kSSAInvalid)
96         : ssaTab(&stab), bbVec(bbvec), dom(dm), targetLevel(level)
97     {
98     }
99 
100     virtual ~SSA() = default;
101 
102     virtual void InsertPhiNode();
103     void RenameAllBBs(MeCFG *cfg);
104 
UpdateDom(Dominance * dm)105     void UpdateDom(Dominance *dm)
106     {
107         dom = dm;
108     }
109 
110 protected:
111     void InsertPhiForDefBB(size_t bbid, VersionSt *vst);
112     void InitRenameStack(const OriginalStTable &, const VersionStTable &, MapleAllocator &renameAlloc);
113     VersionSt *CreateNewVersion(VersionSt &vSym, BB &defBB);
114     void PushToRenameStack(VersionSt *vSym);
115     void RenamePhi(BB &bb);
116     void RenameDefs(StmtNode &stmt, BB &defBB);
117     void RenameMustDefs(const StmtNode &stmt, BB &defBB);
118     void RenameUses(const StmtNode &stmt);
119     void RenamePhiUseInSucc(const BB &bb);
120     void RenameMayUses(const BaseNode &node);
121 
GetVstStacks()122     const MapleVector<MapleStack<VersionSt *> *> &GetVstStacks() const
123     {
124         return *vstStacks;
125     }
126 
GetVstStack(size_t idx)127     const MapleStack<VersionSt *> *GetVstStack(size_t idx) const
128     {
129         DEBUG_ASSERT(idx < vstStacks->size(), "out of range of vstStacks");
130         return vstStacks->at(idx);
131     }
PopVersionSt(size_t idx)132     void PopVersionSt(size_t idx)
133     {
134         vstStacks->at(idx)->pop();
135     }
136 
GetSSATab()137     SSATab *GetSSATab()
138     {
139         return ssaTab;
140     }
141 
BuildSSATopLevel()142     bool BuildSSATopLevel() const
143     {
144         return targetLevel & kSSATopLevel;
145     }
BuildSSAAddrTaken()146     bool BuildSSAAddrTaken() const
147     {
148         return targetLevel & kSSAAddrTaken;
149     }
BuildSSAAllLevel()150     bool BuildSSAAllLevel() const
151     {
152         return BuildSSAAddrTaken() && BuildSSATopLevel();
153     }
154     // Check if ost should be processed according to target ssa level set before
155     bool ShouldProcessOst(const OriginalSt &ost) const;
156 
157     bool ShouldRenameVst(const VersionSt *vst) const;
158 
159     MapleVector<MapleStack<VersionSt *> *> *vstStacks = nullptr;  // rename stack for variable versions
160     SSATab *ssaTab = nullptr;
161     MapleVector<BB *> &bbVec;
162     Dominance *dom = nullptr;
163     SSALevel targetLevel = kSSAInvalid;  // ssa level to build
164 
165 public:
166     bool runRenameOnly = false;
167 };
168 }  // namespace maple
169 #endif  // MAPLE_ME_INCLUDE_SSA_H
170