From 5fcbeb77f394c9f4233e29f6cfd5c803f8485f7b Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 20 May 2021 20:03:48 -0700 Subject: [PATCH 1/5] Merged strength reduction optimization from incubator; not turned on yet --- .../maple_ipa/src/ipa_escape_analysis.cpp | 4 +- src/mapleall/maple_me/BUILD.gn | 1 + src/mapleall/maple_me/include/me_ir.h | 48 ++- src/mapleall/maple_me/include/me_option.h | 1 + src/mapleall/maple_me/include/me_stmt_pre.h | 1 - src/mapleall/maple_me/include/occur.h | 10 +- src/mapleall/maple_me/include/ssa_epre.h | 39 +- src/mapleall/maple_me/include/ssa_pre.h | 14 +- src/mapleall/maple_me/src/hdse.cpp | 4 +- src/mapleall/maple_me/src/ipa_side_effect.cpp | 6 +- src/mapleall/maple_me/src/irmap_build.cpp | 33 +- src/mapleall/maple_me/src/me_delegate_rc.cpp | 8 +- src/mapleall/maple_me/src/me_gc_lowering.cpp | 2 +- src/mapleall/maple_me/src/me_ir.cpp | 26 +- .../maple_me/src/me_loop_unrolling.cpp | 2 +- src/mapleall/maple_me/src/me_may2dassign.cpp | 2 +- src/mapleall/maple_me/src/me_option.cpp | 15 + src/mapleall/maple_me/src/me_placement_rc.cpp | 2 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 4 +- src/mapleall/maple_me/src/me_ssa_epre.cpp | 3 + src/mapleall/maple_me/src/me_ssa_lpre.cpp | 6 +- src/mapleall/maple_me/src/me_ssa_update.cpp | 2 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 22 +- src/mapleall/maple_me/src/me_store_pre.cpp | 2 +- src/mapleall/maple_me/src/occur.cpp | 2 +- src/mapleall/maple_me/src/prop.cpp | 26 +- src/mapleall/maple_me/src/ssa_epre.cpp | 221 +++++------ src/mapleall/maple_me/src/ssa_epre_for_sr.cpp | 329 ++++++++++++++++ src/mapleall/maple_me/src/ssa_pre.cpp | 367 +++++++++--------- 29 files changed, 800 insertions(+), 402 deletions(-) create mode 100644 src/mapleall/maple_me/src/ssa_epre_for_sr.cpp diff --git a/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp b/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp index 4496628398..d4e3c75968 100644 --- a/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp +++ b/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp @@ -592,7 +592,7 @@ void IPAEscapeAnalysis::UpdateEscConnGraphWithStmt(MeStmt &stmt) { break; } CHECK_FATAL(IsExprRefOrPtr(*dasgn->GetRHS()), "type mis-match"); - EACGRefNode *lhsNode = GetOrCreateCGRefNodeForVar(*dasgn->GetVarLHS(), false); + EACGRefNode *lhsNode = GetOrCreateCGRefNodeForVar(*static_cast(dasgn->GetVarLHS()), false); std::vector rhsNodes; GetCGNodeForMeExpr(rhsNodes, *dasgn->GetRHS(), stmt, true); @@ -628,7 +628,7 @@ void IPAEscapeAnalysis::UpdateEscConnGraphWithStmt(MeStmt &stmt) { for (std::pair it : *mdass->GetChiList()) { ChiMeNode *chi = it.second; CHECK_FATAL(IsExprRefOrPtr(*chi->GetLHS()), "type mis-match"); - EACGRefNode *lhsNode = GetOrCreateCGRefNodeForVar(*chi->GetLHS(), false); + EACGRefNode *lhsNode = GetOrCreateCGRefNodeForVar(*static_cast(chi->GetLHS()), false); std::vector rhsNodes; GetCGNodeForMeExpr(rhsNodes, *mdass->GetRHS(), stmt, true); for (const auto &rhsNode : rhsNodes) { diff --git a/src/mapleall/maple_me/BUILD.gn b/src/mapleall/maple_me/BUILD.gn index b6299f9976..2f8e6db555 100755 --- a/src/mapleall/maple_me/BUILD.gn +++ b/src/mapleall/maple_me/BUILD.gn @@ -71,6 +71,7 @@ src_libmplme = [ "src/me_ssa_lpre.cpp", "src/me_ssu_pre.cpp", "src/ssa_epre.cpp", + "src/ssa_epre_for_sr.cpp", "src/ssa_pre.cpp", "src/occur.cpp", "src/me_inequality_graph.cpp", diff --git a/src/mapleall/maple_me/include/me_ir.h b/src/mapleall/maple_me/include/me_ir.h index e22b5974ee..80041f17cd 100644 --- a/src/mapleall/maple_me/include/me_ir.h +++ b/src/mapleall/maple_me/include/me_ir.h @@ -163,8 +163,10 @@ class MeExpr { virtual uint32 GetHashIndex() const { return 0; } + virtual bool StrengthReducible() { return false; } + virtual int64 SRMultiplier() { return 1; } - private: + protected: MeExpr *FindSymAppearance(OStIdx oidx); // find the appearance of the symbol bool IsDexMerge() const; @@ -864,6 +866,8 @@ class OpMeExpr : public MeExpr { } return nullptr; } + bool StrengthReducible() override; + int64 SRMultiplier() override; private: std::array opnds = { nullptr }; // kid @@ -967,13 +971,13 @@ class IvarMeExpr : public MeExpr { volatileFromBaseSymbol = value; } - VarMeExpr *GetMu() { + ScalarMeExpr *GetMu() { return mu; } - const VarMeExpr *GetMu() const { + const ScalarMeExpr *GetMu() const { return mu; } - void SetMuVal(VarMeExpr *muVal) { + void SetMuVal(ScalarMeExpr *muVal) { mu = muVal; } @@ -998,7 +1002,7 @@ class IvarMeExpr : public MeExpr { FieldID fieldID = 0; bool maybeNull = true; // false if definitely not null bool volatileFromBaseSymbol = false; // volatile due to its base symbol being volatile - VarMeExpr *mu = nullptr; // use of mu, only one for IvarMeExpr + ScalarMeExpr *mu = nullptr; // use of mu, only one for IvarMeExpr }; // for array, intrinsicop and intrinsicopwithtype @@ -1217,11 +1221,11 @@ class MeStmt { return nullptr; } - virtual VarMeExpr *GetVarLHS() const { + virtual ScalarMeExpr *GetVarLHS() const { return nullptr; } - virtual VarMeExpr *GetVarLHS() { + virtual ScalarMeExpr *GetVarLHS() { return nullptr; } @@ -1323,23 +1327,23 @@ class ChiMeNode { isLive = value; } - VarMeExpr *GetRHS() { + ScalarMeExpr *GetRHS() { return rhs; } - const VarMeExpr *GetRHS() const { + const ScalarMeExpr *GetRHS() const { return rhs; } - void SetRHS(VarMeExpr *value) { + void SetRHS(ScalarMeExpr *value) { rhs = value; } - VarMeExpr *GetLHS() const { + ScalarMeExpr *GetLHS() const { return lhs; } - void SetLHS(VarMeExpr *value) { + void SetLHS(ScalarMeExpr *value) { lhs = value; } @@ -1354,8 +1358,8 @@ class ChiMeNode { } private: - VarMeExpr *rhs = nullptr; - VarMeExpr *lhs = nullptr; + ScalarMeExpr *rhs = nullptr; + ScalarMeExpr *lhs = nullptr; MeStmt *base; bool isLive = true; }; @@ -1563,6 +1567,8 @@ class AssignMeStmt : public MeStmt { ScalarMeExpr *lhs = nullptr; bool needIncref = false; // to be determined by analyzerc phase bool needDecref = false; // to be determined by analyzerc phase + public: + bool isIncDecStmt = false;// has the form of an increment or decrement stmt }; class DassignMeStmt : public AssignMeStmt { @@ -1607,11 +1613,11 @@ class DassignMeStmt : public AssignMeStmt { void Dump(const IRMap*) const; - VarMeExpr *GetVarLHS() const { + ScalarMeExpr *GetVarLHS() const { return static_cast(lhs); } - VarMeExpr *GetVarLHS() { + ScalarMeExpr *GetVarLHS() { return static_cast(lhs); } @@ -1706,7 +1712,7 @@ class MaydassignMeStmt : public MeStmt { } void Dump(const IRMap*) const; - VarMeExpr *GetLHS() const { + ScalarMeExpr *GetLHS() const { return chiList.find(mayDSSym->GetIndex())->second->GetLHS(); } @@ -1718,11 +1724,11 @@ class MaydassignMeStmt : public MeStmt { rhs = value; } - VarMeExpr *GetVarLHS() const { + ScalarMeExpr *GetVarLHS() const { return chiList.find(mayDSSym->GetIndex())->second->GetLHS(); } - VarMeExpr *GetVarLHS() { + ScalarMeExpr *GetVarLHS() { return chiList.find(mayDSSym->GetIndex())->second->GetLHS(); } @@ -2040,7 +2046,7 @@ class CallMeStmt : public NaryMeStmt, public MuChiMePart, public AssignedPart { return GetAssignedPartLHSRef(excludeLocalRefVar); } - VarMeExpr *GetVarLHS() { + ScalarMeExpr *GetVarLHS() { if (mustDefList.empty() || mustDefList.front().GetLHS()->GetMeOp() != kMeOpVar) { return nullptr; } @@ -2656,7 +2662,7 @@ class AssertMeStmt : public MeStmt { } }; -MapleMap *GenericGetChiListFromVarMeExpr(VarMeExpr &expr); +MapleMap *GenericGetChiListFromVarMeExpr(ScalarMeExpr &expr); void DumpMuList(const IRMap *irMap, const MapleMap &muList); void DumpChiList(const IRMap *irMap, const MapleMap &chiList); class DumpOptions { diff --git a/src/mapleall/maple_me/include/me_option.h b/src/mapleall/maple_me/include/me_option.h index 5d4112e588..61f8eaf7d0 100644 --- a/src/mapleall/maple_me/include/me_option.h +++ b/src/mapleall/maple_me/include/me_option.h @@ -122,6 +122,7 @@ class MeOption : public MapleDriverOptionBase { static bool placementRC; static bool subsumRC; static bool performFSAA; + static bool strengthReduction; static std::string inlineFuncList; static bool meVerify; #if MIR_JAVA diff --git a/src/mapleall/maple_me/include/me_stmt_pre.h b/src/mapleall/maple_me/include/me_stmt_pre.h index 452dc730e3..cc02f07e3d 100644 --- a/src/mapleall/maple_me/include/me_stmt_pre.h +++ b/src/mapleall/maple_me/include/me_stmt_pre.h @@ -60,7 +60,6 @@ class MeStmtPre : public SSAEPre { bool AllVarsSameVersionStmtFre(MeRealOcc &topOcc, MeRealOcc &curOcc) const; void CollectVarForMeStmt(const MeStmt &meStmt, MeExpr *meExpr, std::vector &varVec) const; void CollectVarForCand(MeRealOcc &realOcc, std::vector &varVec) const override; - MeStmt *CopyMeStmt(const MeStmt &meStmt) const override; MeStmt *PhiOpndFromRes4Stmt(MeRealOcc &realZ, size_t j, MeExpr *&lhsVar) const; void Rename1StmtFre(); void Rename2() override; diff --git a/src/mapleall/maple_me/include/occur.h b/src/mapleall/maple_me/include/occur.h index fe49e47319..96f2633637 100644 --- a/src/mapleall/maple_me/include/occur.h +++ b/src/mapleall/maple_me/include/occur.h @@ -272,7 +272,8 @@ class MePhiOpndOcc : public MeOccur { hasRealUse(false), isInsertedOcc(false), isPhiOpndReload(false), - defPhiOcc(nullptr) { + defPhiOcc(nullptr), + phiOpnd4Temp(nullptr) { currentExpr.meStmt = nullptr; } @@ -357,6 +358,8 @@ class MePhiOpndOcc : public MeOccur { MeExpr *meExpr; // the current expression at the end of the block containing this PhiOpnd MeStmt *meStmt; // which will be inserted during finalize } currentExpr; + public: + MeExpr *phiOpnd4Temp; // must be a VarMeExpr/RegMeExpr, set in CodeMotion phase }; class MePhiOcc : public MeOccur { @@ -498,7 +501,8 @@ class PreWorkCand { puIdx(pIdx), hasLocalOpnd(false), redo2HandleCritEdges(false), - needLocalRefVar(false) { + needLocalRefVar(false), + isSRCand(false) { ASSERT(pIdx != 0, "PreWorkCand: initial puIdx cannot be 0"); } @@ -626,6 +630,8 @@ class PreWorkCand { // puIdx cannot be 0 if hasLocalOpnd is true bool redo2HandleCritEdges : 1; // redo to make critical edges affect canbevail bool needLocalRefVar : 1; // for the candidate, if necessary to introduce + public: + bool isSRCand : 1; // is a strength reduction candidate // localrefvar in addition to the temp register to for saving the value }; diff --git a/src/mapleall/maple_me/include/ssa_epre.h b/src/mapleall/maple_me/include/ssa_epre.h index 0bdae5a953..88e5833eab 100644 --- a/src/mapleall/maple_me/include/ssa_epre.h +++ b/src/mapleall/maple_me/include/ssa_epre.h @@ -28,15 +28,15 @@ class SSAEPre : public SSAPre { private: MeExpr *GetTruncExpr(const IvarMeExpr &theLHS, MeExpr &savedRHS); void GenerateSaveLHSRealocc(MeRealOcc &realOcc, ScalarMeExpr ®OrVar); - void GenerateSaveRealOcc(MeRealOcc &realOcc); + void GenerateSaveRealOcc(MeRealOcc &realOcc) override; bool ReserveCalFuncAddrForDecouple(MeExpr &meExpr) const; - void GenerateReloadRealOcc(MeRealOcc &realOcc); - MeExpr *PhiOpndFromRes(MeRealOcc &realZ, size_t j) const; - void ComputeVarAndDfPhis(); - void BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr&, bool isReBuild, MeExpr *tempVar, bool isRootExpr); - void BuildWorkListIvarLHSOcc(MeStmt &meStmt, int32 seqStmt, bool isReBuild, MeExpr *tempVar); - void CollectVarForMeExpr(MeExpr &meExpr, std::vector &varVec) const; - void CollectVarForCand(MeRealOcc &realOcc, std::vector &varVec) const; + void GenerateReloadRealOcc(MeRealOcc &realOcc) override; + MeExpr *PhiOpndFromRes(MeRealOcc &realZ, size_t j) const override; + void ComputeVarAndDfPhis() override; + void BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr&, bool isReBuild, MeExpr *tempVar, bool isRootExpr) override; + void BuildWorkListIvarLHSOcc(MeStmt &meStmt, int32 seqStmt, bool isReBuild, MeExpr *tempVar) override; + void CollectVarForMeExpr(MeExpr &meExpr, std::vector &varVec) const override; + void CollectVarForCand(MeRealOcc &realOcc, std::vector &varVec) const override; bool LeafIsVolatile(const MeExpr *x) const { const VarMeExpr *v = safe_cast(x); return v != nullptr && v->IsVolatile(); @@ -49,7 +49,30 @@ class SSAEPre : public SSAPre { virtual bool CfgHasDoWhile() const { return false; } + // here starts methods related to strength reduction + bool AllVarsSameVersion(const MeRealOcc &realocc1, const MeRealOcc &realocc2) const override; + VarMeExpr *ResolveAllInjuringDefs(VarMeExpr *varx) const override; + RegMeExpr *ResolveAllInjuringDefs(RegMeExpr *regx) const override; + MeExpr *ResolveAllInjuringDefs(MeExpr *x) const override { + if (!workCand->isSRCand) { + return x; + } + return (x->GetMeOp() == kMeOpVar) ? + static_cast(ResolveAllInjuringDefs(static_cast(x))) : + static_cast(ResolveAllInjuringDefs(static_cast(x))); + } + void SubstituteOpnd(MeExpr *x, MeExpr *oldopnd, MeExpr *newopnd) override; + bool OpndInDefOcc(MeExpr *opnd, MeOccur *defocc, uint32 i); + void SRSetNeedRepair(MeOccur *useocc, std::set *needRepairInjuringDefs) override; + MeExpr *InsertRepairStmt(MeExpr *temp, int64 increAmt, MeStmt *injuringDef); + MeExpr *SRRepairOpndInjuries(MeExpr *curopnd, MeOccur *defocc, int32 i, + MeExpr *tempAtDef, std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs); + MeExpr *SRRepairInjuries(MeOccur *useocc, + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) override; + private: bool epreIncludeRef; bool enableLHSIvar; }; diff --git a/src/mapleall/maple_me/include/ssa_pre.h b/src/mapleall/maple_me/include/ssa_pre.h index f34556ed1d..f91b312f8d 100644 --- a/src/mapleall/maple_me/include/ssa_pre.h +++ b/src/mapleall/maple_me/include/ssa_pre.h @@ -60,8 +60,6 @@ class SSAPre { return workCand->GetRealOccs(); } - virtual MeExpr *CopyMeExpr(const MeExpr &expr) const; - virtual MeStmt *CopyMeStmt(const MeStmt &meStmt) const; virtual IassignMeStmt *CopyIassignMeStmt(const IassignMeStmt &iaStmt) const; void IncTreeid() { // Incremented by 2 for each tree; purpose is to avoid processing a node the third time inside a tree @@ -166,7 +164,7 @@ class SSAPre { virtual MeExpr *PhiOpndFromRes(MeRealOcc &realOcc, size_t i) const = 0; virtual void Rename2(); // step 1 phi insertion methods - void SetVarPhis(const MeExpr &meExpr); + void SetVarPhis(MeExpr *meExpr); virtual void ComputeVarAndDfPhis() = 0; virtual void CreateSortedOccs(); // phi insertion methods end @@ -202,6 +200,14 @@ class SSAPre { virtual bool IsLoopHeadBB(BBId) const { return false; } + virtual VarMeExpr *ResolveAllInjuringDefs(VarMeExpr *varx) const { return varx; } + virtual RegMeExpr *ResolveAllInjuringDefs(RegMeExpr *regx) const { return regx; } + virtual MeExpr *ResolveAllInjuringDefs(MeExpr *x) const { return x; } + virtual void SubstituteOpnd(MeExpr *x, MeExpr *oldopnd, MeExpr *newopnd) {} + virtual void SRSetNeedRepair(MeOccur *useocc, std::set *needRepairInjuringDefs) {} + virtual MeExpr *SRRepairInjuries(MeOccur *useocc, + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) { return nullptr; } IRMap *irMap; SSATab *ssaTab; @@ -251,6 +257,8 @@ class SSAPre { bool spillAtCatch = false; bool placementRCEnabled = false; bool addedNewLocalRefVars = false; + public: + bool strengthReduction = false; }; } // namespace maple #endif // MAPLE_ME_INCLUDE_SSAPRE_H diff --git a/src/mapleall/maple_me/src/hdse.cpp b/src/mapleall/maple_me/src/hdse.cpp index 11422e2f38..baac26f90a 100644 --- a/src/mapleall/maple_me/src/hdse.cpp +++ b/src/mapleall/maple_me/src/hdse.cpp @@ -420,7 +420,7 @@ bool HDSE::HasNonDeletableExpr(const MeStmt &meStmt) const { switch (op) { case OP_dassign: { auto &dasgn = static_cast(meStmt); - VarMeExpr *varMeExpr = dasgn.GetVarLHS(); + VarMeExpr *varMeExpr = static_cast(dasgn.GetVarLHS()); return (varMeExpr != nullptr && varMeExpr->IsVolatile()) || ExprNonDeletable(*dasgn.GetRHS()) || (hdseKeepRef && dasgn.Propagated()) || dasgn.GetWasMayDassign() || (decoupleStatic && varMeExpr->GetOst()->GetMIRSymbol()->IsGlobal()); @@ -516,7 +516,7 @@ void HDSE::MarkSingleUseLive(MeExpr &meExpr) { case kMeOpIvar: { auto *base = static_cast(meExpr).GetBase(); MarkSingleUseLive(*base); - VarMeExpr *mu = static_cast(meExpr).GetMu(); + ScalarMeExpr *mu = static_cast(meExpr).GetMu(); workList.push_front(mu); if (mu->GetDefBy() != kDefByNo) { MapleMap *chiList = GenericGetChiListFromVarMeExpr(*mu); diff --git a/src/mapleall/maple_me/src/ipa_side_effect.cpp b/src/mapleall/maple_me/src/ipa_side_effect.cpp index bf976c238c..227b4f2f48 100644 --- a/src/mapleall/maple_me/src/ipa_side_effect.cpp +++ b/src/mapleall/maple_me/src/ipa_side_effect.cpp @@ -738,7 +738,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, AnalyzeExpr(*meStmt.GetOpnd(i), globalExprs, argExprs, nextLevelGlobalExprs, nextLevelArgExprs); } DassignMeStmt &dassignNode = static_cast(meStmt); - VarMeExpr *lhsVar = dassignNode.GetVarLHS(); + VarMeExpr *lhsVar = static_cast(dassignNode.GetVarLHS()); const OriginalSt *ost = meFunc.GetMeSSATab()->GetSymbolOriginalStFromID(lhsVar->GetOstIdx()); if (ost->GetMIRSymbol()->IsGlobal()) { SetHasDef(); @@ -760,10 +760,10 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, SetHasDef(); } if (isGlobal) { - (void)globalExprs.insert(dassignNode.GetChiList()->begin()->second->GetLHS()); + (void)globalExprs.insert(static_cast(dassignNode.GetChiList()->begin()->second->GetLHS())); } if (isArg) { - (void)argExprs.insert(dassignNode.GetChiList()->begin()->second->GetLHS()); + (void)argExprs.insert(static_cast(dassignNode.GetChiList()->begin()->second->GetLHS())); } break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 12e42f0187..f6ccda62eb 100644 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -77,9 +77,20 @@ void IRMapBuild::BuildChiList(MeStmt &meStmt, TypeOfMayDefList &mayDefNodes, for (auto &mayDefNode : mayDefNodes) { VersionSt *opndSt = mayDefNode.GetOpnd(); VersionSt *resSt = mayDefNode.GetResult(); + auto *chiMeStmt = irMap->New(&meStmt); - chiMeStmt->SetRHS(GetOrCreateVarFromVerSt(*opndSt)); - VarMeExpr *lhs = GetOrCreateVarFromVerSt(*resSt); + if (opndSt->GetOst()->IsSymbolOst()) { + chiMeStmt->SetRHS(GetOrCreateVarFromVerSt(*opndSt)); + } else { + chiMeStmt->SetRHS(GetOrCreateRegFromVerSt(*opndSt)); + } + + ScalarMeExpr *lhs = nullptr; + if (resSt->GetOst()->IsSymbolOst()) { + lhs = GetOrCreateVarFromVerSt(*resSt); + } else { + lhs = GetOrCreateRegFromVerSt(*resSt); + } lhs->SetDefBy(kDefByChi); lhs->SetDefChi(*chiMeStmt); chiMeStmt->SetLHS(lhs); @@ -513,6 +524,16 @@ MeStmt *IRMapBuild::BuildDassignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) VarMeExpr *varLHS = static_cast(BuildLHSVar(*ssaPart.GetSSAVar(), *meStmt)); meStmt->SetLHS(varLHS); BuildChiList(*meStmt, ssaPart.GetMayDefNodes(), *meStmt->GetChiList()); + // determine isIncDecStmt + if (meStmt->GetChiList()->empty()) { + MeExpr *rhs = meStmt->GetRHS(); + if (rhs->GetOp() == OP_add || rhs->GetOp() == OP_sub) { + OpMeExpr *oprhs = static_cast(rhs); + if (oprhs->GetOpnd(0)->GetMeOp() == kMeOpVar && oprhs->GetOpnd(1)->GetMeOp() == kMeOpConst) { + meStmt->isIncDecStmt = varLHS->GetOst() == static_cast(oprhs->GetOpnd(0))->GetOst(); + } + } + } if (propagater) { propagater->PropUpdateDef(*meStmt->GetLHS()); propagater->PropUpdateChiListDef(*meStmt->GetChiList()); @@ -526,6 +547,14 @@ MeStmt *IRMapBuild::BuildAssignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { meStmt->SetRHS(BuildExpr(*regNode.Opnd(0), false, false)); auto *regLHS = static_cast(BuildLHSReg(*ssaPart.GetSSAVar(), *meStmt, regNode)); meStmt->SetLHS(regLHS); + // determine isIncDecStmt + MeExpr *rhs = meStmt->GetRHS(); + if (rhs->GetOp() == OP_add || rhs->GetOp() == OP_sub) { + OpMeExpr *oprhs = static_cast(rhs); + if (oprhs->GetOpnd(0)->GetMeOp() == kMeOpReg && oprhs->GetOpnd(1)->GetMeOp() == kMeOpConst) { + meStmt->isIncDecStmt = regLHS->GetOst() == static_cast(oprhs->GetOpnd(0))->GetOst(); + } + } if (propagater) { propagater->PropUpdateDef(*meStmt->GetLHS()); } diff --git a/src/mapleall/maple_me/src/me_delegate_rc.cpp b/src/mapleall/maple_me/src/me_delegate_rc.cpp index 50c0b4d8fd..6e10df2fa5 100644 --- a/src/mapleall/maple_me/src/me_delegate_rc.cpp +++ b/src/mapleall/maple_me/src/me_delegate_rc.cpp @@ -421,7 +421,7 @@ void DelegateRC::DelegateRCTemp(MeStmt &stmt) { if (!stmt.NeedIncref()) { break; } - VarMeExpr *lhsVar = stmt.GetVarLHS(); + ScalarMeExpr *lhsVar = stmt.GetVarLHS(); CHECK_FATAL(lhsVar != nullptr, "null lhs check"); const OriginalSt *ost = lhsVar->GetOst(); if (Options::lazyBinding != 0 || !ost->GetMIRSymbol()->IsGlobal()) { @@ -538,7 +538,7 @@ bool DelegateRC::CanOmitRC4LHSVar(const MeStmt &stmt, bool &onlyWithDecref) cons switch (stmt.GetOp()) { case OP_dassign: case OP_maydassign: { - const VarMeExpr *theLhs = stmt.GetVarLHS(); + const VarMeExpr *theLhs = static_cast(stmt.GetVarLHS()); MeExpr *theRhs = stmt.GetRHS(); CHECK_FATAL(theLhs != nullptr, "null ptr check"); CHECK_FATAL(theRhs != nullptr, "null ptr check"); @@ -623,7 +623,7 @@ void DelegateRC::DelegateHandleNoRCStmt(MeStmt &stmt, bool addDecref) { VarMeExpr *theLhs = nullptr; MeExpr *rhsExpr = stmt.GetRHS(); if (CheckOp(stmt, OP_dassign) || CheckOp(stmt, OP_maydassign)) { - theLhs = stmt.GetVarLHS(); + theLhs = static_cast(stmt.GetVarLHS()); } else if (kOpcodeInfo.IsCallAssigned(stmt.GetOp()) && addDecref) { theLhs = static_cast(stmt.GetAssignedLHS()); } else { @@ -744,7 +744,7 @@ std::set DelegateRC::RenameAndGetLiveLocalRefVar() { } // for live_localrefvars if (CheckOp(stmt, OP_dassign) || CheckOp(stmt, OP_maydassign)) { - VarMeExpr *lhs = stmt.GetVarLHS(); + ScalarMeExpr *lhs = stmt.GetVarLHS(); CHECK_FATAL(lhs != nullptr, "null ptr check"); const OriginalSt *ost = lhs->GetOst(); if (ost->IsLocal() && !ost->IsFormal() && !ost->IsIgnoreRC() && lhs->GetPrimType() == PTY_ref) { diff --git a/src/mapleall/maple_me/src/me_gc_lowering.cpp b/src/mapleall/maple_me/src/me_gc_lowering.cpp index cb1e8e0a8e..448ca9b54d 100644 --- a/src/mapleall/maple_me/src/me_gc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_gc_lowering.cpp @@ -89,7 +89,7 @@ void GCLowering::HandleAssignMeStmt(MeStmt &stmt) { } void GCLowering::HandleVarAssignMeStmt(MeStmt &stmt) { - VarMeExpr *lhsVar = stmt.GetVarLHS(); + VarMeExpr *lhsVar = static_cast(stmt.GetVarLHS()); ASSERT_NOT_NULL(lhsVar); MIRSymbol *lSym = ssaTab.GetMIRSymbolFromID(lhsVar->GetOstIdx()); if (lSym == nullptr || !lSym->IsGlobal()) { diff --git a/src/mapleall/maple_me/src/me_ir.cpp b/src/mapleall/maple_me/src/me_ir.cpp index f006fb2b67..c257bf5317 100644 --- a/src/mapleall/maple_me/src/me_ir.cpp +++ b/src/mapleall/maple_me/src/me_ir.cpp @@ -567,6 +567,20 @@ MeExpr *OpMeExpr::GetIdenticalExpr(MeExpr &expr, bool isConstructor) const { return nullptr; } +bool OpMeExpr::StrengthReducible() { + if (op != OP_mul || !IsPrimitiveInteger(primType)) { + return false; + } + return GetOpnd(1)->GetOp() == OP_constval; +} + +int64 OpMeExpr::SRMultiplier() { + ASSERT(StrengthReducible(), "OpMeExpr::SRMultiplier: operation is not strength reducible"); + MIRConst *constVal = static_cast(GetOpnd(1))->GetConstVal(); + ASSERT(constVal->GetKind() == kConstInt, "OpMeExpr::SRMultiplier: multiplier not an integer constant"); + return static_cast(constVal)->GetValueUnderType(); +} + // first, make sure it's int const and return true if the int const great or eq 0 bool ConstMeExpr::GeZero() const { return (GetIntValue() >= 0); @@ -919,7 +933,7 @@ void NaryMeExpr::Dump(const IRMap *irMap, int32 indent) const { } MeExpr *DassignMeStmt::GetLHSRef(bool excludeLocalRefVar) { - VarMeExpr *lhsOpnd = GetVarLHS(); + ScalarMeExpr *lhsOpnd = GetVarLHS(); if (lhsOpnd->GetPrimType() != PTY_ref) { return nullptr; } @@ -934,7 +948,7 @@ MeExpr *DassignMeStmt::GetLHSRef(bool excludeLocalRefVar) { } MeExpr *MaydassignMeStmt::GetLHSRef(bool excludeLocalRefVar) { - VarMeExpr *lhs = GetVarLHS(); + ScalarMeExpr *lhs = GetVarLHS(); if (lhs->GetPrimType() != PTY_ref) { return nullptr; } @@ -1474,8 +1488,8 @@ bool MeExpr::PointsToSomethingThatNeedsIncRef() { return false; } -MapleMap *GenericGetChiListFromVarMeExprInner(VarMeExpr &expr, - std::unordered_set &visited) { +MapleMap *GenericGetChiListFromVarMeExprInner(ScalarMeExpr &expr, + std::unordered_set &visited) { if (expr.GetDefBy() == kDefByNo || visited.find(&expr) != visited.end()) { return nullptr; } @@ -1498,8 +1512,8 @@ MapleMap *GenericGetChiListFromVarMeExprInner(VarMeExpr &exp return nullptr; } -MapleMap *GenericGetChiListFromVarMeExpr(VarMeExpr &expr) { - std::unordered_set visited; +MapleMap *GenericGetChiListFromVarMeExpr(ScalarMeExpr &expr) { + std::unordered_set visited; return GenericGetChiListFromVarMeExprInner(expr, visited); } diff --git a/src/mapleall/maple_me/src/me_loop_unrolling.cpp b/src/mapleall/maple_me/src/me_loop_unrolling.cpp index 0a093322a6..000fcdead3 100644 --- a/src/mapleall/maple_me/src/me_loop_unrolling.cpp +++ b/src/mapleall/maple_me/src/me_loop_unrolling.cpp @@ -74,7 +74,7 @@ void LoopUnrolling::BuildMustDefList(const BB &bb, MeStmt &newStmt, const MapleV } void LoopUnrolling::CopyDassignStmt(const MeStmt &stmt, BB &bb) { - VarMeExpr *varLHS = static_cast(&stmt)->GetVarLHS(); + VarMeExpr *varLHS = static_cast(static_cast(&stmt)->GetVarLHS()); VarMeExpr *newVarLHS = irMap->CreateVarMeExprVersion(varLHS->GetOst()); InsertCandsForSSAUpdate(newVarLHS->GetOstIdx(), bb); bb.AddMeStmtLast(irMap->CreateAssignMeStmt(*newVarLHS, *stmt.GetRHS(), bb)); diff --git a/src/mapleall/maple_me/src/me_may2dassign.cpp b/src/mapleall/maple_me/src/me_may2dassign.cpp index fda6103494..407f0dd28a 100644 --- a/src/mapleall/maple_me/src/me_may2dassign.cpp +++ b/src/mapleall/maple_me/src/me_may2dassign.cpp @@ -28,7 +28,7 @@ void May2Dassign::DoIt() { auto &mass = static_cast(stmt); // chiList for Maydassign has only 1 element CHECK_FATAL(!mass.GetChiList()->empty(), "chiList is empty in DoIt"); - VarMeExpr *theLhs = mass.GetChiList()->begin()->second->GetLHS(); + VarMeExpr *theLhs = static_cast(mass.GetChiList()->begin()->second->GetLHS()); ASSERT(mass.GetMayDassignSym() == theLhs->GetOst(), "MeDoMay2Dassign: cannot find maydassign lhs"); auto *dass = static_cast(irMap->CreateAssignMeStmt(*theLhs, *mass.GetRHS(), *bb)); diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index ceb474ab4a..4087f4ae04 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -96,6 +96,7 @@ bool MeOption::enableEA = false; bool MeOption::placementRC = false; bool MeOption::subsumRC = false; bool MeOption::performFSAA = true; +bool MeOption::strengthReduction = false; std::string MeOption::inlineFuncList = ""; bool MeOption::meVerify = false; #if MIR_JAVA @@ -183,6 +184,7 @@ enum OptionIndex { kAssign2finalPre, kSubsumRC, kPerformFSAA, + kStrengthReduction, kRegReadAtReturn, kProPatphi, kNoProPatphi, @@ -760,6 +762,16 @@ const Descriptor kUsage[] = { " --no-performFSAA \tDisable flow sensitive alias analysis\n", "me", {} }, + { kStrengthReduction, + kEnable, + "", + "strengthReduction", + kBuildTypeExperimental, + kArgCheckPolicyBool, + " --strengthReduction \tPerform flow sensitive alias analysis\n" + " --no-strengthReduction \tDisable flow sensitive alias analysis\n", + "me", + {} }, { kCheckCastOpt, kEnable, "", @@ -1341,6 +1353,9 @@ bool MeOption::SolveOptions(const std::vector &opts, bool i case kPerformFSAA: performFSAA = (opt.Type() == kEnable); break; + case kStrengthReduction: + strengthReduction = (opt.Type() == kEnable); + break; case kMeInlineHint: inlineFuncList = opt.Args(); break; diff --git a/src/mapleall/maple_me/src/me_placement_rc.cpp b/src/mapleall/maple_me/src/me_placement_rc.cpp index 8592c4e611..00be1e595d 100644 --- a/src/mapleall/maple_me/src/me_placement_rc.cpp +++ b/src/mapleall/maple_me/src/me_placement_rc.cpp @@ -306,7 +306,7 @@ MeStmt *PlacementRC::GetDefStmt(BB &bb) { if (bb.GetAttributes(kBBAttrIsTry)) { for (auto &stmt : bb.GetMeStmts()) { if (stmt.GetOp() == OP_dassign || stmt.GetOp() == OP_maydassign) { - VarMeExpr *lhs = stmt.GetVarLHS(); + VarMeExpr *lhs = static_cast(stmt.GetVarLHS()); CHECK_NULL_FATAL(lhs); if (lhs->GetOst() == workCand->GetTheVar()->GetOst()) { defStmt = &stmt; diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index d9c914f4d4..b87ac307c6 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -681,7 +681,7 @@ void RCLowering::HandleAssignMeStmt(MeStmt &stmt, MeExpr *pendingDec) { } void RCLowering::HandlePerManent(MeStmt &stmt) { - VarMeExpr *lhs = stmt.GetVarLHS(); + VarMeExpr *lhs = static_cast(stmt.GetVarLHS()); if (lhs == nullptr) { return; } @@ -1534,7 +1534,7 @@ void RCLowering::FastLowerRetReg(RetMeStmt &stmt) { } void RCLowering::FastLowerAssignToVar(MeStmt &stmt, MapleMap &exceptionAllocsites) { - VarMeExpr *lhs = stmt.GetVarLHS(); + ScalarMeExpr *lhs = stmt.GetVarLHS(); ASSERT_NOT_NULL(lhs); if (stmt.NeedIncref() || stmt.NeedDecref()) { const MIRSymbol *lSym = lhs->GetOst()->GetMIRSymbol(); diff --git a/src/mapleall/maple_me/src/me_ssa_epre.cpp b/src/mapleall/maple_me/src/me_ssa_epre.cpp index 89942763d4..737ea7ee76 100644 --- a/src/mapleall/maple_me/src/me_ssa_epre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_epre.cpp @@ -85,6 +85,9 @@ AnalysisResult *MeDoSSAEPre::Run(MeFunction *func, MeFuncResultMgr *m, ModuleRes MeSSAEPre ssaPre(*func, *irMap, *dom, kh, *ssaPreMemPool, *NewMemPool(), epreLimitUsed, epreIncludeRef, MeOption::epreLocalRefVar, MeOption::epreLHSIvar); ssaPre.SetSpillAtCatch(MeOption::spillAtCatch); + if (MeOption::strengthReduction) { + ssaPre.strengthReduction = true; + } if (func->GetHints() & kPlacementRCed) { ssaPre.SetPlacementRC(true); } diff --git a/src/mapleall/maple_me/src/me_ssa_lpre.cpp b/src/mapleall/maple_me/src/me_ssa_lpre.cpp index 7073b2dfbc..e8d666a5ae 100644 --- a/src/mapleall/maple_me/src/me_ssa_lpre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_lpre.cpp @@ -47,7 +47,7 @@ void MeSSALPre::GenerateSaveRealOcc(MeRealOcc &realOcc) { } CHECK_FATAL(i < func->GetMirFunc()->GetFormalCount(), "Cannot replace promoted formal"); } else if (realOcc.GetOpcodeOfMeStmt() == OP_dassign || realOcc.GetOpcodeOfMeStmt() == OP_maydassign) { - VarMeExpr *theLHS = realOcc.GetMeStmt()->GetVarLHS(); + VarMeExpr *theLHS = static_cast(realOcc.GetMeStmt()->GetVarLHS()); MeExpr *savedRHS = realOcc.GetMeStmt()->GetRHS(); CHECK_NULL_FATAL(theLHS); CHECK_NULL_FATAL(savedRHS); @@ -172,7 +172,7 @@ void MeSSALPre::ComputeVarAndDfPhis() { GetIterDomFrontier(defBB, &dfPhiDfns); MeExpr *meExpr = realOcc->GetMeExpr(); if (meExpr->GetMeOp() == kMeOpVar) { - SetVarPhis(*meExpr); + SetVarPhis(meExpr); } } } @@ -212,7 +212,7 @@ void MeSSALPre::BuildWorkListLHSOcc(MeStmt &meStmt, int32 seqStmt) { return; } if (meStmt.GetOp() == OP_dassign || meStmt.GetOp() == OP_maydassign) { - VarMeExpr *lhs = meStmt.GetVarLHS(); + VarMeExpr *lhs = static_cast(meStmt.GetVarLHS()); CHECK_NULL_FATAL(lhs); const OriginalSt *ost = lhs->GetOst(); if (mirModule->IsCModule()) { diff --git a/src/mapleall/maple_me/src/me_ssa_update.cpp b/src/mapleall/maple_me/src/me_ssa_update.cpp index 10505e478b..9bf234688a 100644 --- a/src/mapleall/maple_me/src/me_ssa_update.cpp +++ b/src/mapleall/maple_me/src/me_ssa_update.cpp @@ -174,7 +174,7 @@ void MeSSAUpdate::RenameStmts(BB &bb) { } } // process the LHS - VarMeExpr *lhsVar = nullptr; + ScalarMeExpr *lhsVar = nullptr; if (stmt.GetOp() == OP_dassign || stmt.GetOp() == OP_maydassign) { lhsVar = stmt.GetVarLHS(); } else if (kOpcodeInfo.IsCallAssigned(stmt.GetOp())) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index 08c71788c0..757707a7cd 100644 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -93,7 +93,7 @@ void MeStmtPre::CodeMotion() { (void)candsForSSAUpdate[ostIdx]->insert(occ->GetBB()->GetBBId()); } // create a new LHS for the dassign in insertedOcc->GetMeStmt() - VarMeExpr *newVarVersion = irMap->CreateVarMeExprVersion(*dass->GetVarLHS()); + VarMeExpr *newVarVersion = irMap->CreateVarMeExprVersion(*(static_cast(dass->GetVarLHS()))); dass->UpdateLhs(newVarVersion); } else if (insertedOcc->GetOpcodeOfMeStmt() == OP_callassigned) { auto *call = static_cast(insertedOcc->GetMeStmt()); @@ -308,7 +308,7 @@ void MeStmtPre::CollectVarForCand(MeRealOcc &realOcc, std::vector &varV CollectVarForMeStmt(*realOcc.GetMeStmt(), realOcc.GetMeExpr(), varVec); } -MeStmt *MeStmtPre::CopyMeStmt(const MeStmt &meStmt) const { +static MeStmt *CopyMeStmt(IRMap *irMap, const MeStmt &meStmt) { switch (meStmt.GetOp()) { case OP_assertnonnull: { auto *unaryStmt = static_cast(&meStmt); @@ -342,7 +342,7 @@ MeStmt *MeStmtPre::PhiOpndFromRes4Stmt(MeRealOcc &realZ, size_t j, MeExpr *&lhsV MeOccur *defZ = realZ.GetDef(); CHECK_FATAL(defZ != nullptr, "must be def by phiocc"); CHECK_FATAL(defZ->GetOccType() == kOccPhiocc, "must be def by phiocc"); - MeStmt *stmtQ = CopyMeStmt(utils::ToRef(realZ.GetMeStmt())); + MeStmt *stmtQ = CopyMeStmt(irMap, utils::ToRef(realZ.GetMeStmt())); lhsVar = realZ.GetMeExpr(); BB *phiBB = defZ->GetBB(); CHECK_FATAL(stmtQ != nullptr, "nullptr check"); @@ -500,13 +500,13 @@ void MeStmtPre::ComputeVarAndDfPhis() { switch (stmt->GetOp()) { case OP_assertnonnull: { auto *unaryStmt = static_cast(stmt); - SetVarPhis(*unaryStmt->GetOpnd()); + SetVarPhis(unaryStmt->GetOpnd()); break; } case OP_dassign: { auto *dassMeStmt = static_cast(stmt); - SetVarPhis(*dassMeStmt->GetRHS()); - SetVarPhis(*realOcc->GetMeExpr()); + SetVarPhis(dassMeStmt->GetRHS()); + SetVarPhis(realOcc->GetMeExpr()); break; } case OP_intrinsiccall: @@ -514,10 +514,10 @@ void MeStmtPre::ComputeVarAndDfPhis() { case OP_callassigned: { auto *nStmt = static_cast(stmt); for (size_t i = 0; i < nStmt->NumMeStmtOpnds(); ++i) { - SetVarPhis(*nStmt->GetOpnd(i)); + SetVarPhis(nStmt->GetOpnd(i)); } if (realOcc->GetMeExpr() != nullptr) { - SetVarPhis(*realOcc->GetMeExpr()); + SetVarPhis(realOcc->GetMeExpr()); } break; } @@ -541,7 +541,7 @@ void MeStmtPre::CreateSortedOccs() { auto *stmtWkCand = static_cast(workCand); if ((stmtWkCand->GetTheMeStmt()->GetOp() == OP_dassign || stmtWkCand->GetTheMeStmt()->GetOp() == OP_callassigned) && stmtWkCand->GetTheMeStmt()->GetVarLHS() != nullptr && !stmtWkCand->LHSIsFinal()) { - VarMeExpr *lhsVar = stmtWkCand->GetTheMeStmt()->GetVarLHS(); + VarMeExpr *lhsVar = static_cast(stmtWkCand->GetTheMeStmt()->GetVarLHS()); OStIdx ostIdx = lhsVar->GetOstIdx(); MapleMap*>::iterator uMapIt = useOccurMap.find(ostIdx); CHECK_FATAL(uMapIt != useOccurMap.end(), "MeStmtPre::CreateSortedOccs: missing entry in useOccurMap"); @@ -735,7 +735,7 @@ void MeStmtPre::ConstructUseOccurMap() { if (stmtWkCand->LHSIsFinal()) { continue; } - VarMeExpr *lhsVar = stmtWkCand->GetTheMeStmt()->GetVarLHS(); + VarMeExpr *lhsVar = static_cast(stmtWkCand->GetTheMeStmt()->GetVarLHS()); if (lhsVar == nullptr) { continue; } @@ -943,7 +943,7 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { VersionStackChiListUpdate(*dassMeStmt.GetChiList()); break; } - VarMeExpr *varMeExpr = dassMeStmt.GetVarLHS(); + VarMeExpr *varMeExpr = static_cast(dassMeStmt.GetVarLHS()); const OriginalSt *ost = varMeExpr->GetOst(); if (ost->IsFinal()) { PreStmtWorkCand *stmtWkCand = CreateStmtRealOcc(stmt, seqStmt); diff --git a/src/mapleall/maple_me/src/me_store_pre.cpp b/src/mapleall/maple_me/src/me_store_pre.cpp index e61a66b404..3a06327972 100644 --- a/src/mapleall/maple_me/src/me_store_pre.cpp +++ b/src/mapleall/maple_me/src/me_store_pre.cpp @@ -218,7 +218,7 @@ void MeStorePre::CreateRealOcc(const OStIdx &ostIdx, MeStmt &meStmt) { } if (wkCand->GetTheVar() == nullptr) { if (meStmt.GetOp() == OP_dassign) { - wkCand->SetTheVar(*static_cast(&meStmt)->GetVarLHS()); + wkCand->SetTheVar(*static_cast(static_cast(&meStmt)->GetVarLHS())); } else { ASSERT(kOpcodeInfo.IsCallAssigned(meStmt.GetOp()), "CreateRealOcc: callassign expected"); MapleVector *mustDefList = meStmt.GetMustDefList(); diff --git a/src/mapleall/maple_me/src/occur.cpp b/src/mapleall/maple_me/src/occur.cpp index 52aa54ccbe..2671631946 100644 --- a/src/mapleall/maple_me/src/occur.cpp +++ b/src/mapleall/maple_me/src/occur.cpp @@ -323,7 +323,7 @@ uint32 PreWorkCandHashTable::ComputeStmtWorkCandHashIndex(const MeStmt &stmt) { case OP_dassign: { CHECK_NULL_FATAL(stmt.GetVarLHS()); CHECK_NULL_FATAL(stmt.GetRHS()); - VarMeExpr *varMeExpr = stmt.GetVarLHS(); + ScalarMeExpr *varMeExpr = stmt.GetVarLHS(); hIdx += static_cast(varMeExpr->GetOstIdx()) << kOffsetVarMeExprOstIdx; hIdx += ComputeWorkCandHashIndex(*stmt.GetRHS()) << 1; break; diff --git a/src/mapleall/maple_me/src/prop.cpp b/src/mapleall/maple_me/src/prop.cpp index 2041eb5b47..e427276ea1 100644 --- a/src/mapleall/maple_me/src/prop.cpp +++ b/src/mapleall/maple_me/src/prop.cpp @@ -529,6 +529,16 @@ void Prop::TraversalMeStmt(MeStmt &meStmt) { } break; } + case OP_dassign: + case OP_regassign: { + AssignMeStmt *asmestmt = static_cast(&meStmt); + asmestmt->SetRHS(&PropMeExpr(*asmestmt->GetRHS(), subProped, false)); + if (subProped) { + asmestmt->isIncDecStmt = false; + } + PropUpdateDef(*asmestmt->GetLHS()); + break; + } default: for (size_t i = 0; i != meStmt.NumMeStmtOpnds(); ++i) { MeExpr &expr = PropMeExpr(utils::ToRef(meStmt.GetOpnd(i)), subProped, kOpcodeInfo.IsCall(op)); @@ -537,22 +547,6 @@ void Prop::TraversalMeStmt(MeStmt &meStmt) { break; } - // update lhs - switch (op) { - case OP_dassign: { - auto &varMeStmt = static_cast(meStmt); - PropUpdateDef(static_cast(utils::ToRef(varMeStmt.GetLHS()))); - break; - } - case OP_regassign: { - auto ®MeStmt = static_cast(meStmt); - PropUpdateDef(static_cast(utils::ToRef(regMeStmt.GetLHS()))); - break; - } - default: - break; - } - // update chi auto *chiList = meStmt.GetChiList(); if (chiList != nullptr) { diff --git a/src/mapleall/maple_me/src/ssa_epre.cpp b/src/mapleall/maple_me/src/ssa_epre.cpp index 67d924f809..bca8dde259 100644 --- a/src/mapleall/maple_me/src/ssa_epre.cpp +++ b/src/mapleall/maple_me/src/ssa_epre.cpp @@ -14,10 +14,6 @@ */ #include "ssa_epre.h" -namespace { - constexpr maple::uint32 kMeOpOpNum = 3; -} - namespace maple { MeExpr *SSAEPre::GetTruncExpr(const IvarMeExpr &theLHS, MeExpr &savedRHS) { MIRType *lhsType = theLHS.GetType(); @@ -65,6 +61,23 @@ void SSAEPre::GenerateSaveLHSRealocc(MeRealOcc &realOcc, ScalarMeExpr ®OrVar) savedRHS = GetTruncExpr(*theLHS, *savedRHS); if (!workCand->NeedLocalRefVar() || GetPlacementRCOn()) { CHECK_FATAL(regOrVar.GetMeOp() == kMeOpReg, "GenerateSaveLHSRealocc: EPRE temp must b e preg here"); + PrimType lhsPrimType = theLHS->GetType()->GetPrimType(); + if (GetPrimTypeSize(savedRHS->GetPrimType()) > GetPrimTypeSize(lhsPrimType)) { + // insert integer truncation to the rhs + if (GetPrimTypeSize(lhsPrimType) >= 4) { + savedRHS = irMap->CreateMeExprTypeCvt(lhsPrimType, savedRHS->GetPrimType(), *savedRHS); + } else { + Opcode extOp = IsSignedInteger(lhsPrimType) ? OP_sext : OP_zext; + PrimType newPrimType = PTY_u32; + if (IsSignedInteger(lhsPrimType)) { + newPrimType = PTY_i32; + } + OpMeExpr opmeexpr(-1, extOp, newPrimType, 1); + opmeexpr.SetBitsSize(GetPrimTypeSize(lhsPrimType) * 8); + opmeexpr.SetOpnd(0, savedRHS); + savedRHS = irMap->HashMeExpr(opmeexpr); + } + } // change original iassign to regassign; // use placement new to modify in place, because other occ nodes are pointing // to this statement in order to get to the rhs expression; @@ -89,6 +102,8 @@ void SSAEPre::GenerateSaveLHSRealocc(MeRealOcc &realOcc, ScalarMeExpr ®OrVar) dass->SetPrev(savedPrev); dass->SetNext(savedNext); localRefVar->SetDefByStmt(*dass); + + // generate regOrVar = localRefVar rass = irMap->CreateAssignMeStmt(regOrVar, *localRefVar, *savedBB); regOrVar.SetDefByStmt(*rass); savedBB->InsertMeStmtAfter(dass, rass); @@ -122,7 +137,7 @@ void SSAEPre::GenerateSaveRealOcc(MeRealOcc &realOcc) { (realOcc.GetMeStmt()->GetOpnd(0) == realOcc.GetMeExpr())) { isRHSOfDassign = true; // setting flag so delegaterc will skip - static_cast(realOcc.GetMeStmt())->GetVarLHS()->SetNoDelegateRC(true); + static_cast(static_cast(realOcc.GetMeStmt())->GetVarLHS())->SetNoDelegateRC(true); } if (!workCand->NeedLocalRefVar() || isRHSOfDassign || GetPlacementRCOn()) { newMeStmt = irMap->CreateAssignMeStmt(*regOrVar, *realOcc.GetMeExpr(), *realOcc.GetMeStmt()->GetBB()); @@ -205,51 +220,71 @@ MeExpr *SSAEPre::PhiOpndFromRes(MeRealOcc &realZ, size_t j) const { MeOccur *defZ = realZ.GetDef(); CHECK_FATAL(defZ != nullptr, "must be def by phiocc"); CHECK_FATAL(defZ->GetOccType() == kOccPhiocc, "must be def by phiocc"); - MeExpr *exprQ = CopyMeExpr(utils::ToRef(realZ.GetMeExpr())); BB *ePhiBB = defZ->GetBB(); - CHECK_FATAL(exprQ != nullptr, "nullptr check"); - switch (exprQ->GetMeOp()) { + switch (realZ.GetMeExpr()->GetMeOp()) { case kMeOpOp: { - auto *opMeExpr = static_cast(exprQ); - for (size_t i = 0; i < kMeOpOpNum; ++i) { - MeExpr *opnd = opMeExpr->GetOpnd(i); - if (opnd == nullptr) { - break; - }; - MeExpr *retOpnd = GetReplaceMeExpr(*opnd, *ePhiBB, j); + OpMeExpr opMeExpr(*static_cast(realZ.GetMeExpr()), -1); + for (size_t i = 0; i < opMeExpr.GetNumOpnds(); ++i) { + MeExpr *retOpnd = GetReplaceMeExpr(*opMeExpr.GetOpnd(i), *ePhiBB, j); if (retOpnd != nullptr) { - opMeExpr->SetOpnd(i, retOpnd); + opMeExpr.SetOpnd(i, retOpnd); } } - break; + return irMap->HashMeExpr(opMeExpr); } case kMeOpNary: { - auto *naryMeExpr = static_cast(exprQ); - MapleVector &opnds = naryMeExpr->GetOpnds(); - for (size_t i = 0; i < opnds.size(); i++) { - MeExpr *retOpnd = GetReplaceMeExpr(*opnds[i], *ePhiBB, j); + NaryMeExpr naryMeExpr(&irMap->GetIRMapAlloc(), -1, *static_cast(realZ.GetMeExpr())); + for (size_t i = 0; i < naryMeExpr.GetNumOpnds(); i++) { + MeExpr *retOpnd = GetReplaceMeExpr(*naryMeExpr.GetOpnd(i), *ePhiBB, j); if (retOpnd != nullptr) { - opnds[i] = retOpnd; + naryMeExpr.SetOpnd(i, retOpnd); } } - break; + return irMap->HashMeExpr(naryMeExpr); } case kMeOpIvar: { - auto *ivarMeExpr = static_cast(exprQ); - MeExpr *retOpnd = GetReplaceMeExpr(*ivarMeExpr->GetBase(), *ePhiBB, j); + IvarMeExpr ivarMeExpr(-1, *static_cast(realZ.GetMeExpr())); + MeExpr *retOpnd = GetReplaceMeExpr(*ivarMeExpr.GetBase(), *ePhiBB, j); if (retOpnd != nullptr) { - ivarMeExpr->SetBase(retOpnd); + ivarMeExpr.SetBase(retOpnd); } - MeExpr *muOpnd = GetReplaceMeExpr(*ivarMeExpr->GetMu(), *ePhiBB, j); + MeExpr *muOpnd = GetReplaceMeExpr(*ivarMeExpr.GetMu(), *ePhiBB, j); if (muOpnd != nullptr) { - ivarMeExpr->SetMuVal(static_cast(muOpnd)); + ivarMeExpr.SetMuVal(static_cast(muOpnd)); } - break; + return irMap->HashMeExpr(ivarMeExpr); } default: ASSERT(false, "NYI"); } - return irMap->HashMeExpr(*exprQ); + return nullptr; +} + +bool SSAEPre::AllVarsSameVersion(const MeRealOcc &realocc1, const MeRealOcc &realocc2) const { + if (realocc1.GetMeExpr() == realocc2.GetMeExpr()) { + return true; + } else if (!workCand->isSRCand) { + return false; + } + // for each var operand in realocc2, check if it can resolve to the + // corresponding operand in realocc1 via ResolveOneInjuringDef() + for (int32 i = 0; i < realocc2.GetMeExpr()->GetNumOpnds(); i++) { + MeExpr *curopnd = realocc2.GetMeExpr()->GetOpnd(i); + if (curopnd->GetMeOp() != kMeOpVar && curopnd->GetMeOp() != kMeOpReg) { + continue; + } + if (curopnd == realocc1.GetMeExpr()->GetOpnd(i)) { + continue; + } + MeExpr *resolvedOpnd = ResolveAllInjuringDefs(curopnd); + if (resolvedOpnd == curopnd || resolvedOpnd != realocc1.GetMeExpr()->GetOpnd(i)) { + return false; + } + else { + continue; + } + } + return true; } // Df phis are computed into the df_phis set; Var Phis in the var_phis set @@ -263,35 +298,8 @@ void SSAEPre::ComputeVarAndDfPhis() { BB *defBB = realOcc->GetBB(); GetIterDomFrontier(defBB, &dfPhiDfns); MeExpr *meExpr = realOcc->GetMeExpr(); - switch (meExpr->GetMeOp()) { - case kMeOpOp: { - auto *meExprOp = static_cast(meExpr); - for (uint32 i = 0; i < kMeOpOpNum; ++i) { - MeExpr *kidExpr = meExprOp->GetOpnd(i); - if (kidExpr != nullptr) { - SetVarPhis(*kidExpr); - } - } - break; - } - case kMeOpNary: { - auto *naryMeExpr = static_cast(meExpr); - MapleVector &opnds = naryMeExpr->GetOpnds(); - for (size_t i = 0; i < opnds.size(); i++) { - MeExpr *kidExpr = opnds[i]; - if (kidExpr != nullptr) { - SetVarPhis(*kidExpr); - } - } - break; - } - case kMeOpIvar: { - auto *ivarMeExpr = static_cast(meExpr); - SetVarPhis(*ivarMeExpr->GetBase()); - break; - } - default: - CHECK_FATAL(false, "NYI"); + for (int32 i = 0; i < meExpr->GetNumOpnds(); i++) { + SetVarPhis(meExpr->GetOpnd(i)); } } } @@ -309,54 +317,61 @@ void SSAEPre::BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr &meExpr, b switch (meOp) { case kMeOpOp: { auto *meOpExpr = static_cast(&meExpr); - bool isHypo = true; + bool isFirstOrder = true; bool hasTempVarAs1Opnd = false; - for (uint32 i = 0; i < kMeOpOpNum; i++) { + for (uint32 i = 0; i < meOpExpr->GetNumOpnds(); i++) { MeExpr *opnd = meOpExpr->GetOpnd(i); - if (opnd != nullptr) { - if (!opnd->IsLeaf()) { - BuildWorkListExpr(meStmt, seqStmt, *opnd, isRebuild, tempVar, false); - isHypo = false; - } else if (LeafIsVolatile(opnd)) { - isHypo = false; - } else if (tempVar != nullptr && opnd->IsUseSameSymbol(*tempVar)) { - hasTempVarAs1Opnd = true; - } + if (!opnd->IsLeaf()) { + BuildWorkListExpr(meStmt, seqStmt, *opnd, isRebuild, tempVar, false); + isFirstOrder = false; + } else if (LeafIsVolatile(opnd)) { + isFirstOrder = false; + } else if (tempVar != nullptr && opnd->IsUseSameSymbol(*tempVar)) { + hasTempVarAs1Opnd = true; } } + if (!isFirstOrder) { + break; + } if (meExpr.GetPrimType() == PTY_agg) { - isHypo = false; + break; } - if (isHypo && (!isRebuild || hasTempVarAs1Opnd) && !(isRootExpr && kOpcodeInfo.IsCompare(meOpExpr->GetOp())) && - meOpExpr->GetOp() != OP_gcmallocjarray && meOpExpr->GetOp() != OP_gcmalloc && - (epreIncludeRef || meOpExpr->GetPrimType() != PTY_ref)) { - // create a HypotheTemp for this expr - // Exclude cmp operator - (void)CreateRealOcc(meStmt, seqStmt, meExpr, isRebuild); + if (isRootExpr && kOpcodeInfo.IsCompare(meOpExpr->GetOp())) { + break; + } + if (!epreIncludeRef && meOpExpr->GetPrimType() == PTY_ref) { + break; + } + if (meOpExpr->GetOp() == OP_gcmallocjarray || meOpExpr->GetOp() == OP_gcmalloc) { + break; + } + if (isRebuild && !hasTempVarAs1Opnd) { + break; } + (void)CreateRealOcc(meStmt, seqStmt, meExpr, isRebuild); break; } case kMeOpNary: { auto *naryMeExpr = static_cast(&meExpr); - bool isHypo = true; + bool isFirstOrder = true; bool hasTempVarAs1Opnd = false; MapleVector &opnds = naryMeExpr->GetOpnds(); for (auto it = opnds.begin(); it != opnds.end(); ++it) { MeExpr *opnd = *it; if (!opnd->IsLeaf()) { BuildWorkListExpr(meStmt, seqStmt, *opnd, isRebuild, tempVar, false); - isHypo = false; + isFirstOrder = false; } else if (LeafIsVolatile(opnd)) { - isHypo = false; + isFirstOrder = false; } else if (tempVar != nullptr && opnd->IsUseSameSymbol(*tempVar)) { hasTempVarAs1Opnd = true; } } if (meExpr.GetPrimType() == PTY_agg) { - isHypo = false; + isFirstOrder = false; } constexpr uint32 minTypeSizeRequired = 4; - if (isHypo && (!isRebuild || hasTempVarAs1Opnd) && naryMeExpr->GetPrimType() != PTY_u1 && + if (isFirstOrder && (!isRebuild || hasTempVarAs1Opnd) && naryMeExpr->GetPrimType() != PTY_u1 && (GetPrimTypeSize(naryMeExpr->GetPrimType()) >= minTypeSizeRequired || IsPrimitivePoint(naryMeExpr->GetPrimType()) || (naryMeExpr->GetOp() == OP_intrinsicop && IntrinDesc::intrinTable[naryMeExpr->GetIntrinsic()].IsPure())) && @@ -472,42 +487,14 @@ void SSAEPre::BuildWorkListIvarLHSOcc(MeStmt &meStmt, int32 seqStmt, bool isRebu // collect meExpr's variables and put them into varVec // varVec can only store RegMeExpr and VarMeExpr void SSAEPre::CollectVarForMeExpr(MeExpr &meExpr, std::vector &varVec) const { - switch (meExpr.GetMeOp()) { - case kMeOpOp: { - for (uint32 i = 0; i < kMeOpOpNum; i++) { - auto *opMeExpr = static_cast(&meExpr); - MeExpr *opnd = opMeExpr->GetOpnd(i); - if (opnd != nullptr && (opnd->GetMeOp() == kMeOpVar || opnd->GetMeOp() == kMeOpReg)) { - varVec.push_back(opnd); - } - } - break; - } - case kMeOpNary: { - auto *naryMeExpr = static_cast(&meExpr); - const MapleVector &opnds = naryMeExpr->GetOpnds(); - for (MeExpr *kidExpr : opnds) { - if (kidExpr->GetMeOp() == kMeOpVar || kidExpr->GetMeOp() == kMeOpReg) { - varVec.push_back(kidExpr); - } - } - break; - } - case kMeOpIvar: { - auto *ivarMeExpr = static_cast(&meExpr); - CHECK_FATAL(ivarMeExpr->GetBase()->GetMeOp() == kMeOpVar || ivarMeExpr->GetBase()->GetMeOp() == kMeOpConst || - ivarMeExpr->GetBase()->GetMeOp() == kMeOpAddrof || ivarMeExpr->GetBase()->GetMeOp() == kMeOpReg, - "ivarMeExpr not first order expr"); - if (ivarMeExpr->GetBase()->GetMeOp() == kMeOpVar || ivarMeExpr->GetBase()->GetMeOp() == kMeOpReg) { - varVec.push_back(ivarMeExpr->GetBase()); - } - // in case of lhs occurrence, mu can be nullptr, and can use nullptr as value - varVec.push_back(ivarMeExpr->GetMu()); - break; + for (int32 i = 0; i < meExpr.GetNumOpnds(); i++) { + MeExpr *opnd = meExpr.GetOpnd(i); + if (opnd->GetMeOp() == kMeOpVar || opnd->GetMeOp() == kMeOpReg) { + varVec.push_back(opnd); } - default: - ASSERT(false, "should not be here"); - break; + } + if (meExpr.GetMeOp() == kMeOpIvar) { + varVec.push_back(static_cast(meExpr).GetMu()); } } diff --git a/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp new file mode 100644 index 0000000000..ffec581c8e --- /dev/null +++ b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp @@ -0,0 +1,329 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the MulanPSL - 2.0 for more details. + */ + +#include "ssa_epre.h" + +namespace maple { + +static VarMeExpr* ResolveOneInjuringDef(VarMeExpr *varx) { + if (varx->GetDefBy() != kDefByStmt) { + return varx; + } + DassignMeStmt *dass = static_cast(varx->GetDefStmt()); + CHECK_FATAL(dass->GetOp() == OP_dassign, "ResolveInjuringDefs: defStmt is not a dassign"); + CHECK_FATAL(dass->GetLHS() == varx, "ResolveInjuringDefs: defStmt has different lhs"); + if (!dass->isIncDecStmt) { + return varx; + } + CHECK_FATAL(dass->GetRHS()->GetMeOp() == kMeOpOp, "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected rhs form."); + OpMeExpr *oprhs = static_cast(dass->GetRHS()); + CHECK_FATAL(oprhs->GetOpnd(0)->GetMeOp() == kMeOpVar, "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected form."); + VarMeExpr *rhsvar = static_cast(oprhs->GetOpnd(0)); + CHECK_FATAL(rhsvar->GetOst() == varx->GetOst(), "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected rhs var."); + return rhsvar; +} + +VarMeExpr* SSAEPre::ResolveAllInjuringDefs(VarMeExpr *varx) const { + if (!workCand->isSRCand) { + return varx; + } + while (true) { + VarMeExpr *answer = ResolveOneInjuringDef(varx); + if (answer == varx) { + return answer; + } else { + varx = answer; + } + } +} + +static RegMeExpr* ResolveOneInjuringDef(RegMeExpr *regx) { + if (regx->GetDefBy() != kDefByStmt) { + return regx; + } + AssignMeStmt *rass = static_cast(regx->GetDefStmt()); + CHECK_FATAL(rass->GetOp() == OP_regassign, "ResolveInjuringDefs: defStmt is not a regassign"); + CHECK_FATAL(rass->GetLHS() == regx, "ResolveInjuringDefs: defStmt has different lhs"); + if (!rass->isIncDecStmt) { + return regx; + } + CHECK_FATAL(rass->GetRHS()->GetMeOp() == kMeOpOp, "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected rhs form."); + OpMeExpr *oprhs = static_cast(rass->GetRHS()); + CHECK_FATAL(oprhs->GetOpnd(0)->GetMeOp() == kMeOpReg, "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected form."); + RegMeExpr *rhsreg = static_cast(oprhs->GetOpnd(0)); + CHECK_FATAL(rhsreg->GetOst() == regx->GetOst(), "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected rhs reg."); + return rhsreg; +} + +RegMeExpr* SSAEPre::ResolveAllInjuringDefs(RegMeExpr *regx) const { + if (!workCand->isSRCand) { + return regx; + } + while (true) { + RegMeExpr *answer = ResolveOneInjuringDef(regx); + if (answer == regx) { + return answer; + } else { + regx = answer; + } + } +} + +bool SSAEPre::OpndInDefOcc(MeExpr *opnd, MeOccur *defocc, uint32 i) { + if (defocc->GetOccType() == kOccReal) { + MeRealOcc *defrealocc = static_cast(defocc); + MeExpr *defexpr = defrealocc->GetMeExpr(); + return opnd == defexpr->GetOpnd(i); + } else { // kOccPhi + return DefVarDominateOcc(opnd, *defocc); + } +} + +void SSAEPre::SubstituteOpnd(MeExpr *x, MeExpr *oldopnd, MeExpr *newopnd) { + CHECK_FATAL(x->GetMeOp() == kMeOpOp, "SSAEPre::SubstituteOpnd: unexpected expr kind"); + OpMeExpr *opexpr = static_cast(x); + for (uint32 i = 0; i < opexpr->GetNumOpnds(); i++) { + if (opexpr->GetOpnd(i) == oldopnd) { + opexpr->SetOpnd(i, newopnd); + } + } +} + +void SSAEPre::SRSetNeedRepair(MeOccur *useocc, std::set *needRepairInjuringDefs) { + MeOccur *defocc = useocc->GetDef(); + CHECK_FATAL(defocc != nullptr, "SRSetNeedRepair: occ->def must not be null"); + if (defocc->GetOccType() == kOccInserted) { + CHECK_FATAL(defocc->GetBB() == useocc->GetBB(), "SRSetNeedRepair: unexpected inserted occ"); + return; + } + MeExpr *useexpr = nullptr; + if (useocc->GetOccType() == kOccReal) { + MeRealOcc *realocc = static_cast(useocc); + useexpr = realocc->GetMeExpr(); + } else { + MePhiOpndOcc *phiopndocc = static_cast(useocc); + useexpr = phiopndocc->GetCurrentMeExpr(); + if (useexpr == nullptr) { + return; + } + } + for (int32 i = 0; i < useexpr->GetNumOpnds(); i++) { + MeExpr *curopnd = useexpr->GetOpnd(i); + if (curopnd->GetMeOp() != kMeOpVar && curopnd->GetMeOp() != kMeOpReg) { + continue; + } + if (!OpndInDefOcc(curopnd, defocc, i)) { + if (curopnd->GetMeOp() == kMeOpVar) { + VarMeExpr *varx = static_cast(curopnd); + needRepairInjuringDefs->insert(varx->GetDefStmt()); + } else { + RegMeExpr *regx = static_cast(curopnd); + needRepairInjuringDefs->insert(regx->GetDefStmt()); + } + return; // restricted injury requirement to at most 1 operand + } + } +} + +static int64 GetIncreAmtAndRhsVar(MeExpr *x, VarMeExpr *&rhsvar) { + OpMeExpr *opexpr = static_cast(x); + CHECK_FATAL(opexpr->GetOpnd(0)->GetMeOp() == kMeOpVar, "GetIncreAmtAndRhsVar: cannot find var operand"); + CHECK_FATAL(opexpr->GetOpnd(1)->GetMeOp() == kMeOpConst, "GetIncreAmtAndRhsVar: cannot find constant inc/dec amount"); + rhsvar = static_cast(opexpr->GetOpnd(0)); + MIRConst *constVal = static_cast(opexpr->GetOpnd(1))->GetConstVal(); + CHECK_FATAL(constVal->GetKind() == kConstInt, "GetIncreAmtAndRhsVar: unexpected constant type"); + int64 amt = static_cast(constVal)->GetValueUnderType(); + return (opexpr->GetOp() == OP_sub) ? -amt : amt; +} + +static int64 GetIncreAmtAndRhsReg(MeExpr *x, RegMeExpr *&rhsreg) { + OpMeExpr *opexpr = static_cast(x); + CHECK_FATAL(opexpr->GetOpnd(0)->GetMeOp() == kMeOpReg, "GetIncreAmtAndRhsReg: cannot find reg operand"); + CHECK_FATAL(opexpr->GetOpnd(1)->GetMeOp() == kMeOpConst, "GetIncreAmtAndRhsReg: cannot find constant inc/dec amount"); + rhsreg = static_cast(opexpr->GetOpnd(0)); + MIRConst *constVal = static_cast(opexpr->GetOpnd(1))->GetConstVal(); + CHECK_FATAL(constVal->GetKind() == kConstInt, "GetIncreAmtAndRhsReg: unexpected constant type"); + int64 amt = static_cast(constVal)->GetValueUnderType(); + return (opexpr->GetOp() == OP_sub) ? -amt : amt; +} + +MeExpr* SSAEPre::InsertRepairStmt(MeExpr *temp, int64 increAmt, MeStmt *injuringDef) { + MeExpr *rhs = nullptr; + if (increAmt >= 0) { + rhs = irMap->CreateMeExprBinary(OP_add, temp->GetPrimType(), *temp, *irMap->CreateIntConstMeExpr(increAmt, temp->GetPrimType())); + } else { + rhs = irMap->CreateMeExprBinary(OP_sub, temp->GetPrimType(), *temp, *irMap->CreateIntConstMeExpr(-increAmt, temp->GetPrimType())); + } + BB *bb = injuringDef->GetBB(); + MeStmt *newstmt = nullptr; + if (temp->GetMeOp() == kMeOpReg) { + RegMeExpr *newreg = irMap->CreateRegMeExprVersion(*static_cast(temp)); + newstmt = irMap->CreateAssignMeStmt(*newreg, *rhs, *bb); + static_cast(newstmt)->isIncDecStmt = true; + bb->InsertMeStmtAfter(injuringDef, newstmt); + return newreg; + } else { + VarMeExpr *newvar = irMap->CreateVarMeExprVersion(*static_cast(temp)); + newstmt = irMap->CreateAssignMeStmt(*newvar, *rhs, *bb); + static_cast(newstmt)->isIncDecStmt = true; + bb->InsertMeStmtAfter(injuringDef, newstmt); + return newvar; + } +} + +static MeExpr *FindLaterRepairedTemp(MeExpr *temp, MeStmt *injuringDef) { + if (temp->GetMeOp() == kMeOpReg) { + AssignMeStmt *rass = static_cast(injuringDef->GetNext()); + while (rass != nullptr) { + CHECK_FATAL(rass->GetOp() == OP_regassign && rass->isIncDecStmt, + "FindLaterRepairedTemp: failed to find repair statement"); + if (rass->GetLHS()->GetRegIdx() == static_cast(temp)->GetRegIdx()) { + return rass->GetLHS(); + } + rass = static_cast(rass->GetNext()); + } + } else { // kMeOpVar + DassignMeStmt *dass = static_cast(injuringDef->GetNext()); + while (dass != nullptr) { + CHECK_FATAL(dass->GetOp() == OP_dassign && dass->isIncDecStmt, + "FindLaterRepairedTemp: failed to find repair statement"); + if (dass->GetLHS()->GetOst() == static_cast(temp)->GetOst()) { + return dass->GetLHS(); + } + dass = static_cast(dass->GetNext()); + } + } + CHECK_FATAL(false, "FindLaterRepairedTemp: failed to find repair statement"); + return nullptr; +} + +MeExpr* SSAEPre::SRRepairOpndInjuries(MeExpr *curopnd, MeOccur *defocc, int32 i, + MeExpr *tempAtDef, + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) { + MeExpr *repairedTemp = tempAtDef; + if (curopnd->GetMeOp() == kMeOpVar) { + VarMeExpr *varx = static_cast(curopnd); + DassignMeStmt *dass = static_cast(varx->GetDefStmt()); + CHECK_FATAL(dass->isIncDecStmt, "SRRepairInjuries: not an inc/dec statement"); + MeStmt *latestInjuringDef = dass; + if (repairedInjuringDefs->count(dass) == 0) { + repairedInjuringDefs->insert(dass); + bool done = false; + int64 increAmt = 0; + VarMeExpr *rhsvar = nullptr; + do { + increAmt += GetIncreAmtAndRhsVar(dass->GetRHS(), rhsvar); + if (OpndInDefOcc(rhsvar, defocc, i)) { + done = true; + } else { + varx = rhsvar; + dass = static_cast(varx->GetDefStmt()); + CHECK_FATAL(dass->isIncDecStmt, "SRRepairInjuries: not an inc/dec statement"); + done = needRepairInjuringDefs->count(dass) == 1; + if (done) { + if (repairedInjuringDefs->count(dass) == 0) { + repairedTemp = SRRepairOpndInjuries(varx, defocc, i, tempAtDef, needRepairInjuringDefs, repairedInjuringDefs); + } + repairedTemp = FindLaterRepairedTemp(repairedTemp, dass); + } + } + } while (!done); + // generate the increment statement at latestInjuringDef + repairedTemp = InsertRepairStmt(repairedTemp, increAmt*workCand->GetTheMeExpr()->SRMultiplier(), latestInjuringDef); + } else { + // find the last repair increment statement + repairedTemp = FindLaterRepairedTemp(repairedTemp, latestInjuringDef); + } + } else { // kMeOpReg + RegMeExpr *regx = static_cast(curopnd); + AssignMeStmt *rass = static_cast(regx->GetDefStmt()); + CHECK_FATAL(rass->isIncDecStmt, "SRRepairInjuries: not an inc/dec statement"); + MeStmt *latestInjuringDef = rass; + if (repairedInjuringDefs->count(rass) == 0) { + repairedInjuringDefs->insert(rass); + bool done = false; + int64 increAmt = 0; + RegMeExpr *rhsreg = nullptr; + do { + increAmt += GetIncreAmtAndRhsReg(rass->GetRHS(), rhsreg); + if (OpndInDefOcc(rhsreg, defocc, i)) { + done = true; + } else { + regx = rhsreg; + rass = static_cast(regx->GetDefStmt()); + CHECK_FATAL(rass->isIncDecStmt, "SRRepairInjuries: not an inc/dec statement"); + done = needRepairInjuringDefs->count(rass) == 1; + if (done) { + if (repairedInjuringDefs->count(rass) == 0) { + repairedTemp = SRRepairOpndInjuries(regx, defocc, i, tempAtDef, needRepairInjuringDefs, repairedInjuringDefs); + } + repairedTemp = FindLaterRepairedTemp(repairedTemp, rass); + } + } + } while (!done); + // generate the increment statement at latestInjuringDef + repairedTemp = InsertRepairStmt(repairedTemp, increAmt*workCand->GetTheMeExpr()->SRMultiplier(), latestInjuringDef); + } else { + // find the last repair increment statement + repairedTemp = FindLaterRepairedTemp(repairedTemp, latestInjuringDef); + } + } + return repairedTemp; +} + +MeExpr* SSAEPre::SRRepairInjuries(MeOccur *useocc, + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) { + MeExpr *useexpr = nullptr; + if (useocc->GetOccType() == kOccReal) { + MeRealOcc *realocc = static_cast(useocc); + useexpr = realocc->GetMeExpr(); + } else { + MePhiOpndOcc *phiopndocc = static_cast(useocc); + useexpr = phiopndocc->GetCurrentMeExpr(); + } + MeOccur *defocc = useocc->GetDef(); + MeExpr *repairedTemp = nullptr; + if (defocc->GetOccType() == kOccInserted) { + CHECK_FATAL(defocc->GetBB() == useocc->GetBB(), "SRRepairInjuries: unexpected inserted occ"); + return static_cast(defocc)->GetSavedExpr(); + } + if (defocc->GetOccType() == kOccReal) { + MeRealOcc *defrealocc = static_cast(defocc); + repairedTemp = defrealocc->GetSavedExpr(); + } else { // kOccPhiocc + MePhiOcc *defphiocc = static_cast(defocc); + MePhiNode *scalarPhi = (defphiocc->GetRegPhi() ? defphiocc->GetRegPhi() : defphiocc->GetVarPhi()); + repairedTemp = scalarPhi->GetLHS(); + } + if (useexpr == nullptr) { + return repairedTemp; + } + for (int32 i = 0; i < useexpr->GetNumOpnds(); i++) { + MeExpr *curopnd = useexpr->GetOpnd(i); + if (curopnd->GetMeOp() != kMeOpVar && curopnd->GetMeOp() != kMeOpReg) { + continue; + } + if (!OpndInDefOcc(curopnd, defocc, i)) { + repairedTemp = SRRepairOpndInjuries(curopnd, defocc, i, repairedTemp, needRepairInjuringDefs, repairedInjuringDefs); + // restricted to only 1 var or reg injured + break; + } + } // for + return repairedTemp; +} + +} // namespace maple diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index a393f2a43f..1672d2452a 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -48,44 +48,15 @@ ScalarMeExpr *SSAPre::CreateNewCurTemp(const MeExpr &meExpr) { if (workCand->GetPUIdx() != 0) { // allocate a new temp SetCurFunction(workCand->GetPUIdx()); - RegMeExpr *regVar = nullptr; - if (meExpr.GetMeOp() == kMeOpVar) { - auto *ty = static_cast(meExpr).GetType(); - regVar = ty->GetPrimType() == PTY_ref ? irMap->CreateRegMeExpr(*ty) - : irMap->CreateRegMeExpr(ty->GetPrimType()); - } else if (meExpr.GetMeOp() == kMeOpIvar) { - auto *ivarMeExpr = static_cast(&meExpr); - MIRType *ptrMIRType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ivarMeExpr->GetTyIdx()); - CHECK_FATAL(ptrMIRType->GetKind() == kTypePointer, "must be point type for ivar"); - auto *realMIRType = static_cast(ptrMIRType); - FieldID fieldId = ivarMeExpr->GetFieldID(); - MIRType *ty = nullptr; - if (fieldId > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(realMIRType->GetPointedTyIdxWithFieldID(fieldId)); - } else { - ty = realMIRType->GetPointedType(); - } - CHECK_FATAL(GetRegPrimType(ty->GetPrimType()) == GetRegPrimType(meExpr.GetPrimType()) || - GetReg64PrimType(ty->GetPrimType()) == GetReg64PrimType(meExpr.GetPrimType()) || - (IsAddress(ty->GetPrimType()) && IsAddress(meExpr.GetPrimType())) || - (ty->GetPrimType() == PTY_ptr && meExpr.GetPrimType() == PTY_ref) || - (ty->GetPrimType() == PTY_ref && meExpr.GetPrimType() == PTY_ptr), - "inconsistent type"); - regVar = (ty->GetPrimType() == PTY_ref) ? (irMap->CreateRegMeExpr(*ty)) - : (irMap->CreateRegMeExpr(ty->GetPrimType())); - } else { - regVar = meExpr.GetPrimType() != PTY_ref ? irMap->CreateRegMeExpr(meExpr.GetPrimType()) - : irMap->CreateRegMeExpr(meExpr); - } + RegMeExpr *regVar = irMap->CreateRegMeExpr(meExpr); curTemp = regVar; if (preKind == kLoadPre) { irMap->SetLpreTmps(static_cast(&meExpr)->GetOstIdx(), *regVar); } return regVar; } else { - VarMeExpr *tempVar = irMap->CreateNewVar(NewTempStrIdx(), meExpr.GetPrimType(), true); - curTemp = tempVar; - return tempVar; + curTemp = irMap->CreateNewVar(NewTempStrIdx(), meExpr.GetPrimType(), true); + return curTemp; } } @@ -169,7 +140,7 @@ void SSAPre::GenerateSavePhiOcc(MePhiOcc &phiOcc) { void SSAPre::UpdateInsertedPhiOccOpnd() { for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { MePhiOcc *phiOcc = *it; - if (!phiOcc->IsWillBeAvail() || phiOcc->IsExtraneous()) { + if (!phiOcc->IsWillBeAvail() || phiOcc->IsRemoved()) { continue; } if (phiOcc->GetRegPhi()) { @@ -224,10 +195,40 @@ void SSAPre::UpdateInsertedPhiOccOpnd() { } void SSAPre::CodeMotion() { + std::set needRepairInjuringDefs; // for marking injuring defs that have been repaired + + if (workCand->isSRCand) { // pre-pass needed by strength reduction + for (MeOccur *occ : allOccs) { + switch (occ->GetOccType()) { + case kOccReal: { + MeRealOcc *realocc = static_cast(occ); + if (realocc->IsReload()) { + SRSetNeedRepair(realocc, &needRepairInjuringDefs); + } + break; + } + case kOccPhiopnd: { + MePhiOpndOcc *phiopnd = static_cast(occ); + if (phiopnd->GetDefPhiOcc()->IsRemoved() || !phiopnd->GetDefPhiOcc()->IsWillBeAvail()) { + break; + } + if (phiopnd->GetDef()->GetOccType() == kOccInserted) { + break; + } + SRSetNeedRepair(phiopnd, &needRepairInjuringDefs); + break; + } + default: ; + } + } + } + curTemp = nullptr; curLocalRefVar = nullptr; temp2LocalRefVarMap.clear(); reBuiltOccIndex = static_cast(workList.size()); // so we know the elements added due to rebuilding + std::set repairedInjuringDefs; // for marking injuring defs that have been repaired + for (MeOccur *occ : allOccs) { switch (occ->GetOccType()) { case kOccReal: { @@ -236,13 +237,23 @@ void SSAPre::CodeMotion() { CHECK_FATAL(!(realOcc->IsReload()), "reload failed"); GenerateSaveRealOcc(*realOcc); } else if (realOcc->IsReload()) { - GenerateReloadRealOcc(*realOcc); + if (!workCand->isSRCand) { + GenerateReloadRealOcc(*realOcc); + } else { + MeExpr *regorvar = SRRepairInjuries(realOcc, &needRepairInjuringDefs, &repairedInjuringDefs); + // replace realOcc->mestmt's occ with regorvar + bool isreplaced = irMap->ReplaceMeExprStmt(*realOcc->GetMeStmt(), *realOcc->GetMeExpr(), *regorvar); + // update worklist + if (isreplaced) { + BuildWorkListStmt(*realOcc->GetMeStmt(), realOcc->GetSequence(), true, regorvar); + } + } } break; } case kOccPhiopnd: { auto *phiOpnd = static_cast(occ); - if (!phiOpnd->GetDefPhiOcc()->IsWillBeAvail()) { + if (phiOpnd->GetDefPhiOcc()->IsRemoved() || !phiOpnd->GetDefPhiOcc()->IsWillBeAvail()) { break; } MeOccur *defOcc = phiOpnd->GetDef(); @@ -250,13 +261,27 @@ void SSAPre::CodeMotion() { // generate a save of the result in to a new version of t if (!phiOpnd->IsPhiOpndReload()) { GenerateSaveInsertedOcc(*static_cast(defOcc)); + phiOpnd->phiOpnd4Temp = static_cast(defOcc)->GetSavedExpr(); + } + } else { + // set phiOpnd4Temp needed in the temp's phi + if (workCand->isSRCand) { + phiOpnd->phiOpnd4Temp = SRRepairInjuries(phiOpnd, &needRepairInjuringDefs, &repairedInjuringDefs); + } else { + if (defOcc->GetOccType() == kOccReal) { + phiOpnd->phiOpnd4Temp = static_cast(defOcc)->GetSavedExpr(); + } else { + MePhiOcc *defphiocc = static_cast(defOcc); + MePhiNode *scalarPhi = (defphiocc->GetRegPhi() ? defphiocc->GetRegPhi() : defphiocc->GetVarPhi()); + phiOpnd->phiOpnd4Temp = scalarPhi->GetLHS(); + } } } break; } case kOccPhiocc: { auto *phiOcc = static_cast(occ); - if (phiOcc->IsExtraneous() || !phiOcc->IsWillBeAvail()) { + if (phiOcc->IsRemoved() || !phiOcc->IsWillBeAvail()) { break; }; GenerateSavePhiOcc(*phiOcc); @@ -448,7 +473,10 @@ void SSAPre::Finalize2() { for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { MePhiOcc *phiOcc = *it; // initialize extraneouse for each MePhiOcc - phiOcc->SetIsExtraneous(phiOcc->IsWillBeAvail()); + if (!workCand->isSRCand) { + phiOcc->SetIsExtraneous(phiOcc->IsWillBeAvail()); + } + // initialize each operand of phiOcc for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { phiOpnd->SetIsProcessed(false); @@ -460,41 +488,46 @@ void SSAPre::Finalize2() { SetSave(*realOcc->GetDef()); } } - for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { - MePhiOcc *phiOcc = *it; - if (phiOcc->IsRemoved() || !phiOcc->IsExtraneous()) { - continue; - } - if (!phiOcc->IsWillBeAvail()) { - phiOcc->SetIsRemoved(true); - continue; - } - for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { - MeOccur *defOcc = phiOpnd->GetDef(); - switch (defOcc->GetOccType()) { - case kOccReal: - case kOccInserted: - SetReplacement(*phiOcc, *defOcc); - break; - case kOccPhiocc: - if (!static_cast(defOcc)->IsExtraneous()) { + if (!workCand->isSRCand) { + for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { + MePhiOcc *phiOcc = *it; + if (phiOcc->IsRemoved() || !phiOcc->IsExtraneous()) { + continue; + } + if (!phiOcc->IsWillBeAvail()) { + phiOcc->SetIsRemoved(true); + continue; + } + for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { + MeOccur *defOcc = phiOpnd->GetDef(); + switch (defOcc->GetOccType()) { + case kOccReal: SetReplacement(*phiOcc, *defOcc); - } - break; - default: - CHECK_FATAL(false, "unexpected phiOpnd"); + break; + case kOccInserted: + break; + case kOccPhiocc: + if (!static_cast(defOcc)->IsExtraneous()) { + SetReplacement(*phiOcc, *defOcc); + } + break; + default: + CHECK_FATAL(false, "unexpected phiOpnd"); + } } } } + if (GetSSAPreDebug()) { mirModule->GetOut() << "========after Finalize2====================\n"; for (MeOccur *occ : allOccs) { if (occ->GetOccType() == kOccPhiocc) { auto *phiOcc = static_cast(occ); - if (phiOcc->IsExtraneous()) { - phiOcc->Dump(*irMap); - mirModule->GetOut() << "was removed in Finalize2\n"; + phiOcc->Dump(*irMap); + if (phiOcc->IsRemoved()) { + mirModule->GetOut() << "was removed in Finalize2"; } + mirModule->GetOut() << std::endl; } else if (occ->GetOccType() == kOccReal) { auto *realOcc = static_cast(occ); if (realOcc->IsReload()) { @@ -853,8 +886,10 @@ MeExpr *SSAPre::GetReplaceMeExpr(const MeExpr &opnd, const BB &ePhiBB, size_t j) return nullptr; } MeExpr *retExpr = nullptr; - MePhiNode *defPhi = static_cast(&opnd)->GetMePhiDef(); - if (defPhi != nullptr) { + + const ScalarMeExpr *expr = static_cast(&opnd); + if (expr->IsDefByPhi()) { + MePhiNode *defPhi = expr->GetMePhiDef(); if (ePhiBB.GetBBId() == defPhi->GetDefBB()->GetBBId()) { ASSERT(j < defPhi->GetOpnds().size(), "index out of range in SSAPre::GetReplaceMeExpr"); ASSERT(defPhi->GetOpnds()[j]->GetMeOp() == opnd.GetMeOp(), "invalid defPhi"); @@ -913,9 +948,23 @@ void SSAPre::Rename2() { std::vector varVecY; bool alldom = true; CollectVarForMeExpr(*exprY, varVecY); - for (size_t ii = 0; ii < varVecY.size(); ++ii) { - if (!DefVarDominateOcc(varVecY[ii], *defX)) { - alldom = false; + if (exprY->GetMeOp() == kMeOpOp) { + OpMeExpr opmeexpr(*static_cast(exprY), -1); + for (uint32 ii = 0; ii < varVecY.size(); ii++) { + MeExpr *resolvedY = ResolveAllInjuringDefs(varVecY[ii]); + if (resolvedY != varVecY[ii]) { + SubstituteOpnd(&opmeexpr, varVecY[ii], resolvedY); + } + if (!DefVarDominateOcc(resolvedY, *defX)) { + alldom = false; + } + } + exprY = irMap->HashMeExpr(opmeexpr); + } else { + for (size_t ii = 0; ii < varVecY.size(); ++ii) { + if (!DefVarDominateOcc(varVecY[ii], *defX)) { + alldom = false; + } } } if (alldom) { @@ -953,20 +1002,25 @@ void SSAPre::Rename2() { } // ================ Step 1: Phi Insertion ================= -void SSAPre::SetVarPhis(const MeExpr &meExpr) { - MeExprOp meOp = meExpr.GetMeOp(); +void SSAPre::SetVarPhis(MeExpr *meExpr) { + MeExprOp meOp = meExpr->GetMeOp(); if (meOp != kMeOpVar && meOp != kMeOpReg) { return; } - MePhiNode *phiMeNode = static_cast(&meExpr)->GetMePhiDef(); - if (phiMeNode != nullptr) { + + ScalarMeExpr *scalar = static_cast(meExpr); + if (workCand->isSRCand) { + scalar = ResolveAllInjuringDefs(scalar); + } + if (scalar->IsDefByPhi()) { + MePhiNode *phiMeNode = scalar->GetMePhiDef(); BBId defBBId = phiMeNode->GetDefBB()->GetBBId(); CHECK(defBBId < dom->GetDtDfnSize(), "defBBId.idx out of range in SSAPre::SetVarPhis"); if (varPhiDfns.find(dom->GetDtDfnItem(defBBId)) == varPhiDfns.end() && ScreenPhiBB(defBBId)) { (void)varPhiDfns.insert(dom->GetDtDfnItem(defBBId)); for (auto opndIt = phiMeNode->GetOpnds().begin(); opndIt != phiMeNode->GetOpnds().end(); ++opndIt) { ScalarMeExpr *opnd = *opndIt; - SetVarPhis(*opnd); + SetVarPhis(opnd); } } } @@ -1119,37 +1173,6 @@ IassignMeStmt *SSAPre::CopyIassignMeStmt(const IassignMeStmt &iaStmt) const { return meStmt; } -MeStmt *SSAPre::CopyMeStmt(const MeStmt &meStmt) const { - CHECK_FATAL(meStmt.GetOp() == OP_assertlt || meStmt.GetOp() == OP_assertge, "invalid value of meStmt.GetOp()"); - auto *oldStmt = static_cast(&meStmt); - AssertMeStmt *newStmt = irMap->New(*oldStmt); - return newStmt; -} - -MeExpr *SSAPre::CopyMeExpr(const MeExpr &expr) const { - ASSERT_NOT_NULL(irMap); - MapleAllocator *irMapAlloc = &irMap->GetIRMapAlloc(); - switch (expr.GetMeOp()) { - case kMeOpOp: { - auto &opExpr = static_cast(expr); - OpMeExpr *newExpr = irMapAlloc->GetMemPool()->New(opExpr, -1); - return newExpr; - } - case kMeOpNary: { - auto &naryMeExpr = static_cast(expr); - NaryMeExpr *newNaryMeExpr = irMapAlloc->GetMemPool()->New(irMapAlloc, -1, naryMeExpr); - return newNaryMeExpr; - } - case kMeOpIvar: { - auto &ivarMeExpr = static_cast(expr); - IvarMeExpr *newIvar = irMapAlloc->GetMemPool()->New(-1, ivarMeExpr); - return newIvar; - } - default: - CHECK_FATAL(false, "NYI"); - } -} - // if the definition of varMeExpr dominate meocc then return true. otherwise return false; bool SSAPre::DefVarDominateOcc(const MeExpr *meExpr, const MeOccur &meOcc) const { if (meExpr == nullptr) { @@ -1158,104 +1181,53 @@ bool SSAPre::DefVarDominateOcc(const MeExpr *meExpr, const MeOccur &meOcc) const } CHECK_FATAL(meOcc.GetOccType() == kOccPhiocc, "invalid value of meOcc->GetOccType()"); const BB *occBB = (static_cast(&meOcc))->GetBB(); - if (meExpr->GetMeOp() == kMeOpVar) { - auto *varMeExpr = static_cast(meExpr); - switch (varMeExpr->GetDefBy()) { - case kDefByNo: - // zero version vst dominate everything - return ssaTab->IsInitVersion(varMeExpr->GetVstIdx(), varMeExpr->GetOstIdx()); - case kDefByStmt: { - MeStmt *meStmt = varMeExpr->GetDefStmt(); - CHECK_FATAL(meStmt != nullptr, "should have a def meStmt"); - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); - } - case kDefByPhi: { - const MePhiNode &phiMeNode = varMeExpr->GetDefPhi(); - const BB *defBB = phiMeNode.GetDefBB(); - if (defBB->GetBBId() == occBB->GetBBId()) { - return true; - } - return dom->Dominate(*defBB, *occBB); - } - case kDefByMustDef: { - const MeStmt *meStmt = varMeExpr->GetDefMustDef().GetBase(); - if (meStmt == nullptr) { - return true; // it's a original variable dominate everything - } - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); + const ScalarMeExpr *scMeExpr = static_cast(meExpr); + switch (scMeExpr->GetDefBy()) { + case kDefByNo: + return true; // original version dominates everything + case kDefByStmt: { + MeStmt *meStmt = scMeExpr->GetDefStmt(); + CHECK_FATAL(meStmt != nullptr, "should have a def meStmt"); + BB *defBB = meStmt->GetBB(); + if (occBB == defBB) { + return false; } - case kDefByChi: { - MeStmt *meStmt = varMeExpr->GetDefChi().GetBase(); - if (meStmt == nullptr) { - return true; // it's a original variable dominate everything - } - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); + return dom->Dominate(*defBB, *occBB); + } + case kDefByPhi: { + const MePhiNode &phiMeNode = scMeExpr->GetDefPhi(); + const BB *defBB = phiMeNode.GetDefBB(); + if (defBB->GetBBId() == occBB->GetBBId()) { + return true; } - default: - CHECK_FATAL(false, "NYI"); + return dom->Dominate(*defBB, *occBB); } - } else { - CHECK_FATAL(meExpr->GetMeOp() == kMeOpReg, "invalid value of meExpr->GetMeOp()"); - auto *regMeExpr = static_cast(meExpr); - switch (regMeExpr->GetDefBy()) { - case kDefByNo: - return true; // original st dominates everything - case kDefByStmt: { - MeStmt *meStmt = regMeExpr->GetDefStmt(); - CHECK_FATAL(meStmt != nullptr, "invalid value of meStmt"); - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); + case kDefByMustDef: { + const MeStmt *meStmt = scMeExpr->GetDefMustDef().GetBase(); + if (meStmt == nullptr) { + return true; // it's a original variable dominate everything } - case kDefByPhi: { - const MePhiNode &phiMeNode = regMeExpr->GetDefPhi(); - const BB *defBB = phiMeNode.GetDefBB(); - if (defBB->GetBBId() == occBB->GetBBId()) { - return true; - } - return dom->Dominate(*defBB, *occBB); + BB *defBB = meStmt->GetBB(); + if (occBB == defBB) { + return false; } - case kDefByMustDef: { - const MeStmt *meStmt = regMeExpr->GetDefMustDef().GetBase(); - if (meStmt == nullptr) { - return true; // it's a original variable dominate everything - } - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); + return dom->Dominate(*defBB, *occBB); + } + case kDefByChi: { + MeStmt *meStmt = scMeExpr->GetDefChi().GetBase(); + if (meStmt == nullptr) { + return true; // it's a original variable dominate everything } - case kDefByChi: { - MeStmt *mestmt = regMeExpr->GetDefChi().GetBase(); - if (!mestmt) { - return true; // it's a original variable dominate everything - } - BB *defBB = mestmt->GetBB(); - if (occBB == defBB) { - return false; - } else { - return dom->Dominate(*defBB, *occBB); - } + BB *defBB = meStmt->GetBB(); + if (occBB == defBB) { + return false; } - default: - CHECK_FATAL(false, "NYI"); + return dom->Dominate(*defBB, *occBB); } + default: + CHECK_FATAL(false, "NYI"); } + return false; } bool SSAPre::CheckIfAnyLocalOpnd(const MeExpr &meExpr) const { @@ -1342,6 +1314,8 @@ MeRealOcc *SSAPre::CreateRealOcc(MeStmt &meStmt, int seqStmt, MeExpr &meExpr, bo MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fldPair.first); bool isFinal = fldPair.second.GetAttr(FLDATTR_final); wkCand->SetNeedLocalRefVar(ty->GetPrimType() == PTY_ref && !isFinal); + } else if (strengthReduction && meExpr.StrengthReducible()) { + wkCand->isSRCand = true; } workList.push_back(wkCand); wkCand->AddRealOccAsLast(*newOcc, GetPUIdx()); @@ -1434,12 +1408,21 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE } case OP_dassign: { auto *dassMeStmt = static_cast(meStmt); + if (dassMeStmt->isIncDecStmt && preKind == kExprPre) { + break; + } + if (dassMeStmt->GetRHS()->GetMeOp() == dassMeStmt->GetLHS()->GetMeOp() && dassMeStmt->GetLHS()->GetOst() == static_cast(dassMeStmt->GetRHS())->GetOst()) { + break; // identity assignment converted from phi + } BuildWorkListExpr(*meStmt, static_cast(seqStmt), *dassMeStmt->GetRHS(), isRebuilt, tempVar, true); BuildWorkListLHSOcc(*meStmt, static_cast(seqStmt)); break; } case OP_regassign: { auto *rassMeStmt = static_cast(meStmt); + if (rassMeStmt->isIncDecStmt && preKind == kExprPre) { + break; + } BuildWorkListExpr(*meStmt, static_cast(seqStmt), *rassMeStmt->GetRHS(), isRebuilt, tempVar, true); break; } -- Gitee From b8cb9d84863c568666f464bf514b94e017dfba53 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sun, 23 May 2021 08:00:48 -0700 Subject: [PATCH 2/5] Update the strength reduction code with a couple of fixes --- src/mapleall/maple_me/src/me_option.cpp | 6 +++--- src/mapleall/maple_me/src/ssa_pre.cpp | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index 4087f4ae04..8e1a74d305 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -765,11 +765,11 @@ const Descriptor kUsage[] = { { kStrengthReduction, kEnable, "", - "strengthReduction", + "strengthreduction", kBuildTypeExperimental, kArgCheckPolicyBool, - " --strengthReduction \tPerform flow sensitive alias analysis\n" - " --no-strengthReduction \tDisable flow sensitive alias analysis\n", + " --strengthreduction \tPerform flow sensitive alias analysis\n" + " --no-strengthreduction \tDisable flow sensitive alias analysis\n", "me", {} }, { kCheckCastOpt, diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index 1672d2452a..b7f3d011b2 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -936,7 +936,8 @@ void SSAPre::Rename2() { CHECK_FATAL(varVecX.size() == varVecY.size(), "invalid size of varVecY"); bool hasSameVersion = true; for (size_t ii = 0; ii < varVecX.size(); ii++) { - if (varVecX[ii] != varVecY[ii]) { + MeExpr *resolvedY = ResolveAllInjuringDefs(varVecY[ii]); + if (varVecX[ii] != resolvedY) { hasSameVersion = false; } } @@ -1010,7 +1011,11 @@ void SSAPre::SetVarPhis(MeExpr *meExpr) { ScalarMeExpr *scalar = static_cast(meExpr); if (workCand->isSRCand) { - scalar = ResolveAllInjuringDefs(scalar); + if (scalar->GetMeOp() == kMeOpVar) { + scalar = ResolveAllInjuringDefs(static_cast(scalar)); + } else { + scalar = ResolveAllInjuringDefs(scalar); + } } if (scalar->IsDefByPhi()) { MePhiNode *phiMeNode = scalar->GetMePhiDef(); -- Gitee From 83e2789b3def5c07f8f1030fd74855fef176489b Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 20 May 2021 20:03:48 -0700 Subject: [PATCH 3/5] Merged strength reduction optimization from incubator; not turned on yet --- .../maple_ipa/src/ipa_escape_analysis.cpp | 4 +- src/mapleall/maple_me/BUILD.gn | 1 + src/mapleall/maple_me/include/me_ir.h | 48 ++- src/mapleall/maple_me/include/me_option.h | 1 + src/mapleall/maple_me/include/me_stmt_pre.h | 1 - src/mapleall/maple_me/include/occur.h | 10 +- src/mapleall/maple_me/include/ssa_epre.h | 39 +- src/mapleall/maple_me/include/ssa_pre.h | 14 +- src/mapleall/maple_me/src/hdse.cpp | 4 +- src/mapleall/maple_me/src/ipa_side_effect.cpp | 6 +- src/mapleall/maple_me/src/irmap_build.cpp | 33 +- src/mapleall/maple_me/src/me_delegate_rc.cpp | 8 +- src/mapleall/maple_me/src/me_gc_lowering.cpp | 2 +- src/mapleall/maple_me/src/me_ir.cpp | 26 +- .../maple_me/src/me_loop_unrolling.cpp | 2 +- src/mapleall/maple_me/src/me_may2dassign.cpp | 2 +- src/mapleall/maple_me/src/me_option.cpp | 15 + src/mapleall/maple_me/src/me_placement_rc.cpp | 2 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 4 +- src/mapleall/maple_me/src/me_ssa_epre.cpp | 3 + src/mapleall/maple_me/src/me_ssa_lpre.cpp | 6 +- src/mapleall/maple_me/src/me_ssa_update.cpp | 2 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 22 +- src/mapleall/maple_me/src/me_store_pre.cpp | 2 +- src/mapleall/maple_me/src/occur.cpp | 2 +- src/mapleall/maple_me/src/prop.cpp | 26 +- src/mapleall/maple_me/src/ssa_epre.cpp | 221 +++++------ src/mapleall/maple_me/src/ssa_epre_for_sr.cpp | 329 ++++++++++++++++ src/mapleall/maple_me/src/ssa_pre.cpp | 367 +++++++++--------- 29 files changed, 800 insertions(+), 402 deletions(-) create mode 100644 src/mapleall/maple_me/src/ssa_epre_for_sr.cpp diff --git a/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp b/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp index 94482fb10d..2360811210 100644 --- a/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp +++ b/src/mapleall/maple_ipa/src/ipa_escape_analysis.cpp @@ -592,7 +592,7 @@ void IPAEscapeAnalysis::UpdateEscConnGraphWithStmt(MeStmt &stmt) { break; } CHECK_FATAL(IsExprRefOrPtr(*dasgn->GetRHS()), "type mis-match"); - EACGRefNode *lhsNode = GetOrCreateCGRefNodeForVar(*dasgn->GetVarLHS(), false); + EACGRefNode *lhsNode = GetOrCreateCGRefNodeForVar(*static_cast(dasgn->GetVarLHS()), false); std::vector rhsNodes; GetCGNodeForMeExpr(rhsNodes, *dasgn->GetRHS(), stmt, true); @@ -628,7 +628,7 @@ void IPAEscapeAnalysis::UpdateEscConnGraphWithStmt(MeStmt &stmt) { for (std::pair it : *mdass->GetChiList()) { ChiMeNode *chi = it.second; CHECK_FATAL(IsExprRefOrPtr(*chi->GetLHS()), "type mis-match"); - EACGRefNode *lhsNode = GetOrCreateCGRefNodeForVar(*chi->GetLHS(), false); + EACGRefNode *lhsNode = GetOrCreateCGRefNodeForVar(*static_cast(chi->GetLHS()), false); std::vector rhsNodes; GetCGNodeForMeExpr(rhsNodes, *mdass->GetRHS(), stmt, true); for (const auto &rhsNode : rhsNodes) { diff --git a/src/mapleall/maple_me/BUILD.gn b/src/mapleall/maple_me/BUILD.gn index b6299f9976..2f8e6db555 100755 --- a/src/mapleall/maple_me/BUILD.gn +++ b/src/mapleall/maple_me/BUILD.gn @@ -71,6 +71,7 @@ src_libmplme = [ "src/me_ssa_lpre.cpp", "src/me_ssu_pre.cpp", "src/ssa_epre.cpp", + "src/ssa_epre_for_sr.cpp", "src/ssa_pre.cpp", "src/occur.cpp", "src/me_inequality_graph.cpp", diff --git a/src/mapleall/maple_me/include/me_ir.h b/src/mapleall/maple_me/include/me_ir.h index e22b5974ee..80041f17cd 100644 --- a/src/mapleall/maple_me/include/me_ir.h +++ b/src/mapleall/maple_me/include/me_ir.h @@ -163,8 +163,10 @@ class MeExpr { virtual uint32 GetHashIndex() const { return 0; } + virtual bool StrengthReducible() { return false; } + virtual int64 SRMultiplier() { return 1; } - private: + protected: MeExpr *FindSymAppearance(OStIdx oidx); // find the appearance of the symbol bool IsDexMerge() const; @@ -864,6 +866,8 @@ class OpMeExpr : public MeExpr { } return nullptr; } + bool StrengthReducible() override; + int64 SRMultiplier() override; private: std::array opnds = { nullptr }; // kid @@ -967,13 +971,13 @@ class IvarMeExpr : public MeExpr { volatileFromBaseSymbol = value; } - VarMeExpr *GetMu() { + ScalarMeExpr *GetMu() { return mu; } - const VarMeExpr *GetMu() const { + const ScalarMeExpr *GetMu() const { return mu; } - void SetMuVal(VarMeExpr *muVal) { + void SetMuVal(ScalarMeExpr *muVal) { mu = muVal; } @@ -998,7 +1002,7 @@ class IvarMeExpr : public MeExpr { FieldID fieldID = 0; bool maybeNull = true; // false if definitely not null bool volatileFromBaseSymbol = false; // volatile due to its base symbol being volatile - VarMeExpr *mu = nullptr; // use of mu, only one for IvarMeExpr + ScalarMeExpr *mu = nullptr; // use of mu, only one for IvarMeExpr }; // for array, intrinsicop and intrinsicopwithtype @@ -1217,11 +1221,11 @@ class MeStmt { return nullptr; } - virtual VarMeExpr *GetVarLHS() const { + virtual ScalarMeExpr *GetVarLHS() const { return nullptr; } - virtual VarMeExpr *GetVarLHS() { + virtual ScalarMeExpr *GetVarLHS() { return nullptr; } @@ -1323,23 +1327,23 @@ class ChiMeNode { isLive = value; } - VarMeExpr *GetRHS() { + ScalarMeExpr *GetRHS() { return rhs; } - const VarMeExpr *GetRHS() const { + const ScalarMeExpr *GetRHS() const { return rhs; } - void SetRHS(VarMeExpr *value) { + void SetRHS(ScalarMeExpr *value) { rhs = value; } - VarMeExpr *GetLHS() const { + ScalarMeExpr *GetLHS() const { return lhs; } - void SetLHS(VarMeExpr *value) { + void SetLHS(ScalarMeExpr *value) { lhs = value; } @@ -1354,8 +1358,8 @@ class ChiMeNode { } private: - VarMeExpr *rhs = nullptr; - VarMeExpr *lhs = nullptr; + ScalarMeExpr *rhs = nullptr; + ScalarMeExpr *lhs = nullptr; MeStmt *base; bool isLive = true; }; @@ -1563,6 +1567,8 @@ class AssignMeStmt : public MeStmt { ScalarMeExpr *lhs = nullptr; bool needIncref = false; // to be determined by analyzerc phase bool needDecref = false; // to be determined by analyzerc phase + public: + bool isIncDecStmt = false;// has the form of an increment or decrement stmt }; class DassignMeStmt : public AssignMeStmt { @@ -1607,11 +1613,11 @@ class DassignMeStmt : public AssignMeStmt { void Dump(const IRMap*) const; - VarMeExpr *GetVarLHS() const { + ScalarMeExpr *GetVarLHS() const { return static_cast(lhs); } - VarMeExpr *GetVarLHS() { + ScalarMeExpr *GetVarLHS() { return static_cast(lhs); } @@ -1706,7 +1712,7 @@ class MaydassignMeStmt : public MeStmt { } void Dump(const IRMap*) const; - VarMeExpr *GetLHS() const { + ScalarMeExpr *GetLHS() const { return chiList.find(mayDSSym->GetIndex())->second->GetLHS(); } @@ -1718,11 +1724,11 @@ class MaydassignMeStmt : public MeStmt { rhs = value; } - VarMeExpr *GetVarLHS() const { + ScalarMeExpr *GetVarLHS() const { return chiList.find(mayDSSym->GetIndex())->second->GetLHS(); } - VarMeExpr *GetVarLHS() { + ScalarMeExpr *GetVarLHS() { return chiList.find(mayDSSym->GetIndex())->second->GetLHS(); } @@ -2040,7 +2046,7 @@ class CallMeStmt : public NaryMeStmt, public MuChiMePart, public AssignedPart { return GetAssignedPartLHSRef(excludeLocalRefVar); } - VarMeExpr *GetVarLHS() { + ScalarMeExpr *GetVarLHS() { if (mustDefList.empty() || mustDefList.front().GetLHS()->GetMeOp() != kMeOpVar) { return nullptr; } @@ -2656,7 +2662,7 @@ class AssertMeStmt : public MeStmt { } }; -MapleMap *GenericGetChiListFromVarMeExpr(VarMeExpr &expr); +MapleMap *GenericGetChiListFromVarMeExpr(ScalarMeExpr &expr); void DumpMuList(const IRMap *irMap, const MapleMap &muList); void DumpChiList(const IRMap *irMap, const MapleMap &chiList); class DumpOptions { diff --git a/src/mapleall/maple_me/include/me_option.h b/src/mapleall/maple_me/include/me_option.h index 5d4112e588..61f8eaf7d0 100644 --- a/src/mapleall/maple_me/include/me_option.h +++ b/src/mapleall/maple_me/include/me_option.h @@ -122,6 +122,7 @@ class MeOption : public MapleDriverOptionBase { static bool placementRC; static bool subsumRC; static bool performFSAA; + static bool strengthReduction; static std::string inlineFuncList; static bool meVerify; #if MIR_JAVA diff --git a/src/mapleall/maple_me/include/me_stmt_pre.h b/src/mapleall/maple_me/include/me_stmt_pre.h index 452dc730e3..cc02f07e3d 100644 --- a/src/mapleall/maple_me/include/me_stmt_pre.h +++ b/src/mapleall/maple_me/include/me_stmt_pre.h @@ -60,7 +60,6 @@ class MeStmtPre : public SSAEPre { bool AllVarsSameVersionStmtFre(MeRealOcc &topOcc, MeRealOcc &curOcc) const; void CollectVarForMeStmt(const MeStmt &meStmt, MeExpr *meExpr, std::vector &varVec) const; void CollectVarForCand(MeRealOcc &realOcc, std::vector &varVec) const override; - MeStmt *CopyMeStmt(const MeStmt &meStmt) const override; MeStmt *PhiOpndFromRes4Stmt(MeRealOcc &realZ, size_t j, MeExpr *&lhsVar) const; void Rename1StmtFre(); void Rename2() override; diff --git a/src/mapleall/maple_me/include/occur.h b/src/mapleall/maple_me/include/occur.h index fe49e47319..96f2633637 100644 --- a/src/mapleall/maple_me/include/occur.h +++ b/src/mapleall/maple_me/include/occur.h @@ -272,7 +272,8 @@ class MePhiOpndOcc : public MeOccur { hasRealUse(false), isInsertedOcc(false), isPhiOpndReload(false), - defPhiOcc(nullptr) { + defPhiOcc(nullptr), + phiOpnd4Temp(nullptr) { currentExpr.meStmt = nullptr; } @@ -357,6 +358,8 @@ class MePhiOpndOcc : public MeOccur { MeExpr *meExpr; // the current expression at the end of the block containing this PhiOpnd MeStmt *meStmt; // which will be inserted during finalize } currentExpr; + public: + MeExpr *phiOpnd4Temp; // must be a VarMeExpr/RegMeExpr, set in CodeMotion phase }; class MePhiOcc : public MeOccur { @@ -498,7 +501,8 @@ class PreWorkCand { puIdx(pIdx), hasLocalOpnd(false), redo2HandleCritEdges(false), - needLocalRefVar(false) { + needLocalRefVar(false), + isSRCand(false) { ASSERT(pIdx != 0, "PreWorkCand: initial puIdx cannot be 0"); } @@ -626,6 +630,8 @@ class PreWorkCand { // puIdx cannot be 0 if hasLocalOpnd is true bool redo2HandleCritEdges : 1; // redo to make critical edges affect canbevail bool needLocalRefVar : 1; // for the candidate, if necessary to introduce + public: + bool isSRCand : 1; // is a strength reduction candidate // localrefvar in addition to the temp register to for saving the value }; diff --git a/src/mapleall/maple_me/include/ssa_epre.h b/src/mapleall/maple_me/include/ssa_epre.h index 0bdae5a953..88e5833eab 100644 --- a/src/mapleall/maple_me/include/ssa_epre.h +++ b/src/mapleall/maple_me/include/ssa_epre.h @@ -28,15 +28,15 @@ class SSAEPre : public SSAPre { private: MeExpr *GetTruncExpr(const IvarMeExpr &theLHS, MeExpr &savedRHS); void GenerateSaveLHSRealocc(MeRealOcc &realOcc, ScalarMeExpr ®OrVar); - void GenerateSaveRealOcc(MeRealOcc &realOcc); + void GenerateSaveRealOcc(MeRealOcc &realOcc) override; bool ReserveCalFuncAddrForDecouple(MeExpr &meExpr) const; - void GenerateReloadRealOcc(MeRealOcc &realOcc); - MeExpr *PhiOpndFromRes(MeRealOcc &realZ, size_t j) const; - void ComputeVarAndDfPhis(); - void BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr&, bool isReBuild, MeExpr *tempVar, bool isRootExpr); - void BuildWorkListIvarLHSOcc(MeStmt &meStmt, int32 seqStmt, bool isReBuild, MeExpr *tempVar); - void CollectVarForMeExpr(MeExpr &meExpr, std::vector &varVec) const; - void CollectVarForCand(MeRealOcc &realOcc, std::vector &varVec) const; + void GenerateReloadRealOcc(MeRealOcc &realOcc) override; + MeExpr *PhiOpndFromRes(MeRealOcc &realZ, size_t j) const override; + void ComputeVarAndDfPhis() override; + void BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr&, bool isReBuild, MeExpr *tempVar, bool isRootExpr) override; + void BuildWorkListIvarLHSOcc(MeStmt &meStmt, int32 seqStmt, bool isReBuild, MeExpr *tempVar) override; + void CollectVarForMeExpr(MeExpr &meExpr, std::vector &varVec) const override; + void CollectVarForCand(MeRealOcc &realOcc, std::vector &varVec) const override; bool LeafIsVolatile(const MeExpr *x) const { const VarMeExpr *v = safe_cast(x); return v != nullptr && v->IsVolatile(); @@ -49,7 +49,30 @@ class SSAEPre : public SSAPre { virtual bool CfgHasDoWhile() const { return false; } + // here starts methods related to strength reduction + bool AllVarsSameVersion(const MeRealOcc &realocc1, const MeRealOcc &realocc2) const override; + VarMeExpr *ResolveAllInjuringDefs(VarMeExpr *varx) const override; + RegMeExpr *ResolveAllInjuringDefs(RegMeExpr *regx) const override; + MeExpr *ResolveAllInjuringDefs(MeExpr *x) const override { + if (!workCand->isSRCand) { + return x; + } + return (x->GetMeOp() == kMeOpVar) ? + static_cast(ResolveAllInjuringDefs(static_cast(x))) : + static_cast(ResolveAllInjuringDefs(static_cast(x))); + } + void SubstituteOpnd(MeExpr *x, MeExpr *oldopnd, MeExpr *newopnd) override; + bool OpndInDefOcc(MeExpr *opnd, MeOccur *defocc, uint32 i); + void SRSetNeedRepair(MeOccur *useocc, std::set *needRepairInjuringDefs) override; + MeExpr *InsertRepairStmt(MeExpr *temp, int64 increAmt, MeStmt *injuringDef); + MeExpr *SRRepairOpndInjuries(MeExpr *curopnd, MeOccur *defocc, int32 i, + MeExpr *tempAtDef, std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs); + MeExpr *SRRepairInjuries(MeOccur *useocc, + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) override; + private: bool epreIncludeRef; bool enableLHSIvar; }; diff --git a/src/mapleall/maple_me/include/ssa_pre.h b/src/mapleall/maple_me/include/ssa_pre.h index f34556ed1d..f91b312f8d 100644 --- a/src/mapleall/maple_me/include/ssa_pre.h +++ b/src/mapleall/maple_me/include/ssa_pre.h @@ -60,8 +60,6 @@ class SSAPre { return workCand->GetRealOccs(); } - virtual MeExpr *CopyMeExpr(const MeExpr &expr) const; - virtual MeStmt *CopyMeStmt(const MeStmt &meStmt) const; virtual IassignMeStmt *CopyIassignMeStmt(const IassignMeStmt &iaStmt) const; void IncTreeid() { // Incremented by 2 for each tree; purpose is to avoid processing a node the third time inside a tree @@ -166,7 +164,7 @@ class SSAPre { virtual MeExpr *PhiOpndFromRes(MeRealOcc &realOcc, size_t i) const = 0; virtual void Rename2(); // step 1 phi insertion methods - void SetVarPhis(const MeExpr &meExpr); + void SetVarPhis(MeExpr *meExpr); virtual void ComputeVarAndDfPhis() = 0; virtual void CreateSortedOccs(); // phi insertion methods end @@ -202,6 +200,14 @@ class SSAPre { virtual bool IsLoopHeadBB(BBId) const { return false; } + virtual VarMeExpr *ResolveAllInjuringDefs(VarMeExpr *varx) const { return varx; } + virtual RegMeExpr *ResolveAllInjuringDefs(RegMeExpr *regx) const { return regx; } + virtual MeExpr *ResolveAllInjuringDefs(MeExpr *x) const { return x; } + virtual void SubstituteOpnd(MeExpr *x, MeExpr *oldopnd, MeExpr *newopnd) {} + virtual void SRSetNeedRepair(MeOccur *useocc, std::set *needRepairInjuringDefs) {} + virtual MeExpr *SRRepairInjuries(MeOccur *useocc, + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) { return nullptr; } IRMap *irMap; SSATab *ssaTab; @@ -251,6 +257,8 @@ class SSAPre { bool spillAtCatch = false; bool placementRCEnabled = false; bool addedNewLocalRefVars = false; + public: + bool strengthReduction = false; }; } // namespace maple #endif // MAPLE_ME_INCLUDE_SSAPRE_H diff --git a/src/mapleall/maple_me/src/hdse.cpp b/src/mapleall/maple_me/src/hdse.cpp index b21b584bfd..953f295d0f 100644 --- a/src/mapleall/maple_me/src/hdse.cpp +++ b/src/mapleall/maple_me/src/hdse.cpp @@ -425,7 +425,7 @@ bool HDSE::HasNonDeletableExpr(const MeStmt &meStmt) const { switch (op) { case OP_dassign: { auto &dasgn = static_cast(meStmt); - VarMeExpr *varMeExpr = dasgn.GetVarLHS(); + VarMeExpr *varMeExpr = static_cast(dasgn.GetVarLHS()); return (varMeExpr != nullptr && varMeExpr->IsVolatile()) || ExprNonDeletable(*dasgn.GetRHS()) || (hdseKeepRef && dasgn.Propagated()) || dasgn.GetWasMayDassign() || (decoupleStatic && varMeExpr->GetOst()->GetMIRSymbol()->IsGlobal()); @@ -521,7 +521,7 @@ void HDSE::MarkSingleUseLive(MeExpr &meExpr) { case kMeOpIvar: { auto *base = static_cast(meExpr).GetBase(); MarkSingleUseLive(*base); - VarMeExpr *mu = static_cast(meExpr).GetMu(); + ScalarMeExpr *mu = static_cast(meExpr).GetMu(); workList.push_front(mu); if (mu->GetDefBy() != kDefByNo) { MapleMap *chiList = GenericGetChiListFromVarMeExpr(*mu); diff --git a/src/mapleall/maple_me/src/ipa_side_effect.cpp b/src/mapleall/maple_me/src/ipa_side_effect.cpp index e6d14f8c7c..a76d0479bd 100644 --- a/src/mapleall/maple_me/src/ipa_side_effect.cpp +++ b/src/mapleall/maple_me/src/ipa_side_effect.cpp @@ -738,7 +738,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, AnalyzeExpr(*meStmt.GetOpnd(i), globalExprs, argExprs, nextLevelGlobalExprs, nextLevelArgExprs); } DassignMeStmt &dassignNode = static_cast(meStmt); - VarMeExpr *lhsVar = dassignNode.GetVarLHS(); + VarMeExpr *lhsVar = static_cast(dassignNode.GetVarLHS()); const OriginalSt *ost = meFunc.GetMeSSATab()->GetSymbolOriginalStFromID(lhsVar->GetOstIdx()); if (ost->GetMIRSymbol()->IsGlobal()) { SetHasDef(); @@ -760,10 +760,10 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, SetHasDef(); } if (isGlobal) { - (void)globalExprs.insert(dassignNode.GetChiList()->begin()->second->GetLHS()); + (void)globalExprs.insert(static_cast(dassignNode.GetChiList()->begin()->second->GetLHS())); } if (isArg) { - (void)argExprs.insert(dassignNode.GetChiList()->begin()->second->GetLHS()); + (void)argExprs.insert(static_cast(dassignNode.GetChiList()->begin()->second->GetLHS())); } break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 12e42f0187..f6ccda62eb 100644 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -77,9 +77,20 @@ void IRMapBuild::BuildChiList(MeStmt &meStmt, TypeOfMayDefList &mayDefNodes, for (auto &mayDefNode : mayDefNodes) { VersionSt *opndSt = mayDefNode.GetOpnd(); VersionSt *resSt = mayDefNode.GetResult(); + auto *chiMeStmt = irMap->New(&meStmt); - chiMeStmt->SetRHS(GetOrCreateVarFromVerSt(*opndSt)); - VarMeExpr *lhs = GetOrCreateVarFromVerSt(*resSt); + if (opndSt->GetOst()->IsSymbolOst()) { + chiMeStmt->SetRHS(GetOrCreateVarFromVerSt(*opndSt)); + } else { + chiMeStmt->SetRHS(GetOrCreateRegFromVerSt(*opndSt)); + } + + ScalarMeExpr *lhs = nullptr; + if (resSt->GetOst()->IsSymbolOst()) { + lhs = GetOrCreateVarFromVerSt(*resSt); + } else { + lhs = GetOrCreateRegFromVerSt(*resSt); + } lhs->SetDefBy(kDefByChi); lhs->SetDefChi(*chiMeStmt); chiMeStmt->SetLHS(lhs); @@ -513,6 +524,16 @@ MeStmt *IRMapBuild::BuildDassignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) VarMeExpr *varLHS = static_cast(BuildLHSVar(*ssaPart.GetSSAVar(), *meStmt)); meStmt->SetLHS(varLHS); BuildChiList(*meStmt, ssaPart.GetMayDefNodes(), *meStmt->GetChiList()); + // determine isIncDecStmt + if (meStmt->GetChiList()->empty()) { + MeExpr *rhs = meStmt->GetRHS(); + if (rhs->GetOp() == OP_add || rhs->GetOp() == OP_sub) { + OpMeExpr *oprhs = static_cast(rhs); + if (oprhs->GetOpnd(0)->GetMeOp() == kMeOpVar && oprhs->GetOpnd(1)->GetMeOp() == kMeOpConst) { + meStmt->isIncDecStmt = varLHS->GetOst() == static_cast(oprhs->GetOpnd(0))->GetOst(); + } + } + } if (propagater) { propagater->PropUpdateDef(*meStmt->GetLHS()); propagater->PropUpdateChiListDef(*meStmt->GetChiList()); @@ -526,6 +547,14 @@ MeStmt *IRMapBuild::BuildAssignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { meStmt->SetRHS(BuildExpr(*regNode.Opnd(0), false, false)); auto *regLHS = static_cast(BuildLHSReg(*ssaPart.GetSSAVar(), *meStmt, regNode)); meStmt->SetLHS(regLHS); + // determine isIncDecStmt + MeExpr *rhs = meStmt->GetRHS(); + if (rhs->GetOp() == OP_add || rhs->GetOp() == OP_sub) { + OpMeExpr *oprhs = static_cast(rhs); + if (oprhs->GetOpnd(0)->GetMeOp() == kMeOpReg && oprhs->GetOpnd(1)->GetMeOp() == kMeOpConst) { + meStmt->isIncDecStmt = regLHS->GetOst() == static_cast(oprhs->GetOpnd(0))->GetOst(); + } + } if (propagater) { propagater->PropUpdateDef(*meStmt->GetLHS()); } diff --git a/src/mapleall/maple_me/src/me_delegate_rc.cpp b/src/mapleall/maple_me/src/me_delegate_rc.cpp index 50c0b4d8fd..6e10df2fa5 100644 --- a/src/mapleall/maple_me/src/me_delegate_rc.cpp +++ b/src/mapleall/maple_me/src/me_delegate_rc.cpp @@ -421,7 +421,7 @@ void DelegateRC::DelegateRCTemp(MeStmt &stmt) { if (!stmt.NeedIncref()) { break; } - VarMeExpr *lhsVar = stmt.GetVarLHS(); + ScalarMeExpr *lhsVar = stmt.GetVarLHS(); CHECK_FATAL(lhsVar != nullptr, "null lhs check"); const OriginalSt *ost = lhsVar->GetOst(); if (Options::lazyBinding != 0 || !ost->GetMIRSymbol()->IsGlobal()) { @@ -538,7 +538,7 @@ bool DelegateRC::CanOmitRC4LHSVar(const MeStmt &stmt, bool &onlyWithDecref) cons switch (stmt.GetOp()) { case OP_dassign: case OP_maydassign: { - const VarMeExpr *theLhs = stmt.GetVarLHS(); + const VarMeExpr *theLhs = static_cast(stmt.GetVarLHS()); MeExpr *theRhs = stmt.GetRHS(); CHECK_FATAL(theLhs != nullptr, "null ptr check"); CHECK_FATAL(theRhs != nullptr, "null ptr check"); @@ -623,7 +623,7 @@ void DelegateRC::DelegateHandleNoRCStmt(MeStmt &stmt, bool addDecref) { VarMeExpr *theLhs = nullptr; MeExpr *rhsExpr = stmt.GetRHS(); if (CheckOp(stmt, OP_dassign) || CheckOp(stmt, OP_maydassign)) { - theLhs = stmt.GetVarLHS(); + theLhs = static_cast(stmt.GetVarLHS()); } else if (kOpcodeInfo.IsCallAssigned(stmt.GetOp()) && addDecref) { theLhs = static_cast(stmt.GetAssignedLHS()); } else { @@ -744,7 +744,7 @@ std::set DelegateRC::RenameAndGetLiveLocalRefVar() { } // for live_localrefvars if (CheckOp(stmt, OP_dassign) || CheckOp(stmt, OP_maydassign)) { - VarMeExpr *lhs = stmt.GetVarLHS(); + ScalarMeExpr *lhs = stmt.GetVarLHS(); CHECK_FATAL(lhs != nullptr, "null ptr check"); const OriginalSt *ost = lhs->GetOst(); if (ost->IsLocal() && !ost->IsFormal() && !ost->IsIgnoreRC() && lhs->GetPrimType() == PTY_ref) { diff --git a/src/mapleall/maple_me/src/me_gc_lowering.cpp b/src/mapleall/maple_me/src/me_gc_lowering.cpp index cb1e8e0a8e..448ca9b54d 100644 --- a/src/mapleall/maple_me/src/me_gc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_gc_lowering.cpp @@ -89,7 +89,7 @@ void GCLowering::HandleAssignMeStmt(MeStmt &stmt) { } void GCLowering::HandleVarAssignMeStmt(MeStmt &stmt) { - VarMeExpr *lhsVar = stmt.GetVarLHS(); + VarMeExpr *lhsVar = static_cast(stmt.GetVarLHS()); ASSERT_NOT_NULL(lhsVar); MIRSymbol *lSym = ssaTab.GetMIRSymbolFromID(lhsVar->GetOstIdx()); if (lSym == nullptr || !lSym->IsGlobal()) { diff --git a/src/mapleall/maple_me/src/me_ir.cpp b/src/mapleall/maple_me/src/me_ir.cpp index f006fb2b67..c257bf5317 100644 --- a/src/mapleall/maple_me/src/me_ir.cpp +++ b/src/mapleall/maple_me/src/me_ir.cpp @@ -567,6 +567,20 @@ MeExpr *OpMeExpr::GetIdenticalExpr(MeExpr &expr, bool isConstructor) const { return nullptr; } +bool OpMeExpr::StrengthReducible() { + if (op != OP_mul || !IsPrimitiveInteger(primType)) { + return false; + } + return GetOpnd(1)->GetOp() == OP_constval; +} + +int64 OpMeExpr::SRMultiplier() { + ASSERT(StrengthReducible(), "OpMeExpr::SRMultiplier: operation is not strength reducible"); + MIRConst *constVal = static_cast(GetOpnd(1))->GetConstVal(); + ASSERT(constVal->GetKind() == kConstInt, "OpMeExpr::SRMultiplier: multiplier not an integer constant"); + return static_cast(constVal)->GetValueUnderType(); +} + // first, make sure it's int const and return true if the int const great or eq 0 bool ConstMeExpr::GeZero() const { return (GetIntValue() >= 0); @@ -919,7 +933,7 @@ void NaryMeExpr::Dump(const IRMap *irMap, int32 indent) const { } MeExpr *DassignMeStmt::GetLHSRef(bool excludeLocalRefVar) { - VarMeExpr *lhsOpnd = GetVarLHS(); + ScalarMeExpr *lhsOpnd = GetVarLHS(); if (lhsOpnd->GetPrimType() != PTY_ref) { return nullptr; } @@ -934,7 +948,7 @@ MeExpr *DassignMeStmt::GetLHSRef(bool excludeLocalRefVar) { } MeExpr *MaydassignMeStmt::GetLHSRef(bool excludeLocalRefVar) { - VarMeExpr *lhs = GetVarLHS(); + ScalarMeExpr *lhs = GetVarLHS(); if (lhs->GetPrimType() != PTY_ref) { return nullptr; } @@ -1474,8 +1488,8 @@ bool MeExpr::PointsToSomethingThatNeedsIncRef() { return false; } -MapleMap *GenericGetChiListFromVarMeExprInner(VarMeExpr &expr, - std::unordered_set &visited) { +MapleMap *GenericGetChiListFromVarMeExprInner(ScalarMeExpr &expr, + std::unordered_set &visited) { if (expr.GetDefBy() == kDefByNo || visited.find(&expr) != visited.end()) { return nullptr; } @@ -1498,8 +1512,8 @@ MapleMap *GenericGetChiListFromVarMeExprInner(VarMeExpr &exp return nullptr; } -MapleMap *GenericGetChiListFromVarMeExpr(VarMeExpr &expr) { - std::unordered_set visited; +MapleMap *GenericGetChiListFromVarMeExpr(ScalarMeExpr &expr) { + std::unordered_set visited; return GenericGetChiListFromVarMeExprInner(expr, visited); } diff --git a/src/mapleall/maple_me/src/me_loop_unrolling.cpp b/src/mapleall/maple_me/src/me_loop_unrolling.cpp index 0a093322a6..000fcdead3 100644 --- a/src/mapleall/maple_me/src/me_loop_unrolling.cpp +++ b/src/mapleall/maple_me/src/me_loop_unrolling.cpp @@ -74,7 +74,7 @@ void LoopUnrolling::BuildMustDefList(const BB &bb, MeStmt &newStmt, const MapleV } void LoopUnrolling::CopyDassignStmt(const MeStmt &stmt, BB &bb) { - VarMeExpr *varLHS = static_cast(&stmt)->GetVarLHS(); + VarMeExpr *varLHS = static_cast(static_cast(&stmt)->GetVarLHS()); VarMeExpr *newVarLHS = irMap->CreateVarMeExprVersion(varLHS->GetOst()); InsertCandsForSSAUpdate(newVarLHS->GetOstIdx(), bb); bb.AddMeStmtLast(irMap->CreateAssignMeStmt(*newVarLHS, *stmt.GetRHS(), bb)); diff --git a/src/mapleall/maple_me/src/me_may2dassign.cpp b/src/mapleall/maple_me/src/me_may2dassign.cpp index fda6103494..407f0dd28a 100644 --- a/src/mapleall/maple_me/src/me_may2dassign.cpp +++ b/src/mapleall/maple_me/src/me_may2dassign.cpp @@ -28,7 +28,7 @@ void May2Dassign::DoIt() { auto &mass = static_cast(stmt); // chiList for Maydassign has only 1 element CHECK_FATAL(!mass.GetChiList()->empty(), "chiList is empty in DoIt"); - VarMeExpr *theLhs = mass.GetChiList()->begin()->second->GetLHS(); + VarMeExpr *theLhs = static_cast(mass.GetChiList()->begin()->second->GetLHS()); ASSERT(mass.GetMayDassignSym() == theLhs->GetOst(), "MeDoMay2Dassign: cannot find maydassign lhs"); auto *dass = static_cast(irMap->CreateAssignMeStmt(*theLhs, *mass.GetRHS(), *bb)); diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index ceb474ab4a..4087f4ae04 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -96,6 +96,7 @@ bool MeOption::enableEA = false; bool MeOption::placementRC = false; bool MeOption::subsumRC = false; bool MeOption::performFSAA = true; +bool MeOption::strengthReduction = false; std::string MeOption::inlineFuncList = ""; bool MeOption::meVerify = false; #if MIR_JAVA @@ -183,6 +184,7 @@ enum OptionIndex { kAssign2finalPre, kSubsumRC, kPerformFSAA, + kStrengthReduction, kRegReadAtReturn, kProPatphi, kNoProPatphi, @@ -760,6 +762,16 @@ const Descriptor kUsage[] = { " --no-performFSAA \tDisable flow sensitive alias analysis\n", "me", {} }, + { kStrengthReduction, + kEnable, + "", + "strengthReduction", + kBuildTypeExperimental, + kArgCheckPolicyBool, + " --strengthReduction \tPerform flow sensitive alias analysis\n" + " --no-strengthReduction \tDisable flow sensitive alias analysis\n", + "me", + {} }, { kCheckCastOpt, kEnable, "", @@ -1341,6 +1353,9 @@ bool MeOption::SolveOptions(const std::vector &opts, bool i case kPerformFSAA: performFSAA = (opt.Type() == kEnable); break; + case kStrengthReduction: + strengthReduction = (opt.Type() == kEnable); + break; case kMeInlineHint: inlineFuncList = opt.Args(); break; diff --git a/src/mapleall/maple_me/src/me_placement_rc.cpp b/src/mapleall/maple_me/src/me_placement_rc.cpp index 8592c4e611..00be1e595d 100644 --- a/src/mapleall/maple_me/src/me_placement_rc.cpp +++ b/src/mapleall/maple_me/src/me_placement_rc.cpp @@ -306,7 +306,7 @@ MeStmt *PlacementRC::GetDefStmt(BB &bb) { if (bb.GetAttributes(kBBAttrIsTry)) { for (auto &stmt : bb.GetMeStmts()) { if (stmt.GetOp() == OP_dassign || stmt.GetOp() == OP_maydassign) { - VarMeExpr *lhs = stmt.GetVarLHS(); + VarMeExpr *lhs = static_cast(stmt.GetVarLHS()); CHECK_NULL_FATAL(lhs); if (lhs->GetOst() == workCand->GetTheVar()->GetOst()) { defStmt = &stmt; diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index d9c914f4d4..b87ac307c6 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -681,7 +681,7 @@ void RCLowering::HandleAssignMeStmt(MeStmt &stmt, MeExpr *pendingDec) { } void RCLowering::HandlePerManent(MeStmt &stmt) { - VarMeExpr *lhs = stmt.GetVarLHS(); + VarMeExpr *lhs = static_cast(stmt.GetVarLHS()); if (lhs == nullptr) { return; } @@ -1534,7 +1534,7 @@ void RCLowering::FastLowerRetReg(RetMeStmt &stmt) { } void RCLowering::FastLowerAssignToVar(MeStmt &stmt, MapleMap &exceptionAllocsites) { - VarMeExpr *lhs = stmt.GetVarLHS(); + ScalarMeExpr *lhs = stmt.GetVarLHS(); ASSERT_NOT_NULL(lhs); if (stmt.NeedIncref() || stmt.NeedDecref()) { const MIRSymbol *lSym = lhs->GetOst()->GetMIRSymbol(); diff --git a/src/mapleall/maple_me/src/me_ssa_epre.cpp b/src/mapleall/maple_me/src/me_ssa_epre.cpp index 89942763d4..737ea7ee76 100644 --- a/src/mapleall/maple_me/src/me_ssa_epre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_epre.cpp @@ -85,6 +85,9 @@ AnalysisResult *MeDoSSAEPre::Run(MeFunction *func, MeFuncResultMgr *m, ModuleRes MeSSAEPre ssaPre(*func, *irMap, *dom, kh, *ssaPreMemPool, *NewMemPool(), epreLimitUsed, epreIncludeRef, MeOption::epreLocalRefVar, MeOption::epreLHSIvar); ssaPre.SetSpillAtCatch(MeOption::spillAtCatch); + if (MeOption::strengthReduction) { + ssaPre.strengthReduction = true; + } if (func->GetHints() & kPlacementRCed) { ssaPre.SetPlacementRC(true); } diff --git a/src/mapleall/maple_me/src/me_ssa_lpre.cpp b/src/mapleall/maple_me/src/me_ssa_lpre.cpp index 7073b2dfbc..e8d666a5ae 100644 --- a/src/mapleall/maple_me/src/me_ssa_lpre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_lpre.cpp @@ -47,7 +47,7 @@ void MeSSALPre::GenerateSaveRealOcc(MeRealOcc &realOcc) { } CHECK_FATAL(i < func->GetMirFunc()->GetFormalCount(), "Cannot replace promoted formal"); } else if (realOcc.GetOpcodeOfMeStmt() == OP_dassign || realOcc.GetOpcodeOfMeStmt() == OP_maydassign) { - VarMeExpr *theLHS = realOcc.GetMeStmt()->GetVarLHS(); + VarMeExpr *theLHS = static_cast(realOcc.GetMeStmt()->GetVarLHS()); MeExpr *savedRHS = realOcc.GetMeStmt()->GetRHS(); CHECK_NULL_FATAL(theLHS); CHECK_NULL_FATAL(savedRHS); @@ -172,7 +172,7 @@ void MeSSALPre::ComputeVarAndDfPhis() { GetIterDomFrontier(defBB, &dfPhiDfns); MeExpr *meExpr = realOcc->GetMeExpr(); if (meExpr->GetMeOp() == kMeOpVar) { - SetVarPhis(*meExpr); + SetVarPhis(meExpr); } } } @@ -212,7 +212,7 @@ void MeSSALPre::BuildWorkListLHSOcc(MeStmt &meStmt, int32 seqStmt) { return; } if (meStmt.GetOp() == OP_dassign || meStmt.GetOp() == OP_maydassign) { - VarMeExpr *lhs = meStmt.GetVarLHS(); + VarMeExpr *lhs = static_cast(meStmt.GetVarLHS()); CHECK_NULL_FATAL(lhs); const OriginalSt *ost = lhs->GetOst(); if (mirModule->IsCModule()) { diff --git a/src/mapleall/maple_me/src/me_ssa_update.cpp b/src/mapleall/maple_me/src/me_ssa_update.cpp index 10505e478b..9bf234688a 100644 --- a/src/mapleall/maple_me/src/me_ssa_update.cpp +++ b/src/mapleall/maple_me/src/me_ssa_update.cpp @@ -174,7 +174,7 @@ void MeSSAUpdate::RenameStmts(BB &bb) { } } // process the LHS - VarMeExpr *lhsVar = nullptr; + ScalarMeExpr *lhsVar = nullptr; if (stmt.GetOp() == OP_dassign || stmt.GetOp() == OP_maydassign) { lhsVar = stmt.GetVarLHS(); } else if (kOpcodeInfo.IsCallAssigned(stmt.GetOp())) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index 08c71788c0..757707a7cd 100644 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -93,7 +93,7 @@ void MeStmtPre::CodeMotion() { (void)candsForSSAUpdate[ostIdx]->insert(occ->GetBB()->GetBBId()); } // create a new LHS for the dassign in insertedOcc->GetMeStmt() - VarMeExpr *newVarVersion = irMap->CreateVarMeExprVersion(*dass->GetVarLHS()); + VarMeExpr *newVarVersion = irMap->CreateVarMeExprVersion(*(static_cast(dass->GetVarLHS()))); dass->UpdateLhs(newVarVersion); } else if (insertedOcc->GetOpcodeOfMeStmt() == OP_callassigned) { auto *call = static_cast(insertedOcc->GetMeStmt()); @@ -308,7 +308,7 @@ void MeStmtPre::CollectVarForCand(MeRealOcc &realOcc, std::vector &varV CollectVarForMeStmt(*realOcc.GetMeStmt(), realOcc.GetMeExpr(), varVec); } -MeStmt *MeStmtPre::CopyMeStmt(const MeStmt &meStmt) const { +static MeStmt *CopyMeStmt(IRMap *irMap, const MeStmt &meStmt) { switch (meStmt.GetOp()) { case OP_assertnonnull: { auto *unaryStmt = static_cast(&meStmt); @@ -342,7 +342,7 @@ MeStmt *MeStmtPre::PhiOpndFromRes4Stmt(MeRealOcc &realZ, size_t j, MeExpr *&lhsV MeOccur *defZ = realZ.GetDef(); CHECK_FATAL(defZ != nullptr, "must be def by phiocc"); CHECK_FATAL(defZ->GetOccType() == kOccPhiocc, "must be def by phiocc"); - MeStmt *stmtQ = CopyMeStmt(utils::ToRef(realZ.GetMeStmt())); + MeStmt *stmtQ = CopyMeStmt(irMap, utils::ToRef(realZ.GetMeStmt())); lhsVar = realZ.GetMeExpr(); BB *phiBB = defZ->GetBB(); CHECK_FATAL(stmtQ != nullptr, "nullptr check"); @@ -500,13 +500,13 @@ void MeStmtPre::ComputeVarAndDfPhis() { switch (stmt->GetOp()) { case OP_assertnonnull: { auto *unaryStmt = static_cast(stmt); - SetVarPhis(*unaryStmt->GetOpnd()); + SetVarPhis(unaryStmt->GetOpnd()); break; } case OP_dassign: { auto *dassMeStmt = static_cast(stmt); - SetVarPhis(*dassMeStmt->GetRHS()); - SetVarPhis(*realOcc->GetMeExpr()); + SetVarPhis(dassMeStmt->GetRHS()); + SetVarPhis(realOcc->GetMeExpr()); break; } case OP_intrinsiccall: @@ -514,10 +514,10 @@ void MeStmtPre::ComputeVarAndDfPhis() { case OP_callassigned: { auto *nStmt = static_cast(stmt); for (size_t i = 0; i < nStmt->NumMeStmtOpnds(); ++i) { - SetVarPhis(*nStmt->GetOpnd(i)); + SetVarPhis(nStmt->GetOpnd(i)); } if (realOcc->GetMeExpr() != nullptr) { - SetVarPhis(*realOcc->GetMeExpr()); + SetVarPhis(realOcc->GetMeExpr()); } break; } @@ -541,7 +541,7 @@ void MeStmtPre::CreateSortedOccs() { auto *stmtWkCand = static_cast(workCand); if ((stmtWkCand->GetTheMeStmt()->GetOp() == OP_dassign || stmtWkCand->GetTheMeStmt()->GetOp() == OP_callassigned) && stmtWkCand->GetTheMeStmt()->GetVarLHS() != nullptr && !stmtWkCand->LHSIsFinal()) { - VarMeExpr *lhsVar = stmtWkCand->GetTheMeStmt()->GetVarLHS(); + VarMeExpr *lhsVar = static_cast(stmtWkCand->GetTheMeStmt()->GetVarLHS()); OStIdx ostIdx = lhsVar->GetOstIdx(); MapleMap*>::iterator uMapIt = useOccurMap.find(ostIdx); CHECK_FATAL(uMapIt != useOccurMap.end(), "MeStmtPre::CreateSortedOccs: missing entry in useOccurMap"); @@ -735,7 +735,7 @@ void MeStmtPre::ConstructUseOccurMap() { if (stmtWkCand->LHSIsFinal()) { continue; } - VarMeExpr *lhsVar = stmtWkCand->GetTheMeStmt()->GetVarLHS(); + VarMeExpr *lhsVar = static_cast(stmtWkCand->GetTheMeStmt()->GetVarLHS()); if (lhsVar == nullptr) { continue; } @@ -943,7 +943,7 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { VersionStackChiListUpdate(*dassMeStmt.GetChiList()); break; } - VarMeExpr *varMeExpr = dassMeStmt.GetVarLHS(); + VarMeExpr *varMeExpr = static_cast(dassMeStmt.GetVarLHS()); const OriginalSt *ost = varMeExpr->GetOst(); if (ost->IsFinal()) { PreStmtWorkCand *stmtWkCand = CreateStmtRealOcc(stmt, seqStmt); diff --git a/src/mapleall/maple_me/src/me_store_pre.cpp b/src/mapleall/maple_me/src/me_store_pre.cpp index e61a66b404..3a06327972 100644 --- a/src/mapleall/maple_me/src/me_store_pre.cpp +++ b/src/mapleall/maple_me/src/me_store_pre.cpp @@ -218,7 +218,7 @@ void MeStorePre::CreateRealOcc(const OStIdx &ostIdx, MeStmt &meStmt) { } if (wkCand->GetTheVar() == nullptr) { if (meStmt.GetOp() == OP_dassign) { - wkCand->SetTheVar(*static_cast(&meStmt)->GetVarLHS()); + wkCand->SetTheVar(*static_cast(static_cast(&meStmt)->GetVarLHS())); } else { ASSERT(kOpcodeInfo.IsCallAssigned(meStmt.GetOp()), "CreateRealOcc: callassign expected"); MapleVector *mustDefList = meStmt.GetMustDefList(); diff --git a/src/mapleall/maple_me/src/occur.cpp b/src/mapleall/maple_me/src/occur.cpp index 52aa54ccbe..2671631946 100644 --- a/src/mapleall/maple_me/src/occur.cpp +++ b/src/mapleall/maple_me/src/occur.cpp @@ -323,7 +323,7 @@ uint32 PreWorkCandHashTable::ComputeStmtWorkCandHashIndex(const MeStmt &stmt) { case OP_dassign: { CHECK_NULL_FATAL(stmt.GetVarLHS()); CHECK_NULL_FATAL(stmt.GetRHS()); - VarMeExpr *varMeExpr = stmt.GetVarLHS(); + ScalarMeExpr *varMeExpr = stmt.GetVarLHS(); hIdx += static_cast(varMeExpr->GetOstIdx()) << kOffsetVarMeExprOstIdx; hIdx += ComputeWorkCandHashIndex(*stmt.GetRHS()) << 1; break; diff --git a/src/mapleall/maple_me/src/prop.cpp b/src/mapleall/maple_me/src/prop.cpp index 2041eb5b47..e427276ea1 100644 --- a/src/mapleall/maple_me/src/prop.cpp +++ b/src/mapleall/maple_me/src/prop.cpp @@ -529,6 +529,16 @@ void Prop::TraversalMeStmt(MeStmt &meStmt) { } break; } + case OP_dassign: + case OP_regassign: { + AssignMeStmt *asmestmt = static_cast(&meStmt); + asmestmt->SetRHS(&PropMeExpr(*asmestmt->GetRHS(), subProped, false)); + if (subProped) { + asmestmt->isIncDecStmt = false; + } + PropUpdateDef(*asmestmt->GetLHS()); + break; + } default: for (size_t i = 0; i != meStmt.NumMeStmtOpnds(); ++i) { MeExpr &expr = PropMeExpr(utils::ToRef(meStmt.GetOpnd(i)), subProped, kOpcodeInfo.IsCall(op)); @@ -537,22 +547,6 @@ void Prop::TraversalMeStmt(MeStmt &meStmt) { break; } - // update lhs - switch (op) { - case OP_dassign: { - auto &varMeStmt = static_cast(meStmt); - PropUpdateDef(static_cast(utils::ToRef(varMeStmt.GetLHS()))); - break; - } - case OP_regassign: { - auto ®MeStmt = static_cast(meStmt); - PropUpdateDef(static_cast(utils::ToRef(regMeStmt.GetLHS()))); - break; - } - default: - break; - } - // update chi auto *chiList = meStmt.GetChiList(); if (chiList != nullptr) { diff --git a/src/mapleall/maple_me/src/ssa_epre.cpp b/src/mapleall/maple_me/src/ssa_epre.cpp index 67d924f809..bca8dde259 100644 --- a/src/mapleall/maple_me/src/ssa_epre.cpp +++ b/src/mapleall/maple_me/src/ssa_epre.cpp @@ -14,10 +14,6 @@ */ #include "ssa_epre.h" -namespace { - constexpr maple::uint32 kMeOpOpNum = 3; -} - namespace maple { MeExpr *SSAEPre::GetTruncExpr(const IvarMeExpr &theLHS, MeExpr &savedRHS) { MIRType *lhsType = theLHS.GetType(); @@ -65,6 +61,23 @@ void SSAEPre::GenerateSaveLHSRealocc(MeRealOcc &realOcc, ScalarMeExpr ®OrVar) savedRHS = GetTruncExpr(*theLHS, *savedRHS); if (!workCand->NeedLocalRefVar() || GetPlacementRCOn()) { CHECK_FATAL(regOrVar.GetMeOp() == kMeOpReg, "GenerateSaveLHSRealocc: EPRE temp must b e preg here"); + PrimType lhsPrimType = theLHS->GetType()->GetPrimType(); + if (GetPrimTypeSize(savedRHS->GetPrimType()) > GetPrimTypeSize(lhsPrimType)) { + // insert integer truncation to the rhs + if (GetPrimTypeSize(lhsPrimType) >= 4) { + savedRHS = irMap->CreateMeExprTypeCvt(lhsPrimType, savedRHS->GetPrimType(), *savedRHS); + } else { + Opcode extOp = IsSignedInteger(lhsPrimType) ? OP_sext : OP_zext; + PrimType newPrimType = PTY_u32; + if (IsSignedInteger(lhsPrimType)) { + newPrimType = PTY_i32; + } + OpMeExpr opmeexpr(-1, extOp, newPrimType, 1); + opmeexpr.SetBitsSize(GetPrimTypeSize(lhsPrimType) * 8); + opmeexpr.SetOpnd(0, savedRHS); + savedRHS = irMap->HashMeExpr(opmeexpr); + } + } // change original iassign to regassign; // use placement new to modify in place, because other occ nodes are pointing // to this statement in order to get to the rhs expression; @@ -89,6 +102,8 @@ void SSAEPre::GenerateSaveLHSRealocc(MeRealOcc &realOcc, ScalarMeExpr ®OrVar) dass->SetPrev(savedPrev); dass->SetNext(savedNext); localRefVar->SetDefByStmt(*dass); + + // generate regOrVar = localRefVar rass = irMap->CreateAssignMeStmt(regOrVar, *localRefVar, *savedBB); regOrVar.SetDefByStmt(*rass); savedBB->InsertMeStmtAfter(dass, rass); @@ -122,7 +137,7 @@ void SSAEPre::GenerateSaveRealOcc(MeRealOcc &realOcc) { (realOcc.GetMeStmt()->GetOpnd(0) == realOcc.GetMeExpr())) { isRHSOfDassign = true; // setting flag so delegaterc will skip - static_cast(realOcc.GetMeStmt())->GetVarLHS()->SetNoDelegateRC(true); + static_cast(static_cast(realOcc.GetMeStmt())->GetVarLHS())->SetNoDelegateRC(true); } if (!workCand->NeedLocalRefVar() || isRHSOfDassign || GetPlacementRCOn()) { newMeStmt = irMap->CreateAssignMeStmt(*regOrVar, *realOcc.GetMeExpr(), *realOcc.GetMeStmt()->GetBB()); @@ -205,51 +220,71 @@ MeExpr *SSAEPre::PhiOpndFromRes(MeRealOcc &realZ, size_t j) const { MeOccur *defZ = realZ.GetDef(); CHECK_FATAL(defZ != nullptr, "must be def by phiocc"); CHECK_FATAL(defZ->GetOccType() == kOccPhiocc, "must be def by phiocc"); - MeExpr *exprQ = CopyMeExpr(utils::ToRef(realZ.GetMeExpr())); BB *ePhiBB = defZ->GetBB(); - CHECK_FATAL(exprQ != nullptr, "nullptr check"); - switch (exprQ->GetMeOp()) { + switch (realZ.GetMeExpr()->GetMeOp()) { case kMeOpOp: { - auto *opMeExpr = static_cast(exprQ); - for (size_t i = 0; i < kMeOpOpNum; ++i) { - MeExpr *opnd = opMeExpr->GetOpnd(i); - if (opnd == nullptr) { - break; - }; - MeExpr *retOpnd = GetReplaceMeExpr(*opnd, *ePhiBB, j); + OpMeExpr opMeExpr(*static_cast(realZ.GetMeExpr()), -1); + for (size_t i = 0; i < opMeExpr.GetNumOpnds(); ++i) { + MeExpr *retOpnd = GetReplaceMeExpr(*opMeExpr.GetOpnd(i), *ePhiBB, j); if (retOpnd != nullptr) { - opMeExpr->SetOpnd(i, retOpnd); + opMeExpr.SetOpnd(i, retOpnd); } } - break; + return irMap->HashMeExpr(opMeExpr); } case kMeOpNary: { - auto *naryMeExpr = static_cast(exprQ); - MapleVector &opnds = naryMeExpr->GetOpnds(); - for (size_t i = 0; i < opnds.size(); i++) { - MeExpr *retOpnd = GetReplaceMeExpr(*opnds[i], *ePhiBB, j); + NaryMeExpr naryMeExpr(&irMap->GetIRMapAlloc(), -1, *static_cast(realZ.GetMeExpr())); + for (size_t i = 0; i < naryMeExpr.GetNumOpnds(); i++) { + MeExpr *retOpnd = GetReplaceMeExpr(*naryMeExpr.GetOpnd(i), *ePhiBB, j); if (retOpnd != nullptr) { - opnds[i] = retOpnd; + naryMeExpr.SetOpnd(i, retOpnd); } } - break; + return irMap->HashMeExpr(naryMeExpr); } case kMeOpIvar: { - auto *ivarMeExpr = static_cast(exprQ); - MeExpr *retOpnd = GetReplaceMeExpr(*ivarMeExpr->GetBase(), *ePhiBB, j); + IvarMeExpr ivarMeExpr(-1, *static_cast(realZ.GetMeExpr())); + MeExpr *retOpnd = GetReplaceMeExpr(*ivarMeExpr.GetBase(), *ePhiBB, j); if (retOpnd != nullptr) { - ivarMeExpr->SetBase(retOpnd); + ivarMeExpr.SetBase(retOpnd); } - MeExpr *muOpnd = GetReplaceMeExpr(*ivarMeExpr->GetMu(), *ePhiBB, j); + MeExpr *muOpnd = GetReplaceMeExpr(*ivarMeExpr.GetMu(), *ePhiBB, j); if (muOpnd != nullptr) { - ivarMeExpr->SetMuVal(static_cast(muOpnd)); + ivarMeExpr.SetMuVal(static_cast(muOpnd)); } - break; + return irMap->HashMeExpr(ivarMeExpr); } default: ASSERT(false, "NYI"); } - return irMap->HashMeExpr(*exprQ); + return nullptr; +} + +bool SSAEPre::AllVarsSameVersion(const MeRealOcc &realocc1, const MeRealOcc &realocc2) const { + if (realocc1.GetMeExpr() == realocc2.GetMeExpr()) { + return true; + } else if (!workCand->isSRCand) { + return false; + } + // for each var operand in realocc2, check if it can resolve to the + // corresponding operand in realocc1 via ResolveOneInjuringDef() + for (int32 i = 0; i < realocc2.GetMeExpr()->GetNumOpnds(); i++) { + MeExpr *curopnd = realocc2.GetMeExpr()->GetOpnd(i); + if (curopnd->GetMeOp() != kMeOpVar && curopnd->GetMeOp() != kMeOpReg) { + continue; + } + if (curopnd == realocc1.GetMeExpr()->GetOpnd(i)) { + continue; + } + MeExpr *resolvedOpnd = ResolveAllInjuringDefs(curopnd); + if (resolvedOpnd == curopnd || resolvedOpnd != realocc1.GetMeExpr()->GetOpnd(i)) { + return false; + } + else { + continue; + } + } + return true; } // Df phis are computed into the df_phis set; Var Phis in the var_phis set @@ -263,35 +298,8 @@ void SSAEPre::ComputeVarAndDfPhis() { BB *defBB = realOcc->GetBB(); GetIterDomFrontier(defBB, &dfPhiDfns); MeExpr *meExpr = realOcc->GetMeExpr(); - switch (meExpr->GetMeOp()) { - case kMeOpOp: { - auto *meExprOp = static_cast(meExpr); - for (uint32 i = 0; i < kMeOpOpNum; ++i) { - MeExpr *kidExpr = meExprOp->GetOpnd(i); - if (kidExpr != nullptr) { - SetVarPhis(*kidExpr); - } - } - break; - } - case kMeOpNary: { - auto *naryMeExpr = static_cast(meExpr); - MapleVector &opnds = naryMeExpr->GetOpnds(); - for (size_t i = 0; i < opnds.size(); i++) { - MeExpr *kidExpr = opnds[i]; - if (kidExpr != nullptr) { - SetVarPhis(*kidExpr); - } - } - break; - } - case kMeOpIvar: { - auto *ivarMeExpr = static_cast(meExpr); - SetVarPhis(*ivarMeExpr->GetBase()); - break; - } - default: - CHECK_FATAL(false, "NYI"); + for (int32 i = 0; i < meExpr->GetNumOpnds(); i++) { + SetVarPhis(meExpr->GetOpnd(i)); } } } @@ -309,54 +317,61 @@ void SSAEPre::BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr &meExpr, b switch (meOp) { case kMeOpOp: { auto *meOpExpr = static_cast(&meExpr); - bool isHypo = true; + bool isFirstOrder = true; bool hasTempVarAs1Opnd = false; - for (uint32 i = 0; i < kMeOpOpNum; i++) { + for (uint32 i = 0; i < meOpExpr->GetNumOpnds(); i++) { MeExpr *opnd = meOpExpr->GetOpnd(i); - if (opnd != nullptr) { - if (!opnd->IsLeaf()) { - BuildWorkListExpr(meStmt, seqStmt, *opnd, isRebuild, tempVar, false); - isHypo = false; - } else if (LeafIsVolatile(opnd)) { - isHypo = false; - } else if (tempVar != nullptr && opnd->IsUseSameSymbol(*tempVar)) { - hasTempVarAs1Opnd = true; - } + if (!opnd->IsLeaf()) { + BuildWorkListExpr(meStmt, seqStmt, *opnd, isRebuild, tempVar, false); + isFirstOrder = false; + } else if (LeafIsVolatile(opnd)) { + isFirstOrder = false; + } else if (tempVar != nullptr && opnd->IsUseSameSymbol(*tempVar)) { + hasTempVarAs1Opnd = true; } } + if (!isFirstOrder) { + break; + } if (meExpr.GetPrimType() == PTY_agg) { - isHypo = false; + break; } - if (isHypo && (!isRebuild || hasTempVarAs1Opnd) && !(isRootExpr && kOpcodeInfo.IsCompare(meOpExpr->GetOp())) && - meOpExpr->GetOp() != OP_gcmallocjarray && meOpExpr->GetOp() != OP_gcmalloc && - (epreIncludeRef || meOpExpr->GetPrimType() != PTY_ref)) { - // create a HypotheTemp for this expr - // Exclude cmp operator - (void)CreateRealOcc(meStmt, seqStmt, meExpr, isRebuild); + if (isRootExpr && kOpcodeInfo.IsCompare(meOpExpr->GetOp())) { + break; + } + if (!epreIncludeRef && meOpExpr->GetPrimType() == PTY_ref) { + break; + } + if (meOpExpr->GetOp() == OP_gcmallocjarray || meOpExpr->GetOp() == OP_gcmalloc) { + break; + } + if (isRebuild && !hasTempVarAs1Opnd) { + break; } + (void)CreateRealOcc(meStmt, seqStmt, meExpr, isRebuild); break; } case kMeOpNary: { auto *naryMeExpr = static_cast(&meExpr); - bool isHypo = true; + bool isFirstOrder = true; bool hasTempVarAs1Opnd = false; MapleVector &opnds = naryMeExpr->GetOpnds(); for (auto it = opnds.begin(); it != opnds.end(); ++it) { MeExpr *opnd = *it; if (!opnd->IsLeaf()) { BuildWorkListExpr(meStmt, seqStmt, *opnd, isRebuild, tempVar, false); - isHypo = false; + isFirstOrder = false; } else if (LeafIsVolatile(opnd)) { - isHypo = false; + isFirstOrder = false; } else if (tempVar != nullptr && opnd->IsUseSameSymbol(*tempVar)) { hasTempVarAs1Opnd = true; } } if (meExpr.GetPrimType() == PTY_agg) { - isHypo = false; + isFirstOrder = false; } constexpr uint32 minTypeSizeRequired = 4; - if (isHypo && (!isRebuild || hasTempVarAs1Opnd) && naryMeExpr->GetPrimType() != PTY_u1 && + if (isFirstOrder && (!isRebuild || hasTempVarAs1Opnd) && naryMeExpr->GetPrimType() != PTY_u1 && (GetPrimTypeSize(naryMeExpr->GetPrimType()) >= minTypeSizeRequired || IsPrimitivePoint(naryMeExpr->GetPrimType()) || (naryMeExpr->GetOp() == OP_intrinsicop && IntrinDesc::intrinTable[naryMeExpr->GetIntrinsic()].IsPure())) && @@ -472,42 +487,14 @@ void SSAEPre::BuildWorkListIvarLHSOcc(MeStmt &meStmt, int32 seqStmt, bool isRebu // collect meExpr's variables and put them into varVec // varVec can only store RegMeExpr and VarMeExpr void SSAEPre::CollectVarForMeExpr(MeExpr &meExpr, std::vector &varVec) const { - switch (meExpr.GetMeOp()) { - case kMeOpOp: { - for (uint32 i = 0; i < kMeOpOpNum; i++) { - auto *opMeExpr = static_cast(&meExpr); - MeExpr *opnd = opMeExpr->GetOpnd(i); - if (opnd != nullptr && (opnd->GetMeOp() == kMeOpVar || opnd->GetMeOp() == kMeOpReg)) { - varVec.push_back(opnd); - } - } - break; - } - case kMeOpNary: { - auto *naryMeExpr = static_cast(&meExpr); - const MapleVector &opnds = naryMeExpr->GetOpnds(); - for (MeExpr *kidExpr : opnds) { - if (kidExpr->GetMeOp() == kMeOpVar || kidExpr->GetMeOp() == kMeOpReg) { - varVec.push_back(kidExpr); - } - } - break; - } - case kMeOpIvar: { - auto *ivarMeExpr = static_cast(&meExpr); - CHECK_FATAL(ivarMeExpr->GetBase()->GetMeOp() == kMeOpVar || ivarMeExpr->GetBase()->GetMeOp() == kMeOpConst || - ivarMeExpr->GetBase()->GetMeOp() == kMeOpAddrof || ivarMeExpr->GetBase()->GetMeOp() == kMeOpReg, - "ivarMeExpr not first order expr"); - if (ivarMeExpr->GetBase()->GetMeOp() == kMeOpVar || ivarMeExpr->GetBase()->GetMeOp() == kMeOpReg) { - varVec.push_back(ivarMeExpr->GetBase()); - } - // in case of lhs occurrence, mu can be nullptr, and can use nullptr as value - varVec.push_back(ivarMeExpr->GetMu()); - break; + for (int32 i = 0; i < meExpr.GetNumOpnds(); i++) { + MeExpr *opnd = meExpr.GetOpnd(i); + if (opnd->GetMeOp() == kMeOpVar || opnd->GetMeOp() == kMeOpReg) { + varVec.push_back(opnd); } - default: - ASSERT(false, "should not be here"); - break; + } + if (meExpr.GetMeOp() == kMeOpIvar) { + varVec.push_back(static_cast(meExpr).GetMu()); } } diff --git a/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp new file mode 100644 index 0000000000..ffec581c8e --- /dev/null +++ b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp @@ -0,0 +1,329 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the MulanPSL - 2.0 for more details. + */ + +#include "ssa_epre.h" + +namespace maple { + +static VarMeExpr* ResolveOneInjuringDef(VarMeExpr *varx) { + if (varx->GetDefBy() != kDefByStmt) { + return varx; + } + DassignMeStmt *dass = static_cast(varx->GetDefStmt()); + CHECK_FATAL(dass->GetOp() == OP_dassign, "ResolveInjuringDefs: defStmt is not a dassign"); + CHECK_FATAL(dass->GetLHS() == varx, "ResolveInjuringDefs: defStmt has different lhs"); + if (!dass->isIncDecStmt) { + return varx; + } + CHECK_FATAL(dass->GetRHS()->GetMeOp() == kMeOpOp, "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected rhs form."); + OpMeExpr *oprhs = static_cast(dass->GetRHS()); + CHECK_FATAL(oprhs->GetOpnd(0)->GetMeOp() == kMeOpVar, "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected form."); + VarMeExpr *rhsvar = static_cast(oprhs->GetOpnd(0)); + CHECK_FATAL(rhsvar->GetOst() == varx->GetOst(), "ResolveOneInjuringDef: dassign marked isIncDecStmt has unexpected rhs var."); + return rhsvar; +} + +VarMeExpr* SSAEPre::ResolveAllInjuringDefs(VarMeExpr *varx) const { + if (!workCand->isSRCand) { + return varx; + } + while (true) { + VarMeExpr *answer = ResolveOneInjuringDef(varx); + if (answer == varx) { + return answer; + } else { + varx = answer; + } + } +} + +static RegMeExpr* ResolveOneInjuringDef(RegMeExpr *regx) { + if (regx->GetDefBy() != kDefByStmt) { + return regx; + } + AssignMeStmt *rass = static_cast(regx->GetDefStmt()); + CHECK_FATAL(rass->GetOp() == OP_regassign, "ResolveInjuringDefs: defStmt is not a regassign"); + CHECK_FATAL(rass->GetLHS() == regx, "ResolveInjuringDefs: defStmt has different lhs"); + if (!rass->isIncDecStmt) { + return regx; + } + CHECK_FATAL(rass->GetRHS()->GetMeOp() == kMeOpOp, "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected rhs form."); + OpMeExpr *oprhs = static_cast(rass->GetRHS()); + CHECK_FATAL(oprhs->GetOpnd(0)->GetMeOp() == kMeOpReg, "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected form."); + RegMeExpr *rhsreg = static_cast(oprhs->GetOpnd(0)); + CHECK_FATAL(rhsreg->GetOst() == regx->GetOst(), "ResolveOneInjuringDef: regassign marked isIncDecStmt has unexpected rhs reg."); + return rhsreg; +} + +RegMeExpr* SSAEPre::ResolveAllInjuringDefs(RegMeExpr *regx) const { + if (!workCand->isSRCand) { + return regx; + } + while (true) { + RegMeExpr *answer = ResolveOneInjuringDef(regx); + if (answer == regx) { + return answer; + } else { + regx = answer; + } + } +} + +bool SSAEPre::OpndInDefOcc(MeExpr *opnd, MeOccur *defocc, uint32 i) { + if (defocc->GetOccType() == kOccReal) { + MeRealOcc *defrealocc = static_cast(defocc); + MeExpr *defexpr = defrealocc->GetMeExpr(); + return opnd == defexpr->GetOpnd(i); + } else { // kOccPhi + return DefVarDominateOcc(opnd, *defocc); + } +} + +void SSAEPre::SubstituteOpnd(MeExpr *x, MeExpr *oldopnd, MeExpr *newopnd) { + CHECK_FATAL(x->GetMeOp() == kMeOpOp, "SSAEPre::SubstituteOpnd: unexpected expr kind"); + OpMeExpr *opexpr = static_cast(x); + for (uint32 i = 0; i < opexpr->GetNumOpnds(); i++) { + if (opexpr->GetOpnd(i) == oldopnd) { + opexpr->SetOpnd(i, newopnd); + } + } +} + +void SSAEPre::SRSetNeedRepair(MeOccur *useocc, std::set *needRepairInjuringDefs) { + MeOccur *defocc = useocc->GetDef(); + CHECK_FATAL(defocc != nullptr, "SRSetNeedRepair: occ->def must not be null"); + if (defocc->GetOccType() == kOccInserted) { + CHECK_FATAL(defocc->GetBB() == useocc->GetBB(), "SRSetNeedRepair: unexpected inserted occ"); + return; + } + MeExpr *useexpr = nullptr; + if (useocc->GetOccType() == kOccReal) { + MeRealOcc *realocc = static_cast(useocc); + useexpr = realocc->GetMeExpr(); + } else { + MePhiOpndOcc *phiopndocc = static_cast(useocc); + useexpr = phiopndocc->GetCurrentMeExpr(); + if (useexpr == nullptr) { + return; + } + } + for (int32 i = 0; i < useexpr->GetNumOpnds(); i++) { + MeExpr *curopnd = useexpr->GetOpnd(i); + if (curopnd->GetMeOp() != kMeOpVar && curopnd->GetMeOp() != kMeOpReg) { + continue; + } + if (!OpndInDefOcc(curopnd, defocc, i)) { + if (curopnd->GetMeOp() == kMeOpVar) { + VarMeExpr *varx = static_cast(curopnd); + needRepairInjuringDefs->insert(varx->GetDefStmt()); + } else { + RegMeExpr *regx = static_cast(curopnd); + needRepairInjuringDefs->insert(regx->GetDefStmt()); + } + return; // restricted injury requirement to at most 1 operand + } + } +} + +static int64 GetIncreAmtAndRhsVar(MeExpr *x, VarMeExpr *&rhsvar) { + OpMeExpr *opexpr = static_cast(x); + CHECK_FATAL(opexpr->GetOpnd(0)->GetMeOp() == kMeOpVar, "GetIncreAmtAndRhsVar: cannot find var operand"); + CHECK_FATAL(opexpr->GetOpnd(1)->GetMeOp() == kMeOpConst, "GetIncreAmtAndRhsVar: cannot find constant inc/dec amount"); + rhsvar = static_cast(opexpr->GetOpnd(0)); + MIRConst *constVal = static_cast(opexpr->GetOpnd(1))->GetConstVal(); + CHECK_FATAL(constVal->GetKind() == kConstInt, "GetIncreAmtAndRhsVar: unexpected constant type"); + int64 amt = static_cast(constVal)->GetValueUnderType(); + return (opexpr->GetOp() == OP_sub) ? -amt : amt; +} + +static int64 GetIncreAmtAndRhsReg(MeExpr *x, RegMeExpr *&rhsreg) { + OpMeExpr *opexpr = static_cast(x); + CHECK_FATAL(opexpr->GetOpnd(0)->GetMeOp() == kMeOpReg, "GetIncreAmtAndRhsReg: cannot find reg operand"); + CHECK_FATAL(opexpr->GetOpnd(1)->GetMeOp() == kMeOpConst, "GetIncreAmtAndRhsReg: cannot find constant inc/dec amount"); + rhsreg = static_cast(opexpr->GetOpnd(0)); + MIRConst *constVal = static_cast(opexpr->GetOpnd(1))->GetConstVal(); + CHECK_FATAL(constVal->GetKind() == kConstInt, "GetIncreAmtAndRhsReg: unexpected constant type"); + int64 amt = static_cast(constVal)->GetValueUnderType(); + return (opexpr->GetOp() == OP_sub) ? -amt : amt; +} + +MeExpr* SSAEPre::InsertRepairStmt(MeExpr *temp, int64 increAmt, MeStmt *injuringDef) { + MeExpr *rhs = nullptr; + if (increAmt >= 0) { + rhs = irMap->CreateMeExprBinary(OP_add, temp->GetPrimType(), *temp, *irMap->CreateIntConstMeExpr(increAmt, temp->GetPrimType())); + } else { + rhs = irMap->CreateMeExprBinary(OP_sub, temp->GetPrimType(), *temp, *irMap->CreateIntConstMeExpr(-increAmt, temp->GetPrimType())); + } + BB *bb = injuringDef->GetBB(); + MeStmt *newstmt = nullptr; + if (temp->GetMeOp() == kMeOpReg) { + RegMeExpr *newreg = irMap->CreateRegMeExprVersion(*static_cast(temp)); + newstmt = irMap->CreateAssignMeStmt(*newreg, *rhs, *bb); + static_cast(newstmt)->isIncDecStmt = true; + bb->InsertMeStmtAfter(injuringDef, newstmt); + return newreg; + } else { + VarMeExpr *newvar = irMap->CreateVarMeExprVersion(*static_cast(temp)); + newstmt = irMap->CreateAssignMeStmt(*newvar, *rhs, *bb); + static_cast(newstmt)->isIncDecStmt = true; + bb->InsertMeStmtAfter(injuringDef, newstmt); + return newvar; + } +} + +static MeExpr *FindLaterRepairedTemp(MeExpr *temp, MeStmt *injuringDef) { + if (temp->GetMeOp() == kMeOpReg) { + AssignMeStmt *rass = static_cast(injuringDef->GetNext()); + while (rass != nullptr) { + CHECK_FATAL(rass->GetOp() == OP_regassign && rass->isIncDecStmt, + "FindLaterRepairedTemp: failed to find repair statement"); + if (rass->GetLHS()->GetRegIdx() == static_cast(temp)->GetRegIdx()) { + return rass->GetLHS(); + } + rass = static_cast(rass->GetNext()); + } + } else { // kMeOpVar + DassignMeStmt *dass = static_cast(injuringDef->GetNext()); + while (dass != nullptr) { + CHECK_FATAL(dass->GetOp() == OP_dassign && dass->isIncDecStmt, + "FindLaterRepairedTemp: failed to find repair statement"); + if (dass->GetLHS()->GetOst() == static_cast(temp)->GetOst()) { + return dass->GetLHS(); + } + dass = static_cast(dass->GetNext()); + } + } + CHECK_FATAL(false, "FindLaterRepairedTemp: failed to find repair statement"); + return nullptr; +} + +MeExpr* SSAEPre::SRRepairOpndInjuries(MeExpr *curopnd, MeOccur *defocc, int32 i, + MeExpr *tempAtDef, + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) { + MeExpr *repairedTemp = tempAtDef; + if (curopnd->GetMeOp() == kMeOpVar) { + VarMeExpr *varx = static_cast(curopnd); + DassignMeStmt *dass = static_cast(varx->GetDefStmt()); + CHECK_FATAL(dass->isIncDecStmt, "SRRepairInjuries: not an inc/dec statement"); + MeStmt *latestInjuringDef = dass; + if (repairedInjuringDefs->count(dass) == 0) { + repairedInjuringDefs->insert(dass); + bool done = false; + int64 increAmt = 0; + VarMeExpr *rhsvar = nullptr; + do { + increAmt += GetIncreAmtAndRhsVar(dass->GetRHS(), rhsvar); + if (OpndInDefOcc(rhsvar, defocc, i)) { + done = true; + } else { + varx = rhsvar; + dass = static_cast(varx->GetDefStmt()); + CHECK_FATAL(dass->isIncDecStmt, "SRRepairInjuries: not an inc/dec statement"); + done = needRepairInjuringDefs->count(dass) == 1; + if (done) { + if (repairedInjuringDefs->count(dass) == 0) { + repairedTemp = SRRepairOpndInjuries(varx, defocc, i, tempAtDef, needRepairInjuringDefs, repairedInjuringDefs); + } + repairedTemp = FindLaterRepairedTemp(repairedTemp, dass); + } + } + } while (!done); + // generate the increment statement at latestInjuringDef + repairedTemp = InsertRepairStmt(repairedTemp, increAmt*workCand->GetTheMeExpr()->SRMultiplier(), latestInjuringDef); + } else { + // find the last repair increment statement + repairedTemp = FindLaterRepairedTemp(repairedTemp, latestInjuringDef); + } + } else { // kMeOpReg + RegMeExpr *regx = static_cast(curopnd); + AssignMeStmt *rass = static_cast(regx->GetDefStmt()); + CHECK_FATAL(rass->isIncDecStmt, "SRRepairInjuries: not an inc/dec statement"); + MeStmt *latestInjuringDef = rass; + if (repairedInjuringDefs->count(rass) == 0) { + repairedInjuringDefs->insert(rass); + bool done = false; + int64 increAmt = 0; + RegMeExpr *rhsreg = nullptr; + do { + increAmt += GetIncreAmtAndRhsReg(rass->GetRHS(), rhsreg); + if (OpndInDefOcc(rhsreg, defocc, i)) { + done = true; + } else { + regx = rhsreg; + rass = static_cast(regx->GetDefStmt()); + CHECK_FATAL(rass->isIncDecStmt, "SRRepairInjuries: not an inc/dec statement"); + done = needRepairInjuringDefs->count(rass) == 1; + if (done) { + if (repairedInjuringDefs->count(rass) == 0) { + repairedTemp = SRRepairOpndInjuries(regx, defocc, i, tempAtDef, needRepairInjuringDefs, repairedInjuringDefs); + } + repairedTemp = FindLaterRepairedTemp(repairedTemp, rass); + } + } + } while (!done); + // generate the increment statement at latestInjuringDef + repairedTemp = InsertRepairStmt(repairedTemp, increAmt*workCand->GetTheMeExpr()->SRMultiplier(), latestInjuringDef); + } else { + // find the last repair increment statement + repairedTemp = FindLaterRepairedTemp(repairedTemp, latestInjuringDef); + } + } + return repairedTemp; +} + +MeExpr* SSAEPre::SRRepairInjuries(MeOccur *useocc, + std::set *needRepairInjuringDefs, + std::set *repairedInjuringDefs) { + MeExpr *useexpr = nullptr; + if (useocc->GetOccType() == kOccReal) { + MeRealOcc *realocc = static_cast(useocc); + useexpr = realocc->GetMeExpr(); + } else { + MePhiOpndOcc *phiopndocc = static_cast(useocc); + useexpr = phiopndocc->GetCurrentMeExpr(); + } + MeOccur *defocc = useocc->GetDef(); + MeExpr *repairedTemp = nullptr; + if (defocc->GetOccType() == kOccInserted) { + CHECK_FATAL(defocc->GetBB() == useocc->GetBB(), "SRRepairInjuries: unexpected inserted occ"); + return static_cast(defocc)->GetSavedExpr(); + } + if (defocc->GetOccType() == kOccReal) { + MeRealOcc *defrealocc = static_cast(defocc); + repairedTemp = defrealocc->GetSavedExpr(); + } else { // kOccPhiocc + MePhiOcc *defphiocc = static_cast(defocc); + MePhiNode *scalarPhi = (defphiocc->GetRegPhi() ? defphiocc->GetRegPhi() : defphiocc->GetVarPhi()); + repairedTemp = scalarPhi->GetLHS(); + } + if (useexpr == nullptr) { + return repairedTemp; + } + for (int32 i = 0; i < useexpr->GetNumOpnds(); i++) { + MeExpr *curopnd = useexpr->GetOpnd(i); + if (curopnd->GetMeOp() != kMeOpVar && curopnd->GetMeOp() != kMeOpReg) { + continue; + } + if (!OpndInDefOcc(curopnd, defocc, i)) { + repairedTemp = SRRepairOpndInjuries(curopnd, defocc, i, repairedTemp, needRepairInjuringDefs, repairedInjuringDefs); + // restricted to only 1 var or reg injured + break; + } + } // for + return repairedTemp; +} + +} // namespace maple diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index a393f2a43f..1672d2452a 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -48,44 +48,15 @@ ScalarMeExpr *SSAPre::CreateNewCurTemp(const MeExpr &meExpr) { if (workCand->GetPUIdx() != 0) { // allocate a new temp SetCurFunction(workCand->GetPUIdx()); - RegMeExpr *regVar = nullptr; - if (meExpr.GetMeOp() == kMeOpVar) { - auto *ty = static_cast(meExpr).GetType(); - regVar = ty->GetPrimType() == PTY_ref ? irMap->CreateRegMeExpr(*ty) - : irMap->CreateRegMeExpr(ty->GetPrimType()); - } else if (meExpr.GetMeOp() == kMeOpIvar) { - auto *ivarMeExpr = static_cast(&meExpr); - MIRType *ptrMIRType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ivarMeExpr->GetTyIdx()); - CHECK_FATAL(ptrMIRType->GetKind() == kTypePointer, "must be point type for ivar"); - auto *realMIRType = static_cast(ptrMIRType); - FieldID fieldId = ivarMeExpr->GetFieldID(); - MIRType *ty = nullptr; - if (fieldId > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(realMIRType->GetPointedTyIdxWithFieldID(fieldId)); - } else { - ty = realMIRType->GetPointedType(); - } - CHECK_FATAL(GetRegPrimType(ty->GetPrimType()) == GetRegPrimType(meExpr.GetPrimType()) || - GetReg64PrimType(ty->GetPrimType()) == GetReg64PrimType(meExpr.GetPrimType()) || - (IsAddress(ty->GetPrimType()) && IsAddress(meExpr.GetPrimType())) || - (ty->GetPrimType() == PTY_ptr && meExpr.GetPrimType() == PTY_ref) || - (ty->GetPrimType() == PTY_ref && meExpr.GetPrimType() == PTY_ptr), - "inconsistent type"); - regVar = (ty->GetPrimType() == PTY_ref) ? (irMap->CreateRegMeExpr(*ty)) - : (irMap->CreateRegMeExpr(ty->GetPrimType())); - } else { - regVar = meExpr.GetPrimType() != PTY_ref ? irMap->CreateRegMeExpr(meExpr.GetPrimType()) - : irMap->CreateRegMeExpr(meExpr); - } + RegMeExpr *regVar = irMap->CreateRegMeExpr(meExpr); curTemp = regVar; if (preKind == kLoadPre) { irMap->SetLpreTmps(static_cast(&meExpr)->GetOstIdx(), *regVar); } return regVar; } else { - VarMeExpr *tempVar = irMap->CreateNewVar(NewTempStrIdx(), meExpr.GetPrimType(), true); - curTemp = tempVar; - return tempVar; + curTemp = irMap->CreateNewVar(NewTempStrIdx(), meExpr.GetPrimType(), true); + return curTemp; } } @@ -169,7 +140,7 @@ void SSAPre::GenerateSavePhiOcc(MePhiOcc &phiOcc) { void SSAPre::UpdateInsertedPhiOccOpnd() { for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { MePhiOcc *phiOcc = *it; - if (!phiOcc->IsWillBeAvail() || phiOcc->IsExtraneous()) { + if (!phiOcc->IsWillBeAvail() || phiOcc->IsRemoved()) { continue; } if (phiOcc->GetRegPhi()) { @@ -224,10 +195,40 @@ void SSAPre::UpdateInsertedPhiOccOpnd() { } void SSAPre::CodeMotion() { + std::set needRepairInjuringDefs; // for marking injuring defs that have been repaired + + if (workCand->isSRCand) { // pre-pass needed by strength reduction + for (MeOccur *occ : allOccs) { + switch (occ->GetOccType()) { + case kOccReal: { + MeRealOcc *realocc = static_cast(occ); + if (realocc->IsReload()) { + SRSetNeedRepair(realocc, &needRepairInjuringDefs); + } + break; + } + case kOccPhiopnd: { + MePhiOpndOcc *phiopnd = static_cast(occ); + if (phiopnd->GetDefPhiOcc()->IsRemoved() || !phiopnd->GetDefPhiOcc()->IsWillBeAvail()) { + break; + } + if (phiopnd->GetDef()->GetOccType() == kOccInserted) { + break; + } + SRSetNeedRepair(phiopnd, &needRepairInjuringDefs); + break; + } + default: ; + } + } + } + curTemp = nullptr; curLocalRefVar = nullptr; temp2LocalRefVarMap.clear(); reBuiltOccIndex = static_cast(workList.size()); // so we know the elements added due to rebuilding + std::set repairedInjuringDefs; // for marking injuring defs that have been repaired + for (MeOccur *occ : allOccs) { switch (occ->GetOccType()) { case kOccReal: { @@ -236,13 +237,23 @@ void SSAPre::CodeMotion() { CHECK_FATAL(!(realOcc->IsReload()), "reload failed"); GenerateSaveRealOcc(*realOcc); } else if (realOcc->IsReload()) { - GenerateReloadRealOcc(*realOcc); + if (!workCand->isSRCand) { + GenerateReloadRealOcc(*realOcc); + } else { + MeExpr *regorvar = SRRepairInjuries(realOcc, &needRepairInjuringDefs, &repairedInjuringDefs); + // replace realOcc->mestmt's occ with regorvar + bool isreplaced = irMap->ReplaceMeExprStmt(*realOcc->GetMeStmt(), *realOcc->GetMeExpr(), *regorvar); + // update worklist + if (isreplaced) { + BuildWorkListStmt(*realOcc->GetMeStmt(), realOcc->GetSequence(), true, regorvar); + } + } } break; } case kOccPhiopnd: { auto *phiOpnd = static_cast(occ); - if (!phiOpnd->GetDefPhiOcc()->IsWillBeAvail()) { + if (phiOpnd->GetDefPhiOcc()->IsRemoved() || !phiOpnd->GetDefPhiOcc()->IsWillBeAvail()) { break; } MeOccur *defOcc = phiOpnd->GetDef(); @@ -250,13 +261,27 @@ void SSAPre::CodeMotion() { // generate a save of the result in to a new version of t if (!phiOpnd->IsPhiOpndReload()) { GenerateSaveInsertedOcc(*static_cast(defOcc)); + phiOpnd->phiOpnd4Temp = static_cast(defOcc)->GetSavedExpr(); + } + } else { + // set phiOpnd4Temp needed in the temp's phi + if (workCand->isSRCand) { + phiOpnd->phiOpnd4Temp = SRRepairInjuries(phiOpnd, &needRepairInjuringDefs, &repairedInjuringDefs); + } else { + if (defOcc->GetOccType() == kOccReal) { + phiOpnd->phiOpnd4Temp = static_cast(defOcc)->GetSavedExpr(); + } else { + MePhiOcc *defphiocc = static_cast(defOcc); + MePhiNode *scalarPhi = (defphiocc->GetRegPhi() ? defphiocc->GetRegPhi() : defphiocc->GetVarPhi()); + phiOpnd->phiOpnd4Temp = scalarPhi->GetLHS(); + } } } break; } case kOccPhiocc: { auto *phiOcc = static_cast(occ); - if (phiOcc->IsExtraneous() || !phiOcc->IsWillBeAvail()) { + if (phiOcc->IsRemoved() || !phiOcc->IsWillBeAvail()) { break; }; GenerateSavePhiOcc(*phiOcc); @@ -448,7 +473,10 @@ void SSAPre::Finalize2() { for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { MePhiOcc *phiOcc = *it; // initialize extraneouse for each MePhiOcc - phiOcc->SetIsExtraneous(phiOcc->IsWillBeAvail()); + if (!workCand->isSRCand) { + phiOcc->SetIsExtraneous(phiOcc->IsWillBeAvail()); + } + // initialize each operand of phiOcc for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { phiOpnd->SetIsProcessed(false); @@ -460,41 +488,46 @@ void SSAPre::Finalize2() { SetSave(*realOcc->GetDef()); } } - for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { - MePhiOcc *phiOcc = *it; - if (phiOcc->IsRemoved() || !phiOcc->IsExtraneous()) { - continue; - } - if (!phiOcc->IsWillBeAvail()) { - phiOcc->SetIsRemoved(true); - continue; - } - for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { - MeOccur *defOcc = phiOpnd->GetDef(); - switch (defOcc->GetOccType()) { - case kOccReal: - case kOccInserted: - SetReplacement(*phiOcc, *defOcc); - break; - case kOccPhiocc: - if (!static_cast(defOcc)->IsExtraneous()) { + if (!workCand->isSRCand) { + for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { + MePhiOcc *phiOcc = *it; + if (phiOcc->IsRemoved() || !phiOcc->IsExtraneous()) { + continue; + } + if (!phiOcc->IsWillBeAvail()) { + phiOcc->SetIsRemoved(true); + continue; + } + for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { + MeOccur *defOcc = phiOpnd->GetDef(); + switch (defOcc->GetOccType()) { + case kOccReal: SetReplacement(*phiOcc, *defOcc); - } - break; - default: - CHECK_FATAL(false, "unexpected phiOpnd"); + break; + case kOccInserted: + break; + case kOccPhiocc: + if (!static_cast(defOcc)->IsExtraneous()) { + SetReplacement(*phiOcc, *defOcc); + } + break; + default: + CHECK_FATAL(false, "unexpected phiOpnd"); + } } } } + if (GetSSAPreDebug()) { mirModule->GetOut() << "========after Finalize2====================\n"; for (MeOccur *occ : allOccs) { if (occ->GetOccType() == kOccPhiocc) { auto *phiOcc = static_cast(occ); - if (phiOcc->IsExtraneous()) { - phiOcc->Dump(*irMap); - mirModule->GetOut() << "was removed in Finalize2\n"; + phiOcc->Dump(*irMap); + if (phiOcc->IsRemoved()) { + mirModule->GetOut() << "was removed in Finalize2"; } + mirModule->GetOut() << std::endl; } else if (occ->GetOccType() == kOccReal) { auto *realOcc = static_cast(occ); if (realOcc->IsReload()) { @@ -853,8 +886,10 @@ MeExpr *SSAPre::GetReplaceMeExpr(const MeExpr &opnd, const BB &ePhiBB, size_t j) return nullptr; } MeExpr *retExpr = nullptr; - MePhiNode *defPhi = static_cast(&opnd)->GetMePhiDef(); - if (defPhi != nullptr) { + + const ScalarMeExpr *expr = static_cast(&opnd); + if (expr->IsDefByPhi()) { + MePhiNode *defPhi = expr->GetMePhiDef(); if (ePhiBB.GetBBId() == defPhi->GetDefBB()->GetBBId()) { ASSERT(j < defPhi->GetOpnds().size(), "index out of range in SSAPre::GetReplaceMeExpr"); ASSERT(defPhi->GetOpnds()[j]->GetMeOp() == opnd.GetMeOp(), "invalid defPhi"); @@ -913,9 +948,23 @@ void SSAPre::Rename2() { std::vector varVecY; bool alldom = true; CollectVarForMeExpr(*exprY, varVecY); - for (size_t ii = 0; ii < varVecY.size(); ++ii) { - if (!DefVarDominateOcc(varVecY[ii], *defX)) { - alldom = false; + if (exprY->GetMeOp() == kMeOpOp) { + OpMeExpr opmeexpr(*static_cast(exprY), -1); + for (uint32 ii = 0; ii < varVecY.size(); ii++) { + MeExpr *resolvedY = ResolveAllInjuringDefs(varVecY[ii]); + if (resolvedY != varVecY[ii]) { + SubstituteOpnd(&opmeexpr, varVecY[ii], resolvedY); + } + if (!DefVarDominateOcc(resolvedY, *defX)) { + alldom = false; + } + } + exprY = irMap->HashMeExpr(opmeexpr); + } else { + for (size_t ii = 0; ii < varVecY.size(); ++ii) { + if (!DefVarDominateOcc(varVecY[ii], *defX)) { + alldom = false; + } } } if (alldom) { @@ -953,20 +1002,25 @@ void SSAPre::Rename2() { } // ================ Step 1: Phi Insertion ================= -void SSAPre::SetVarPhis(const MeExpr &meExpr) { - MeExprOp meOp = meExpr.GetMeOp(); +void SSAPre::SetVarPhis(MeExpr *meExpr) { + MeExprOp meOp = meExpr->GetMeOp(); if (meOp != kMeOpVar && meOp != kMeOpReg) { return; } - MePhiNode *phiMeNode = static_cast(&meExpr)->GetMePhiDef(); - if (phiMeNode != nullptr) { + + ScalarMeExpr *scalar = static_cast(meExpr); + if (workCand->isSRCand) { + scalar = ResolveAllInjuringDefs(scalar); + } + if (scalar->IsDefByPhi()) { + MePhiNode *phiMeNode = scalar->GetMePhiDef(); BBId defBBId = phiMeNode->GetDefBB()->GetBBId(); CHECK(defBBId < dom->GetDtDfnSize(), "defBBId.idx out of range in SSAPre::SetVarPhis"); if (varPhiDfns.find(dom->GetDtDfnItem(defBBId)) == varPhiDfns.end() && ScreenPhiBB(defBBId)) { (void)varPhiDfns.insert(dom->GetDtDfnItem(defBBId)); for (auto opndIt = phiMeNode->GetOpnds().begin(); opndIt != phiMeNode->GetOpnds().end(); ++opndIt) { ScalarMeExpr *opnd = *opndIt; - SetVarPhis(*opnd); + SetVarPhis(opnd); } } } @@ -1119,37 +1173,6 @@ IassignMeStmt *SSAPre::CopyIassignMeStmt(const IassignMeStmt &iaStmt) const { return meStmt; } -MeStmt *SSAPre::CopyMeStmt(const MeStmt &meStmt) const { - CHECK_FATAL(meStmt.GetOp() == OP_assertlt || meStmt.GetOp() == OP_assertge, "invalid value of meStmt.GetOp()"); - auto *oldStmt = static_cast(&meStmt); - AssertMeStmt *newStmt = irMap->New(*oldStmt); - return newStmt; -} - -MeExpr *SSAPre::CopyMeExpr(const MeExpr &expr) const { - ASSERT_NOT_NULL(irMap); - MapleAllocator *irMapAlloc = &irMap->GetIRMapAlloc(); - switch (expr.GetMeOp()) { - case kMeOpOp: { - auto &opExpr = static_cast(expr); - OpMeExpr *newExpr = irMapAlloc->GetMemPool()->New(opExpr, -1); - return newExpr; - } - case kMeOpNary: { - auto &naryMeExpr = static_cast(expr); - NaryMeExpr *newNaryMeExpr = irMapAlloc->GetMemPool()->New(irMapAlloc, -1, naryMeExpr); - return newNaryMeExpr; - } - case kMeOpIvar: { - auto &ivarMeExpr = static_cast(expr); - IvarMeExpr *newIvar = irMapAlloc->GetMemPool()->New(-1, ivarMeExpr); - return newIvar; - } - default: - CHECK_FATAL(false, "NYI"); - } -} - // if the definition of varMeExpr dominate meocc then return true. otherwise return false; bool SSAPre::DefVarDominateOcc(const MeExpr *meExpr, const MeOccur &meOcc) const { if (meExpr == nullptr) { @@ -1158,104 +1181,53 @@ bool SSAPre::DefVarDominateOcc(const MeExpr *meExpr, const MeOccur &meOcc) const } CHECK_FATAL(meOcc.GetOccType() == kOccPhiocc, "invalid value of meOcc->GetOccType()"); const BB *occBB = (static_cast(&meOcc))->GetBB(); - if (meExpr->GetMeOp() == kMeOpVar) { - auto *varMeExpr = static_cast(meExpr); - switch (varMeExpr->GetDefBy()) { - case kDefByNo: - // zero version vst dominate everything - return ssaTab->IsInitVersion(varMeExpr->GetVstIdx(), varMeExpr->GetOstIdx()); - case kDefByStmt: { - MeStmt *meStmt = varMeExpr->GetDefStmt(); - CHECK_FATAL(meStmt != nullptr, "should have a def meStmt"); - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); - } - case kDefByPhi: { - const MePhiNode &phiMeNode = varMeExpr->GetDefPhi(); - const BB *defBB = phiMeNode.GetDefBB(); - if (defBB->GetBBId() == occBB->GetBBId()) { - return true; - } - return dom->Dominate(*defBB, *occBB); - } - case kDefByMustDef: { - const MeStmt *meStmt = varMeExpr->GetDefMustDef().GetBase(); - if (meStmt == nullptr) { - return true; // it's a original variable dominate everything - } - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); + const ScalarMeExpr *scMeExpr = static_cast(meExpr); + switch (scMeExpr->GetDefBy()) { + case kDefByNo: + return true; // original version dominates everything + case kDefByStmt: { + MeStmt *meStmt = scMeExpr->GetDefStmt(); + CHECK_FATAL(meStmt != nullptr, "should have a def meStmt"); + BB *defBB = meStmt->GetBB(); + if (occBB == defBB) { + return false; } - case kDefByChi: { - MeStmt *meStmt = varMeExpr->GetDefChi().GetBase(); - if (meStmt == nullptr) { - return true; // it's a original variable dominate everything - } - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); + return dom->Dominate(*defBB, *occBB); + } + case kDefByPhi: { + const MePhiNode &phiMeNode = scMeExpr->GetDefPhi(); + const BB *defBB = phiMeNode.GetDefBB(); + if (defBB->GetBBId() == occBB->GetBBId()) { + return true; } - default: - CHECK_FATAL(false, "NYI"); + return dom->Dominate(*defBB, *occBB); } - } else { - CHECK_FATAL(meExpr->GetMeOp() == kMeOpReg, "invalid value of meExpr->GetMeOp()"); - auto *regMeExpr = static_cast(meExpr); - switch (regMeExpr->GetDefBy()) { - case kDefByNo: - return true; // original st dominates everything - case kDefByStmt: { - MeStmt *meStmt = regMeExpr->GetDefStmt(); - CHECK_FATAL(meStmt != nullptr, "invalid value of meStmt"); - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); + case kDefByMustDef: { + const MeStmt *meStmt = scMeExpr->GetDefMustDef().GetBase(); + if (meStmt == nullptr) { + return true; // it's a original variable dominate everything } - case kDefByPhi: { - const MePhiNode &phiMeNode = regMeExpr->GetDefPhi(); - const BB *defBB = phiMeNode.GetDefBB(); - if (defBB->GetBBId() == occBB->GetBBId()) { - return true; - } - return dom->Dominate(*defBB, *occBB); + BB *defBB = meStmt->GetBB(); + if (occBB == defBB) { + return false; } - case kDefByMustDef: { - const MeStmt *meStmt = regMeExpr->GetDefMustDef().GetBase(); - if (meStmt == nullptr) { - return true; // it's a original variable dominate everything - } - BB *defBB = meStmt->GetBB(); - if (occBB == defBB) { - return false; - } - return dom->Dominate(*defBB, *occBB); + return dom->Dominate(*defBB, *occBB); + } + case kDefByChi: { + MeStmt *meStmt = scMeExpr->GetDefChi().GetBase(); + if (meStmt == nullptr) { + return true; // it's a original variable dominate everything } - case kDefByChi: { - MeStmt *mestmt = regMeExpr->GetDefChi().GetBase(); - if (!mestmt) { - return true; // it's a original variable dominate everything - } - BB *defBB = mestmt->GetBB(); - if (occBB == defBB) { - return false; - } else { - return dom->Dominate(*defBB, *occBB); - } + BB *defBB = meStmt->GetBB(); + if (occBB == defBB) { + return false; } - default: - CHECK_FATAL(false, "NYI"); + return dom->Dominate(*defBB, *occBB); } + default: + CHECK_FATAL(false, "NYI"); } + return false; } bool SSAPre::CheckIfAnyLocalOpnd(const MeExpr &meExpr) const { @@ -1342,6 +1314,8 @@ MeRealOcc *SSAPre::CreateRealOcc(MeStmt &meStmt, int seqStmt, MeExpr &meExpr, bo MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fldPair.first); bool isFinal = fldPair.second.GetAttr(FLDATTR_final); wkCand->SetNeedLocalRefVar(ty->GetPrimType() == PTY_ref && !isFinal); + } else if (strengthReduction && meExpr.StrengthReducible()) { + wkCand->isSRCand = true; } workList.push_back(wkCand); wkCand->AddRealOccAsLast(*newOcc, GetPUIdx()); @@ -1434,12 +1408,21 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE } case OP_dassign: { auto *dassMeStmt = static_cast(meStmt); + if (dassMeStmt->isIncDecStmt && preKind == kExprPre) { + break; + } + if (dassMeStmt->GetRHS()->GetMeOp() == dassMeStmt->GetLHS()->GetMeOp() && dassMeStmt->GetLHS()->GetOst() == static_cast(dassMeStmt->GetRHS())->GetOst()) { + break; // identity assignment converted from phi + } BuildWorkListExpr(*meStmt, static_cast(seqStmt), *dassMeStmt->GetRHS(), isRebuilt, tempVar, true); BuildWorkListLHSOcc(*meStmt, static_cast(seqStmt)); break; } case OP_regassign: { auto *rassMeStmt = static_cast(meStmt); + if (rassMeStmt->isIncDecStmt && preKind == kExprPre) { + break; + } BuildWorkListExpr(*meStmt, static_cast(seqStmt), *rassMeStmt->GetRHS(), isRebuilt, tempVar, true); break; } -- Gitee From 1982ef70e1fab9cb10daef8f7a7fa29c8b6155cc Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sun, 23 May 2021 08:00:48 -0700 Subject: [PATCH 4/5] Update the strength reduction code with a couple of fixes --- src/mapleall/maple_me/src/me_option.cpp | 6 +++--- src/mapleall/maple_me/src/ssa_pre.cpp | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index 4087f4ae04..8e1a74d305 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -765,11 +765,11 @@ const Descriptor kUsage[] = { { kStrengthReduction, kEnable, "", - "strengthReduction", + "strengthreduction", kBuildTypeExperimental, kArgCheckPolicyBool, - " --strengthReduction \tPerform flow sensitive alias analysis\n" - " --no-strengthReduction \tDisable flow sensitive alias analysis\n", + " --strengthreduction \tPerform flow sensitive alias analysis\n" + " --no-strengthreduction \tDisable flow sensitive alias analysis\n", "me", {} }, { kCheckCastOpt, diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index 1672d2452a..b7f3d011b2 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -936,7 +936,8 @@ void SSAPre::Rename2() { CHECK_FATAL(varVecX.size() == varVecY.size(), "invalid size of varVecY"); bool hasSameVersion = true; for (size_t ii = 0; ii < varVecX.size(); ii++) { - if (varVecX[ii] != varVecY[ii]) { + MeExpr *resolvedY = ResolveAllInjuringDefs(varVecY[ii]); + if (varVecX[ii] != resolvedY) { hasSameVersion = false; } } @@ -1010,7 +1011,11 @@ void SSAPre::SetVarPhis(MeExpr *meExpr) { ScalarMeExpr *scalar = static_cast(meExpr); if (workCand->isSRCand) { - scalar = ResolveAllInjuringDefs(scalar); + if (scalar->GetMeOp() == kMeOpVar) { + scalar = ResolveAllInjuringDefs(static_cast(scalar)); + } else { + scalar = ResolveAllInjuringDefs(scalar); + } } if (scalar->IsDefByPhi()) { MePhiNode *phiMeNode = scalar->GetMePhiDef(); -- Gitee From c059d4cfa3de56c0cb56abf4b41f0527553fd542 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Tue, 25 May 2021 00:02:46 -0700 Subject: [PATCH 5/5] more strength reduction bug fixes --- src/mapleall/maple_me/src/ssa_pre.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index b7f3d011b2..a5e3958dd4 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -145,8 +145,9 @@ void SSAPre::UpdateInsertedPhiOccOpnd() { } if (phiOcc->GetRegPhi()) { MePhiNode *phiReg = phiOcc->GetRegPhi(); - for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { - auto *regOpnd = static_cast(phiOpnd->GetDef()->GetSavedExpr()); + const MapleVector &phiopnds = phiOcc->GetPhiOpnds(); + for (uint32 i = 0; i < phiopnds.size(); i++) { + RegMeExpr *regOpnd = static_cast(phiopnds[i]->phiOpnd4Temp); if (regOpnd == nullptr) { // create a zero version CHECK_FATAL(curTemp != nullptr, "curTemp can't be null in SSAPre::UpdateInsertedPhiOccOpnd"); @@ -157,8 +158,9 @@ void SSAPre::UpdateInsertedPhiOccOpnd() { (void)phiOcc->GetBB()->GetMePhiList().insert(std::make_pair(phiReg->GetOpnd(0)->GetOstIdx(), phiReg)); if (workCand->NeedLocalRefVar() && phiOcc->GetVarPhi() != nullptr) { MePhiNode *phiVar = phiOcc->GetVarPhi(); - for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { - auto *regOpnd = static_cast(phiOpnd->GetDef()->GetSavedExpr()); + const MapleVector &phiopnds = phiOcc->GetPhiOpnds(); + for (uint32 i = 0; i < phiopnds.size(); i++) { + RegMeExpr *regOpnd = static_cast(phiopnds[i]->phiOpnd4Temp); VarMeExpr *localRefVarOpnd = nullptr; if (regOpnd == nullptr) { // create a zero version @@ -181,8 +183,9 @@ void SSAPre::UpdateInsertedPhiOccOpnd() { } } else { MePhiNode *phiVar = phiOcc->GetVarPhi(); - for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { - auto *varOpnd = static_cast(phiOpnd->GetDef()->GetSavedExpr()); + const MapleVector &phiopnds = phiOcc->GetPhiOpnds(); + for (uint32 i = 0; i < phiopnds.size(); i++) { + VarMeExpr *varOpnd = static_cast(phiopnds[i]->phiOpnd4Temp); if (varOpnd == nullptr) { CHECK_FATAL(curTemp != nullptr, "curTemp can't be null in SSAPre::UpdateInsertedPhiOccOpnd"); varOpnd = irMap->CreateVarMeExprVersion(static_cast(*curTemp)); @@ -271,8 +274,8 @@ void SSAPre::CodeMotion() { if (defOcc->GetOccType() == kOccReal) { phiOpnd->phiOpnd4Temp = static_cast(defOcc)->GetSavedExpr(); } else { - MePhiOcc *defphiocc = static_cast(defOcc); - MePhiNode *scalarPhi = (defphiocc->GetRegPhi() ? defphiocc->GetRegPhi() : defphiocc->GetVarPhi()); + MePhiOcc *defphiOcc = static_cast(defOcc); + MePhiNode *scalarPhi = (defphiOcc->GetRegPhi() ? defphiOcc->GetRegPhi() : defphiOcc->GetVarPhi()); phiOpnd->phiOpnd4Temp = scalarPhi->GetLHS(); } } -- Gitee