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_IRMAP_H 17 #define MAPLE_ME_INCLUDE_IRMAP_H 18 #include "bb.h" 19 #include "ver_symbol.h" 20 #include "ssa_tab.h" 21 #include "me_ir.h" 22 #include "meexpr_use_info.h" 23 24 namespace maple { 25 class IRMapBuild; // circular dependency exists, no other choice 26 27 class IRMap : public AnalysisResult { 28 friend IRMapBuild; 29 30 public: IRMap(SSATab & ssaTab,MemPool & memPool,uint32 hashTableSize)31 IRMap(SSATab &ssaTab, MemPool &memPool, uint32 hashTableSize) 32 : AnalysisResult(&memPool), 33 ssaTab(ssaTab), 34 mirModule(ssaTab.GetModule()), 35 irMapAlloc(&memPool), 36 mapHashLength(hashTableSize), 37 hashTable(mapHashLength, nullptr, irMapAlloc.Adapter()), 38 verst2MeExprTable(ssaTab.GetVersionStTableSize(), nullptr, irMapAlloc.Adapter()), 39 lpreTmps(irMapAlloc.Adapter()), 40 vst2Decrefs(irMapAlloc.Adapter()), 41 exprUseInfo(&memPool) 42 { 43 } 44 45 virtual ~IRMap() = default; 46 virtual BB *GetBB(BBId id) = 0; 47 virtual BB *GetBBForLabIdx(LabelIdx lidx, PUIdx pidx = 0) = 0; 48 MeExpr *HashMeExpr(MeExpr &meExpr); 49 IvarMeExpr *BuildLHSIvarFromIassMeStmt(IassignMeStmt &iassignMeStmt); 50 IvarMeExpr *BuildLHSIvar(MeExpr &baseAddr, PrimType primType, const TyIdx &tyIdx, FieldID fieldID); 51 IvarMeExpr *BuildLHSIvar(MeExpr &baseAddr, IassignMeStmt &iassignMeStmt, FieldID fieldID); 52 MeExpr *CreateAddrofMeExpr(MeExpr &); 53 MeExpr *CreateAddroffuncMeExpr(PUIdx); 54 MeExpr *CreateAddrofMeExprFromSymbol(MIRSymbol &sym, PUIdx puIdx); 55 MeExpr *CreateIaddrofMeExpr(FieldID fieldId, TyIdx tyIdx, MeExpr *base); 56 MeExpr *CreateIvarMeExpr(MeExpr &expr, TyIdx tyIdx, MeExpr &base); 57 58 // for creating VarMeExpr 59 VarMeExpr *CreateVarMeExprVersion(OriginalSt *ost); CreateVarMeExprVersion(const VarMeExpr & varx)60 VarMeExpr *CreateVarMeExprVersion(const VarMeExpr &varx) 61 { 62 return CreateVarMeExprVersion(varx.GetOst()); 63 } 64 RegMeExpr *CreateRegRefMeExpr(const MeExpr &meExpr); 65 VarMeExpr *CreateNewVar(GStrIdx strIdx, PrimType primType, bool isGlobal); 66 VarMeExpr *CreateNewLocalRefVarTmp(GStrIdx strIdx, TyIdx tIdx); 67 68 // for creating RegMeExpr 69 RegMeExpr *CreateRegMeExprVersion(OriginalSt &); CreateRegMeExprVersion(const RegMeExpr & regx)70 RegMeExpr *CreateRegMeExprVersion(const RegMeExpr ®x) 71 { 72 return CreateRegMeExprVersion(*regx.GetOst()); 73 } 74 75 ScalarMeExpr *CreateRegOrVarMeExprVersion(OStIdx ostIdx); 76 RegMeExpr *CreateRegMeExpr(PrimType); 77 RegMeExpr *CreateRegMeExpr(MIRType &); CreateRegMeExpr(const MeExpr & meexpr)78 RegMeExpr *CreateRegMeExpr(const MeExpr &meexpr) 79 { 80 MIRType *mirType = meexpr.GetType(); 81 if (mirType == nullptr || mirType->GetPrimType() == PTY_agg) { 82 return CreateRegMeExpr(meexpr.GetPrimType()); 83 } 84 if (meexpr.GetMeOp() == kMeOpIvar && mirType->GetPrimType() != PTY_ref) { 85 return CreateRegMeExpr(meexpr.GetPrimType()); 86 } 87 return CreateRegMeExpr(*mirType); 88 } 89 90 MeExpr *ReplaceMeExprExpr(MeExpr &, const MeExpr &, MeExpr &); GetMeExprByVerID(uint32 verid)91 MeExpr *GetMeExprByVerID(uint32 verid) const 92 { 93 return verst2MeExprTable[verid]; 94 } 95 GetMeExpr(size_t index)96 MeExpr *GetMeExpr(size_t index) 97 { 98 DEBUG_ASSERT(index < verst2MeExprTable.size(), "index out of range"); 99 MeExpr *meExpr = verst2MeExprTable.at(index); 100 if (meExpr == nullptr || !meExpr->IsScalar()) { 101 return nullptr; 102 } 103 return meExpr; 104 } 105 106 IassignMeStmt *CreateIassignMeStmt(TyIdx, IvarMeExpr &, MeExpr &, const MapleMap<OStIdx, ChiMeNode *> &); 107 AssignMeStmt *CreateAssignMeStmt(ScalarMeExpr &, MeExpr &, BB &); 108 void InsertMeStmtBefore(BB &, MeStmt &, MeStmt &); 109 MePhiNode *CreateMePhi(ScalarMeExpr &); 110 DumpBB(const BB & bb)111 void DumpBB(const BB &bb) 112 { 113 int i = 0; 114 for (const auto &meStmt : bb.GetMeStmts()) { 115 if (GetDumpStmtNum()) { 116 LogInfo::MapleLogger() << "(" << i++ << ") "; 117 } 118 meStmt.Dump(this); 119 } 120 } 121 122 virtual void Dump() = 0; SetCurFunction(const BB &)123 virtual void SetCurFunction(const BB &) {} 124 125 MeExpr *CreateIntConstMeExpr(const IntVal &value, PrimType pType); 126 MeExpr *CreateIntConstMeExpr(int64, PrimType); 127 MeExpr *CreateConstMeExpr(PrimType, MIRConst &); 128 MeExpr *CreateMeExprUnary(Opcode, PrimType, MeExpr &); 129 MeExpr *CreateMeExprBinary(Opcode, PrimType, MeExpr &, MeExpr &); 130 MeExpr *CreateMeExprCompare(Opcode, PrimType, PrimType, MeExpr &, MeExpr &); 131 MeExpr *CreateMeExprSelect(PrimType, MeExpr &, MeExpr &, MeExpr &); 132 MeExpr *CreateMeExprTypeCvt(PrimType, PrimType, MeExpr &); 133 MeExpr *CreateMeExprRetype(PrimType, TyIdx, MeExpr &); 134 MeExpr *CreateMeExprExt(Opcode, PrimType, uint32, MeExpr &); 135 UnaryMeStmt *CreateUnaryMeStmt(Opcode op, MeExpr *opnd); 136 UnaryMeStmt *CreateUnaryMeStmt(Opcode op, MeExpr *opnd, BB *bb, const SrcPosition *src); 137 GotoMeStmt *CreateGotoMeStmt(uint32 offset, BB *bb, const SrcPosition *src = nullptr); 138 IntrinsiccallMeStmt *CreateIntrinsicCallMeStmt(MIRIntrinsicID idx, std::vector<MeExpr *> &opnds, 139 TyIdx tyIdx = TyIdx()); 140 IntrinsiccallMeStmt *CreateIntrinsicCallAssignedMeStmt(MIRIntrinsicID idx, std::vector<MeExpr *> &opnds, 141 ScalarMeExpr *ret, TyIdx tyIdx = TyIdx()); 142 MeExpr *CreateCanonicalizedMeExpr(PrimType primType, Opcode opA, Opcode opB, MeExpr *opndA, MeExpr *opndB, 143 MeExpr *opndC); 144 MeExpr *CreateCanonicalizedMeExpr(PrimType primType, Opcode opA, MeExpr *opndA, Opcode opB, MeExpr *opndB, 145 MeExpr *opndC); 146 MeExpr *CreateCanonicalizedMeExpr(PrimType primType, Opcode opA, Opcode opB, MeExpr *opndA, MeExpr *opndB, 147 Opcode opC, MeExpr *opndC, MeExpr *opndD); 148 MeExpr *FoldConstExpr(PrimType primType, Opcode op, ConstMeExpr *opndA, ConstMeExpr *opndB); 149 MeExpr *SimplifyBandExpr(const OpMeExpr *bandExpr); 150 MeExpr *SimplifyLshrExpr(const OpMeExpr *shrExpr); 151 MeExpr *SimplifySubExpr(const OpMeExpr *subExpr); 152 MeExpr *SimplifyAddExpr(const OpMeExpr *addExpr); 153 MeExpr *SimplifyMulExpr(const OpMeExpr *mulExpr); 154 MeExpr *SimplifyCmpExpr(OpMeExpr *cmpExpr); 155 MeExpr *SimplifySelExpr(OpMeExpr *selExpr); 156 MeExpr *SimplifyOpMeExpr(OpMeExpr *opmeexpr); 157 MeExpr *SimplifyOrMeExpr(OpMeExpr *opmeexpr); 158 MeExpr *SimplifyAshrMeExpr(OpMeExpr *opmeexpr); 159 MeExpr *SimplifyMeExpr(MeExpr *x); 160 void SimplifyCastForAssign(MeStmt *assignStmt); 161 void SimplifyAssign(AssignMeStmt *assignStmt); 162 MeExpr *SimplifyCast(MeExpr *expr); 163 MeExpr *SimplifyIvarWithConstOffset(IvarMeExpr *ivar, bool lhsIvar); 164 MeExpr *SimplifyIvarWithAddrofBase(IvarMeExpr *ivar); 165 MeExpr *SimplifyIvarWithIaddrofBase(IvarMeExpr *ivar, bool lhsIvar); 166 MeExpr *SimplifyIvar(IvarMeExpr *ivar, bool lhsIvar); 167 void UpdateIncDecAttr(MeStmt &meStmt); 168 169 template <class T, typename... Arguments> NewInPool(Arguments &&...args)170 T *NewInPool(Arguments &&... args) 171 { 172 return irMapAlloc.GetMemPool()->New<T>(&irMapAlloc, std::forward<Arguments>(args)...); 173 } 174 175 template <class T, typename... Arguments> New(Arguments &&...args)176 T *New(Arguments &&... args) 177 { 178 return irMapAlloc.GetMemPool()->New<T>(std::forward<Arguments>(args)...); 179 } 180 GetSSATab()181 SSATab &GetSSATab() 182 { 183 return ssaTab; 184 } 185 GetSSATab()186 const SSATab &GetSSATab() const 187 { 188 return ssaTab; 189 } 190 GetMIRModule()191 MIRModule &GetMIRModule() 192 { 193 return mirModule; 194 } 195 GetMIRModule()196 const MIRModule &GetMIRModule() const 197 { 198 return mirModule; 199 } 200 GetIRMapAlloc()201 MapleAllocator &GetIRMapAlloc() 202 { 203 return irMapAlloc; 204 } 205 GetExprID()206 int32 GetExprID() const 207 { 208 return exprID; 209 } 210 SetExprID(int32 id)211 void SetExprID(int32 id) 212 { 213 exprID = id; 214 } 215 GetVerst2MeExprTable()216 MapleVector<MeExpr *> &GetVerst2MeExprTable() 217 { 218 return verst2MeExprTable; 219 } 220 GetVerst2MeExprTableItem(uint32 i)221 MeExpr *GetVerst2MeExprTableItem(uint32 i) 222 { 223 if (i >= verst2MeExprTable.size()) { 224 return nullptr; 225 } 226 return verst2MeExprTable[i]; 227 } 228 SetVerst2MeExprTableItem(uint32 i,MeExpr * expr)229 void SetVerst2MeExprTableItem(uint32 i, MeExpr *expr) 230 { 231 verst2MeExprTable[i] = expr; 232 } 233 GetLpreTmpsEnd()234 MapleUnorderedMap<OStIdx, RegMeExpr *>::iterator GetLpreTmpsEnd() 235 { 236 return lpreTmps.end(); 237 } 238 FindLpreTmpsItem(OStIdx idx)239 MapleUnorderedMap<OStIdx, RegMeExpr *>::iterator FindLpreTmpsItem(OStIdx idx) 240 { 241 return lpreTmps.find(idx); 242 } 243 SetLpreTmps(OStIdx idx,RegMeExpr & expr)244 void SetLpreTmps(OStIdx idx, RegMeExpr &expr) 245 { 246 lpreTmps[idx] = &expr; 247 } 248 GetVerst2DecrefsMap()249 MapleUnorderedMap<VarMeExpr *, MapleSet<MeStmt *> *> &GetVerst2DecrefsMap() 250 { 251 return vst2Decrefs; 252 } 253 GetDecrefsEnd()254 MapleUnorderedMap<VarMeExpr *, MapleSet<MeStmt *> *>::iterator GetDecrefsEnd() 255 { 256 return vst2Decrefs.end(); 257 } 258 FindDecrefItem(VarMeExpr & var)259 MapleUnorderedMap<VarMeExpr *, MapleSet<MeStmt *> *>::iterator FindDecrefItem(VarMeExpr &var) 260 { 261 return vst2Decrefs.find(&var); 262 } 263 SetDecrefs(VarMeExpr & var,MapleSet<MeStmt * > & set)264 void SetDecrefs(VarMeExpr &var, MapleSet<MeStmt *> &set) 265 { 266 vst2Decrefs[&var] = &set; 267 } 268 SetNeedAnotherPass(bool need)269 void SetNeedAnotherPass(bool need) 270 { 271 needAnotherPass = need; 272 } 273 GetNeedAnotherPass()274 bool GetNeedAnotherPass() const 275 { 276 return needAnotherPass; 277 } 278 GetDumpStmtNum()279 bool GetDumpStmtNum() const 280 { 281 return dumpStmtNum; 282 } 283 SetDumpStmtNum(bool num)284 void SetDumpStmtNum(bool num) 285 { 286 dumpStmtNum = num; 287 } GetExprUseInfo()288 const MeExprUseInfo &GetExprUseInfo() const 289 { 290 return exprUseInfo; 291 } 292 GetExprUseInfo()293 MeExprUseInfo &GetExprUseInfo() 294 { 295 return exprUseInfo; 296 } 297 298 private: 299 SSATab &ssaTab; 300 MIRModule &mirModule; 301 MapleAllocator irMapAlloc; 302 int32 exprID = 0; // for allocating exprid_ in MeExpr 303 uint32 mapHashLength; // size of hashTable 304 MapleVector<MeExpr *> hashTable; // the value number hash table 305 MapleVector<MeExpr *> verst2MeExprTable; // map versionst to MeExpr. 306 MapleUnorderedMap<OStIdx, RegMeExpr *> lpreTmps; // for passing LPRE's temp usage to SPRE 307 MapleUnorderedMap<VarMeExpr *, MapleSet<MeStmt *> *> vst2Decrefs; // map versionst to decrefreset. 308 MeExprUseInfo exprUseInfo; 309 bool needAnotherPass = false; // set to true if CFG has changed 310 bool dumpStmtNum = false; 311 BB *curBB = nullptr; // current maple_me::BB being visited 312 313 bool ReplaceMeExprStmtOpnd(uint32, MeStmt &, const MeExpr &, MeExpr &); 314 void PutToBucket(uint32, MeExpr &); 315 const BB *GetFalseBrBB(const CondGotoMeStmt &); 316 MeExpr *ReplaceMeExprExpr(MeExpr &origExpr, MeExpr &newExpr, size_t opndsSize, const MeExpr &meExpr, 317 MeExpr &repExpr); 318 MeExpr *SimplifyCompareSameExpr(OpMeExpr *opmeexpr); 319 bool IfMeExprIsU1Type(const MeExpr *expr) const; 320 }; 321 } // namespace maple 322 #endif // MAPLE_ME_INCLUDE_IRMAP_H 323