From 955f566e593013bb5e5f64dcc444809586897c45 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 15 Jul 2021 11:47:37 -0700 Subject: [PATCH] Implemented the lamport and gcd dependency tests --- src/mapleall/maple_me/include/lfo_dep_test.h | 71 +++-- src/mapleall/maple_me/include/orig_symbol.h | 10 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 283 +++++++++++++++++-- src/mapleall/maple_me/src/lfo_iv_canon.cpp | 11 +- src/mapleall/maple_me/src/lfo_pre_emit.cpp | 1 + src/mapleall/maple_me/src/me_cfg.cpp | 13 +- src/mapleall/maple_me/src/me_prop.cpp | 2 +- 7 files changed, 349 insertions(+), 42 deletions(-) diff --git a/src/mapleall/maple_me/include/lfo_dep_test.h b/src/mapleall/maple_me/include/lfo_dep_test.h index 0769abe900..f2ef199771 100644 --- a/src/mapleall/maple_me/include/lfo_dep_test.h +++ b/src/mapleall/maple_me/include/lfo_dep_test.h @@ -18,27 +18,45 @@ #include "lfo_function.h" #include "lfo_pre_emit.h" +#include "orig_symbol.h" #include "me_phase.h" +#include "me_ir.h" +#include "dominance.h" namespace maple { class LfoDepInfo; class SubscriptDesc{ public: - DreadNode *iv = nullptr; // the variable - int64 coeff = 1; // coefficient of the variable + MeExpr *subscriptX; + DreadNode *iv = nullptr; // the variable + int64 coeff = 1; // coefficient of the variable int64 additiveConst = 0; - bool tooMessy = false;; // too complicated to analyze + bool tooMessy = false;; // too complicated to analyze + bool loopInvariant = false; // loop invariant w.r.t. closest nesting loop - SubscriptDesc() = default; + public: + SubscriptDesc(MeExpr *x) : subscriptX(x) {} }; class ArrayAccessDesc { public: ArrayNode *theArray; + OriginalSt *arrayOst = nullptr; MapleVector subscriptVec; // describe the subscript of each array dimension - ArrayAccessDesc(MapleAllocator *alloc, ArrayNode *arr) : theArray(arr), subscriptVec(alloc->Adapter()) {} + public: + ArrayAccessDesc(MapleAllocator *alloc, ArrayNode *arr, OriginalSt *arryOst) : theArray(arr), arrayOst(arryOst), subscriptVec(alloc->Adapter()) {} +}; + +class DepTestPair { + public: + std::pair depTestPair; // based on indices in lhsArrays and rhsArrays + bool dependent = false; + bool unknownDist = false; // if dependent + int64 depDist = 0; // if unknownDist is false + public: + DepTestPair(size_t i, size_t j) : depTestPair(i, j) {} }; class DoloopInfo { @@ -50,42 +68,57 @@ class DoloopInfo { MapleVector children; // for the nested doloops in program order MapleVector lhsArrays; // each element represents an array assign MapleVector rhsArrays; // each element represents an array read + BB *doloopBB = nullptr; // the start BB for the doloop body bool hasPtrAccess = false; // give up dep testing if true bool hasCall = false; // give up dep testing if true + bool hasScalarAssign = false; // give up dep testing if true + bool hasMayDef = false; // give up dep testing if true + MapleVector outputDepTestList; // output dependence only + MapleVector flowDepTestList; // include both true and anti dependences - DoloopInfo(MapleAllocator *allc, LfoDepInfo *depinfo, DoloopNode *doloop, DoloopInfo *prnt) - : alloc(allc), - depInfo(depinfo), - doloop(doloop), - parent(prnt), - children(alloc->Adapter()), - lhsArrays(alloc->Adapter()), - rhsArrays(alloc->Adapter()) {} + public: + DoloopInfo(MapleAllocator *allc, LfoDepInfo *depinfo, DoloopNode *doloop, DoloopInfo *prnt) : + alloc(allc), + depInfo(depinfo), + doloop(doloop), + parent(prnt), + children(alloc->Adapter()), + lhsArrays(alloc->Adapter()), + rhsArrays(alloc->Adapter()), + outputDepTestList(alloc->Adapter()), + flowDepTestList(alloc->Adapter()) {} ~DoloopInfo() = default; + bool IsLoopInvariant(MeExpr *x); SubscriptDesc *BuildOneSubscriptDesc(BaseNode *subsX); - void BuildOneArrayAccessDesc(ArrayNode *arr, bool isRHS); + ArrayAccessDesc *BuildOneArrayAccessDesc(ArrayNode *arr, bool isRHS); void CreateRHSArrayAccessDesc(BaseNode *x); void CreateArrayAccessDesc(BlockNode *block); + void CreateDepTestLists(); + void TestDependences(MapleVector *depTestList, bool bothLHS); + bool Parallelizable(); }; class LfoDepInfo : public AnalysisResult { public: MapleAllocator alloc; LfoFunction *lfoFunc; + Dominance *dom; LfoPreEmitter *preEmit; MapleVector outermostDoloopInfoVec; // outermost doloops' DoloopInfo in program order MapleMap doloopInfoMap; - LfoDepInfo(MemPool *mempool, LfoFunction *f, LfoPreEmitter *preemit) - : AnalysisResult(mempool), - alloc(mempool), - lfoFunc(f), + public: + LfoDepInfo(MemPool *mempool, LfoFunction *f, Dominance *dm, LfoPreEmitter *preemit) + : AnalysisResult(mempool), + alloc(mempool), + lfoFunc(f), + dom(dm), preEmit(preemit), outermostDoloopInfoVec(alloc.Adapter()), doloopInfoMap(alloc.Adapter()) {} ~LfoDepInfo() = default; void CreateDoloopInfo(BlockNode *block, DoloopInfo *parent); - void CreateArrayAccessDesc(MapleMap *doloopInfoVec); + void PerformDepTest(); std::string PhaseName() const { return "deptest"; } }; diff --git a/src/mapleall/maple_me/include/orig_symbol.h b/src/mapleall/maple_me/include/orig_symbol.h index d1b21ee348..2ae92ec298 100644 --- a/src/mapleall/maple_me/include/orig_symbol.h +++ b/src/mapleall/maple_me/include/orig_symbol.h @@ -213,7 +213,15 @@ class OriginalSt { return false; } MIRType *mirtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - return IsPrimitiveInteger(mirtype->GetPrimType()) && (mirtype->GetKind() != kTypeBitField); + if (IsPrimitiveInteger(mirtype->GetPrimType()) && (mirtype->GetKind() != kTypeBitField)) { + // additional check using MIRSymbol's tyIdx + if (IsSymbolOst()) { + return IsPrimitiveInteger(GetMIRSymbol()->GetType()->GetPrimType()); + } + return true; + } else { + return false; + } } MIRType *GetType() const { diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index 9eecf4d473..95e5680bab 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -29,6 +29,9 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { } else { outermostDoloopInfoVec.push_back(doloopInfo); } + LfoPart *lfopart = preEmit->GetLfoStmtPart(doloop->GetStmtID()); + MeStmt *meStmt = lfopart->GetMeStmt(); + doloopInfo->doloopBB = meStmt->GetBB(); CreateDoloopInfo(doloop->GetDoBody(), doloopInfo); break; } @@ -58,8 +61,62 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { } } +// check if x is loop-invariant w.r.t. the doloop +bool DoloopInfo::IsLoopInvariant(MeExpr *x) { + if (x == nullptr) { + return true; + } + switch (x->GetMeOp()) { + case kMeOpAddrof: + case kMeOpAddroffunc: + case kMeOpConst: + case kMeOpConststr: + case kMeOpConststr16: + case kMeOpSizeoftype: + case kMeOpFieldsDist: return true; + case kMeOpVar: + case kMeOpReg: { + ScalarMeExpr *scalar = static_cast(x); + BB *defBB = scalar->DefByBB(); + return defBB == nullptr || (defBB != doloopBB && depInfo->dom->Dominate(*defBB, *doloopBB)); + } + case kMeOpIvar: { + IvarMeExpr *ivar = static_cast(x); + if (!IsLoopInvariant(ivar->GetBase())) { + return false; + } + BB *defBB = ivar->GetMu()->DefByBB(); + return defBB == nullptr || (defBB != doloopBB && depInfo->dom->Dominate(*defBB, *doloopBB)); + } + case kMeOpOp: { + OpMeExpr *opexp = static_cast(x); + return IsLoopInvariant(opexp->GetOpnd(0)) && + IsLoopInvariant(opexp->GetOpnd(1)) && + IsLoopInvariant(opexp->GetOpnd(2)); + } + case kMeOpNary: { + NaryMeExpr *opexp = static_cast(x); + for (uint32 i = 0; i < opexp->GetNumOpnds(); i++) { + if (!IsLoopInvariant(opexp->GetOpnd(i))) { + return false; + } + } + return true; + } + default: + break; + } + return false; +} + SubscriptDesc *DoloopInfo::BuildOneSubscriptDesc(BaseNode *subsX) { - SubscriptDesc *subsDesc = alloc->GetMemPool()->New(); + LfoPart *lfopart = depInfo->preEmit->GetLfoExprPart(subsX); + MeExpr *meExpr = lfopart->GetMeExpr(); + SubscriptDesc *subsDesc = alloc->GetMemPool()->New(meExpr); + if (IsLoopInvariant(meExpr)) { + subsDesc->loopInvariant = true; + return subsDesc; + } Opcode op = subsX->GetOpCode(); BaseNode *mainTerm = nullptr; if (op != OP_add && op != OP_sub) { @@ -106,7 +163,11 @@ SubscriptDesc *DoloopInfo::BuildOneSubscriptDesc(BaseNode *subsX) { return subsDesc; } subsDesc->coeff = static_cast(mirconst)->GetValue(); - } + if (subsDesc->coeff < 0) { + subsDesc->tooMessy = true; + return subsDesc; + } + } // process varNode if (varNode->GetOpCode() == OP_dread) { DreadNode *dnode = static_cast(varNode); @@ -119,7 +180,7 @@ SubscriptDesc *DoloopInfo::BuildOneSubscriptDesc(BaseNode *subsX) { return subsDesc; } -void DoloopInfo::BuildOneArrayAccessDesc(ArrayNode *arr, bool isRHS) { +ArrayAccessDesc *DoloopInfo::BuildOneArrayAccessDesc(ArrayNode *arr, bool isRHS) { #if 0 MIRType *atype = arr->GetArrayType(GlobalTables::GetTypeTable()); ASSERT(atype->GetKind() == kTypeArray, "type was wrong"); @@ -129,7 +190,24 @@ void DoloopInfo::BuildOneArrayAccessDesc(ArrayNode *arr, bool isRHS) { #else size_t dim = arr->NumOpnds() - 1; #endif - ArrayAccessDesc *arrDesc = alloc->GetMemPool()->New(alloc, arr); + // determine arrayOst + LfoPart *lfopart = depInfo->preEmit->GetLfoExprPart(arr); + OpMeExpr *arrayMeExpr = static_cast(lfopart->GetMeExpr()); + OriginalSt *arryOst = nullptr; + if (arrayMeExpr->GetOpnd(0)->GetMeOp() == kMeOpAddrof) { + AddrofMeExpr *addrof = static_cast(arrayMeExpr->GetOpnd(0)); + arryOst = depInfo->lfoFunc->meFunc->GetMeSSATab()->GetOriginalStFromID(addrof->GetOstIdx()); + + } else { + ScalarMeExpr *scalar = dynamic_cast(arrayMeExpr->GetOpnd(0)); + if (scalar) { + arryOst = scalar->GetOst(); + } else { + hasPtrAccess = true; + return nullptr; + } + } + ArrayAccessDesc *arrDesc = alloc->GetMemPool()->New(alloc, arr, arryOst); if (isRHS) { rhsArrays.push_back(arrDesc); } else { @@ -139,6 +217,7 @@ void DoloopInfo::BuildOneArrayAccessDesc(ArrayNode *arr, bool isRHS) { SubscriptDesc *subs = BuildOneSubscriptDesc(arr->GetIndex(i)); arrDesc->subscriptVec.push_back(subs); } + return arrDesc; } void DoloopInfo::CreateRHSArrayAccessDesc(BaseNode *x) { @@ -180,13 +259,35 @@ void DoloopInfo::CreateArrayAccessDesc(BlockNode *block) { case OP_iassign: { IassignNode *iass = static_cast(stmt); if (iass->addrExpr->GetOpCode() == OP_array) { - BuildOneArrayAccessDesc(static_cast(iass->addrExpr), false /* isRHS */); + ArrayAccessDesc *adesc = BuildOneArrayAccessDesc(static_cast(iass->addrExpr), false/*isRHS*/); + if (adesc == nullptr) { + hasMayDef = true; + } else { + // check if the chi list has only the same array + LfoPart *lfopart = depInfo->preEmit->GetLfoStmtPart(iass->GetStmtID()); + IassignMeStmt *iassMeStmt = static_cast(lfopart->GetMeStmt()); + MapleMap *chilist = iassMeStmt->GetChiList(); + MapleMap::iterator chiit = chilist->begin(); + for (; chiit != chilist->end(); chiit++) { + OriginalSt *chiOst = depInfo->lfoFunc->meFunc->GetMeSSATab()->GetOriginalStFromID(chiit->first); + if (!chiOst->IsSameSymOrPreg(adesc->arrayOst)) { + hasMayDef = true; + break; + } + } + } } else { hasPtrAccess = true; } CreateRHSArrayAccessDesc(iass->rhs); break; } + case OP_dassign: + case OP_regassign: { + hasScalarAssign = true; + CreateRHSArrayAccessDesc(stmt->Opnd(0)); + break; + } case OP_call: case OP_callassigned: case OP_icall: @@ -206,8 +307,105 @@ void DoloopInfo::CreateArrayAccessDesc(BlockNode *block) { } } -void LfoDepInfo::CreateArrayAccessDesc(MapleMap *doloopInfoMap) { - for (auto mapit = doloopInfoMap->begin(); mapit != doloopInfoMap->end(); mapit++) { +void DoloopInfo::CreateDepTestLists() { + size_t i, j; + for (i = 0; i < lhsArrays.size(); i++) { + for (j = i+1; j < lhsArrays.size(); j++) { + if (lhsArrays[i]->arrayOst->IsSameSymOrPreg(lhsArrays[j]->arrayOst)) { + outputDepTestList.push_back(DepTestPair(i, j)); + } + } + } + for (i = 0; i < lhsArrays.size(); i++) { + for (j = 0; j < rhsArrays.size(); j++) { + if (lhsArrays[i]->arrayOst->IsSameSymOrPreg(rhsArrays[j]->arrayOst)) { + flowDepTestList.push_back(DepTestPair(i, j)); + } + } + } +} + +static int64 Gcd(int64 a, int64 b) { + CHECK_FATAL(a > 0 && b >= 0, "Gcd: NYI"); + if (b == 0) + return a; + return Gcd(b, a % b); +} + +void DoloopInfo::TestDependences(MapleVector *depTestList, bool bothLHS) { + size_t i, j; + for (i = 0; i < depTestList->size(); i++) { + DepTestPair *testPair = &(*depTestList)[i]; + ArrayAccessDesc *arrDesc1 = lhsArrays[testPair->depTestPair.first]; + ArrayAccessDesc *arrDesc2 = nullptr; + if (bothLHS) { + arrDesc2 = lhsArrays[testPair->depTestPair.second]; + } else { + arrDesc2 = rhsArrays[testPair->depTestPair.second]; + } + CHECK_FATAL(arrDesc1->subscriptVec.size() == arrDesc2->subscriptVec.size(), + "TestDependences: inconsistent array dimension"); + for (j = 0; j < arrDesc1->subscriptVec.size(); j++) { + SubscriptDesc *subs1 = arrDesc1->subscriptVec[j]; + SubscriptDesc *subs2 = arrDesc2->subscriptVec[j]; + if (subs1->tooMessy || subs2->tooMessy) { + testPair->dependent = true; + testPair->unknownDist = true; + break; + } + if (subs1->loopInvariant || subs2->loopInvariant) { + if (subs1->subscriptX == subs2->subscriptX) { + continue; + } else { + testPair->dependent = true; + testPair->unknownDist = true; + break; + } + } + if (subs1->coeff == subs2->coeff) { // lamport test + if (((subs1->additiveConst - subs2->additiveConst) % subs1->coeff) != 0) { + continue; + } + testPair->dependent = true; + int64 dist = (subs1->additiveConst - subs2->additiveConst) / subs1->coeff; + if (dist != 0) { + testPair->depDist = dist; + } + continue; + } + // gcd test + if ((subs1->additiveConst - subs2->additiveConst) % Gcd(subs1->coeff, subs2->coeff) == 0) { + testPair->dependent = true; + testPair->unknownDist = true; + break; + } + } + } +} + +bool DoloopInfo::Parallelizable() { + if (hasPtrAccess || hasCall || hasScalarAssign || hasMayDef) { + return true; + } + for (size_t i = 0; i < outputDepTestList.size(); i++) { + DepTestPair *testPair = &outputDepTestList[i]; + if (testPair->dependent && (testPair->unknownDist || testPair->depDist != 0)) { + return false; + } + } + for (size_t i = 0; i < flowDepTestList.size(); i++) { + DepTestPair *testPair = &flowDepTestList[i]; + if (testPair->dependent && (testPair->unknownDist || testPair->depDist != 0)) { + return false; + } + } + return true; +} + +void LfoDepInfo::PerformDepTest() { + size_t i; + MapleMap::iterator mapit = doloopInfoMap.begin(); + for (; mapit != doloopInfoMap.end(); mapit++) { DoloopInfo *doloopInfo = mapit->second; if (!doloopInfo->children.empty()) { continue; // only handling innermost doloops @@ -221,14 +419,24 @@ void LfoDepInfo::CreateArrayAccessDesc(MapleMap *dol if (doloopInfo->hasCall) { LogInfo::MapleLogger() << " hasCall"; } + if (doloopInfo->hasScalarAssign) { + LogInfo::MapleLogger() << " hasScalarAssign"; + } + if (doloopInfo->hasMayDef) { + LogInfo::MapleLogger() << " hasMayDef"; + } LogInfo::MapleLogger() << std::endl; doloopInfo->doloop->Dump(0); LogInfo::MapleLogger() << "LHS arrays:\n"; - for (ArrayAccessDesc *arrAcc : doloopInfo->lhsArrays) { - arrAcc->theArray->Dump(0); + for (i = 0; i < doloopInfo->lhsArrays.size(); i++) { + ArrayAccessDesc *arrAcc = doloopInfo->lhsArrays[i]; + LogInfo::MapleLogger() << "(L" << i << ") "; + arrAcc->arrayOst->Dump(); LogInfo::MapleLogger() << " subscripts:"; for (SubscriptDesc *subs : arrAcc->subscriptVec) { - if (subs->tooMessy) { + if (subs->loopInvariant) { + LogInfo::MapleLogger() << " [loopinvariant]"; + } else if (subs->tooMessy) { LogInfo::MapleLogger() << " [messy]"; } else { LogInfo::MapleLogger() << " [" << subs->coeff << "*"; @@ -240,12 +448,16 @@ void LfoDepInfo::CreateArrayAccessDesc(MapleMap *dol } LogInfo::MapleLogger() << std::endl; } - LogInfo::MapleLogger() << "RHS arrays: "; - for (ArrayAccessDesc *arrAcc : doloopInfo->rhsArrays) { - arrAcc->theArray->Dump(0); + LogInfo::MapleLogger() << "RHS arrays:\n"; + for (i = 0; i < doloopInfo->rhsArrays.size(); i++) { + ArrayAccessDesc *arrAcc = doloopInfo->rhsArrays[i]; + LogInfo::MapleLogger() << "(R" << i << ") "; + arrAcc->arrayOst->Dump(); LogInfo::MapleLogger() << " subscripts:"; for (SubscriptDesc *subs : arrAcc->subscriptVec) { - if (subs->tooMessy) { + if (subs->loopInvariant) { + LogInfo::MapleLogger() << " [loopinvariant]"; + } else if (subs->tooMessy) { LogInfo::MapleLogger() << " [messy]"; } else { LogInfo::MapleLogger() << " [" << subs->coeff << "*"; @@ -259,19 +471,58 @@ void LfoDepInfo::CreateArrayAccessDesc(MapleMap *dol } LogInfo::MapleLogger() << std::endl; } + doloopInfo->CreateDepTestLists(); + doloopInfo->TestDependences(&doloopInfo->outputDepTestList, true); + doloopInfo->TestDependences(&doloopInfo->flowDepTestList, false); + if (DEBUGFUNC(lfoFunc->meFunc)) { + for (DepTestPair item : doloopInfo->outputDepTestList) { + LogInfo::MapleLogger() << "Dep between L" << item.depTestPair.first << " and L" << item.depTestPair.second; + if (!item.dependent) { + LogInfo::MapleLogger() << " independent"; + } else { + LogInfo::MapleLogger() << " dependent"; + if (item.unknownDist) { + LogInfo::MapleLogger() << " unknownDist"; + } else { + LogInfo::MapleLogger() << " distance: " << item.depDist; + } + } + LogInfo::MapleLogger() << std::endl; + } + for (DepTestPair item : doloopInfo->flowDepTestList) { + LogInfo::MapleLogger() << "Dep between L" << item.depTestPair.first << " and R" << item.depTestPair.second; + if (!item.dependent) { + LogInfo::MapleLogger() << " independent"; + } else { + LogInfo::MapleLogger() << " dependent"; + if (item.unknownDist) { + LogInfo::MapleLogger() << " unknownDist"; + } else { + LogInfo::MapleLogger() << " distance: " << item.depDist; + } + } + LogInfo::MapleLogger() << std::endl; + } + if (doloopInfo->Parallelizable()) { + LogInfo::MapleLogger() << "LOOP CAN BE VECTORIZED\n"; + } + } } } AnalysisResult *DoLfoDepTest::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + ASSERT(dom != nullptr, "dominance phase has problem"); LfoPreEmitter *preEmit = static_cast(m->GetAnalysisResult(MeFuncPhase_LFOPREEMIT, func)); + ASSERT(preEmit != nullptr, "lfo preemit phase has problem"); LfoFunction *lfoFunc = func->GetLfoFunc(); MemPool *depTestMp = NewMemPool(); - LfoDepInfo *depInfo = depTestMp->New(depTestMp, lfoFunc, preEmit); + LfoDepInfo *depInfo = depTestMp->New(depTestMp, lfoFunc, dom, preEmit); if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============== LFO_DEP_TEST =============" << '\n'; } depInfo->CreateDoloopInfo(func->GetMirFunc()->GetBody(), nullptr); - depInfo->CreateArrayAccessDesc(&depInfo->doloopInfoMap); + depInfo->PerformDepTest(); if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "________________" << std::endl; lfoFunc->meFunc->GetMirFunc()->Dump(); diff --git a/src/mapleall/maple_me/src/lfo_iv_canon.cpp b/src/mapleall/maple_me/src/lfo_iv_canon.cpp index 5b5ba3ecc9..2584cb6a89 100644 --- a/src/mapleall/maple_me/src/lfo_iv_canon.cpp +++ b/src/mapleall/maple_me/src/lfo_iv_canon.cpp @@ -177,18 +177,21 @@ bool IVCanon::IsLoopInvariant(MeExpr *x) { case kMeOpReg: { ScalarMeExpr *scalar = static_cast(x); BB *defBB = scalar->DefByBB(); - return defBB == nullptr || dominance->Dominate(*defBB, *aloop->head); + return defBB == nullptr || (defBB != aloop->head && dominance->Dominate(*defBB, *aloop->head)); } case kMeOpIvar: { IvarMeExpr *ivar = static_cast(x); + if (!IsLoopInvariant(ivar->GetBase())) { + return false; + } BB *defBB = ivar->GetMu()->DefByBB(); - return defBB == nullptr || dominance->Dominate(*defBB, *aloop->head); + return defBB == nullptr || (defBB != aloop->head && dominance->Dominate(*defBB, *aloop->head)); } case kMeOpOp: { OpMeExpr *opexp = static_cast(x); return IsLoopInvariant(opexp->GetOpnd(0)) && - IsLoopInvariant(opexp->GetOpnd(1)) && - IsLoopInvariant(opexp->GetOpnd(2)); + IsLoopInvariant(opexp->GetOpnd(1)) && + IsLoopInvariant(opexp->GetOpnd(2)); } case kMeOpNary: { NaryMeExpr *opexp = static_cast(x); diff --git a/src/mapleall/maple_me/src/lfo_pre_emit.cpp b/src/mapleall/maple_me/src/lfo_pre_emit.cpp index 9edab60338..a7899e2fb6 100644 --- a/src/mapleall/maple_me/src/lfo_pre_emit.cpp +++ b/src/mapleall/maple_me/src/lfo_pre_emit.cpp @@ -574,6 +574,7 @@ DoloopNode *LfoPreEmitter::EmitLfoDoloop(BB *mewhilebb, BlockNode *curblk, LfoWh "EmitLfoDoLoop: there are other statements at while header bb"); DoloopNode *Doloopnode = codeMP->New(); LfoPart *lfopart = lfoMP->New(curblk); + lfopart->mestmt = lastmestmt; lfoStmtParts[Doloopnode->GetStmtID()] = lfopart; Doloopnode->SetDoVarStIdx(whileInfo->ivOst->GetMIRSymbol()->GetStIdx()); CondGotoMeStmt *condGotostmt = static_cast(lastmestmt); diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 5082622e05..ae602ae65e 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1287,10 +1287,21 @@ void MeCFG::CreateBasicBlocks() { break; } case OP_dassign: { + DassignNode *dass = static_cast(stmt); + if (!func.IsLfo() && func.GetLfoFunc() != nullptr) { + // delete identity assignments inserted by LFO + if (dass->GetRHS()->GetOpCode() == OP_dread) { + DreadNode *dread = static_cast(dass->GetRHS()); + if (dass->GetStIdx() == dread->GetStIdx() && dass->GetFieldID() == dread->GetFieldID()) { + func.CurFunction()->GetBody()->RemoveStmt(stmt); + break; + } + } + } if (curBB->IsEmpty()) { curBB->SetFirst(stmt); } - if (isJavaModule && static_cast(stmt)->GetRHS()->MayThrowException()) { + if (isJavaModule && dass->GetRHS()->MayThrowException()) { stmt->SetOpCode(OP_maydassign); if (tryStmt != nullptr) { // breaks new BB only inside try blocks diff --git a/src/mapleall/maple_me/src/me_prop.cpp b/src/mapleall/maple_me/src/me_prop.cpp index 8981b39f33..dd223ce146 100644 --- a/src/mapleall/maple_me/src/me_prop.cpp +++ b/src/mapleall/maple_me/src/me_prop.cpp @@ -51,7 +51,7 @@ AnalysisResult *MeDoMeProp::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResu } MeProp meProp(*hMap, *dom, *NewMemPool(), Prop::PropConfig { MeOption::propBase, propIloadRef, MeOption::propGlobalRef, MeOption::propFinaliLoadRef, MeOption::propIloadRefNonParm, MeOption::propAtPhi, - MeOption::propWithInverse || MeOption::optLevel >= 3 }); + MeOption::propWithInverse || func->IsLfo() }); meProp.TraversalBB(*func->GetCfg()->GetCommonEntryBB()); if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============== After Copy Propagation =============" << '\n'; -- Gitee