diff --git a/src/mapleall/maple_me/include/me_hdse.h b/src/mapleall/maple_me/include/me_hdse.h index a8434b1b636dba988b5d4d5156144721301f4206..7b9dab50f7af3987437a98ee6e2f8276a987dd4a 100644 --- a/src/mapleall/maple_me/include/me_hdse.h +++ b/src/mapleall/maple_me/include/me_hdse.h @@ -31,6 +31,9 @@ class MeHDSE : public HDSE { virtual ~MeHDSE() = default; void BackwardSubstitution(); + std::string PhaseName() const { + return "hdse"; + } }; class MeDoHDSE : public MeFuncPhase { diff --git a/src/mapleall/maple_me/src/me_ir.cpp b/src/mapleall/maple_me/src/me_ir.cpp index c257bf53175620c3f0a4bd1ada81aa984a7e9ea4..87d89bd04ee6f5d499cc8679c29122f170b5fa22 100644 --- a/src/mapleall/maple_me/src/me_ir.cpp +++ b/src/mapleall/maple_me/src/me_ir.cpp @@ -568,14 +568,26 @@ MeExpr *OpMeExpr::GetIdenticalExpr(MeExpr &expr, bool isConstructor) const { } bool OpMeExpr::StrengthReducible() { - if (op != OP_mul || !IsPrimitiveInteger(primType)) { + if (!IsPrimitiveInteger(primType)) { return false; } - return GetOpnd(1)->GetOp() == OP_constval; + switch (op) { + case OP_cvt: { + return IsPrimitiveInteger(opndType) && GetPrimTypeSize(primType) >= GetPrimTypeSize(opndType); + } + case OP_mul: + return GetOpnd(1)->GetOp() == OP_constval; + case OP_add: + return true; + default: return false; + } } int64 OpMeExpr::SRMultiplier() { ASSERT(StrengthReducible(), "OpMeExpr::SRMultiplier: operation is not strength reducible"); + if (op != OP_mul) { + return 1; + } MIRConst *constVal = static_cast(GetOpnd(1))->GetConstVal(); ASSERT(constVal->GetKind() == kConstInt, "OpMeExpr::SRMultiplier: multiplier not an integer constant"); return static_cast(constVal)->GetValueUnderType(); diff --git a/src/mapleall/maple_me/src/me_ssa_epre.cpp b/src/mapleall/maple_me/src/me_ssa_epre.cpp index 737ea7ee7606e12c6fcae996bb39523123511d38..a7badd23c159a3c860c377b5531f62a00d55914b 100644 --- a/src/mapleall/maple_me/src/me_ssa_epre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_epre.cpp @@ -16,6 +16,8 @@ #include "me_dominance.h" #include "me_ssa_update.h" #include "me_placement_rc.h" +#include "me_loop_analysis.h" +#include "me_hdse.h" namespace { const std::set propWhiteList { @@ -74,6 +76,9 @@ AnalysisResult *MeDoSSAEPre::Run(MeFunction *func, MeFuncResultMgr *m, ModuleRes kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->GetMIRModule())); CHECK_FATAL(kh != nullptr, "KlassHierarchy phase has problem"); } + auto *identLoops = static_cast(m->GetAnalysisResult(MeFuncPhase_MELOOP, func)); + CHECK_NULL_FATAL(identLoops); + bool eprePULimitSpecified = MeOption::eprePULimit != UINT32_MAX; uint32 epreLimitUsed = (eprePULimitSpecified && puCount != MeOption::eprePULimit) ? UINT32_MAX : MeOption::epreLimit; @@ -109,6 +114,14 @@ AnalysisResult *MeDoSSAEPre::Run(MeFunction *func, MeFuncResultMgr *m, ModuleRes placeRC.preKind = MeSSUPre::kSecondDecrefPre; placeRC.ApplySSUPre(); } + if (MeOption::strengthReduction) { // for deleting redundant injury repairs + MeHDSE hdse(*func, *dom, *func->GetIRMap(), DEBUGFUNC(func)); + if (!MeOption::quiet) { + LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << hdse.PhaseName() << " ] ==\n"; + } + hdse.hdseKeepRef = MeOption::dseKeepRef; + hdse.DoHDSE(); + } if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============== EPRE =============" << "\n"; func->Dump(false); diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index db02549cf7d67e69c0c3648c4020bfdae78b384e..41036e72732731a34138ed8b21d08bfb347b4e03 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1322,7 +1322,7 @@ 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()) { + } else if (strengthReduction && meExpr.StrengthReducible() && meStmt.GetBB()->GetAttributes(kBBAttrIsInLoop)) { wkCand->isSRCand = true; } workList.push_back(wkCand);