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