From cd002953045f9ff9e7582fbac1167031e7dc0db3 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Tue, 14 Dec 2021 15:04:11 -0800 Subject: [PATCH] make lfounroll handle loops with non-constant trip count --- src/mapleall/maple_me/src/lfo_unroll.cpp | 74 ++++++++++++++----- src/mapleall/maple_me/src/me_autovec.cpp | 1 - .../maple_me/src/me_phase_manager.cpp | 2 +- 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/src/mapleall/maple_me/src/lfo_unroll.cpp b/src/mapleall/maple_me/src/lfo_unroll.cpp index 89bc5c97bf..971b5ec1c9 100644 --- a/src/mapleall/maple_me/src/lfo_unroll.cpp +++ b/src/mapleall/maple_me/src/lfo_unroll.cpp @@ -85,22 +85,54 @@ BlockNode *LfoUnrollOneLoop::DoFullUnroll(size_t tripCount) { BlockNode *LfoUnrollOneLoop::DoUnroll(size_t times, size_t tripCount) { BlockNode *unrolledBlk = nullptr; // form the remainder loop before the unrolled loop - size_t remainderTripCount = tripCount % times; - if (remainderTripCount == 0) { - unrolledBlk = codeMP->New(); - } else if (remainderTripCount == 1) { - unrolledBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); - ReplaceIV(unrolledBlk, doloop->GetStartExpr()); + size_t remainderTripCount = tripCount % times; // used when constant tripcount + PregIdx regIdx = 0; // used when unknown tripcount + if (tripCount != 0) { + if (remainderTripCount == 0) { + unrolledBlk = codeMP->New(); + } else if (remainderTripCount == 1) { + unrolledBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); + ReplaceIV(unrolledBlk, doloop->GetStartExpr()); + } else { + DoloopNode *remDoloop = doloop->CloneTree(*preEmit->GetCodeMPAlloc()); + // generate remDoloop's termination + BaseNode *terminationRHS = codeMP->New(OP_add, ivPrimType, + doloop->GetStartExpr()->CloneTree(*preEmit->GetCodeMPAlloc()), + mirBuilder->CreateIntConst(remainderTripCount, ivPrimType)); + remDoloop->SetContExpr(codeMP->New(OP_lt, PTY_i32, ivPrimType, CloneIVNode(), terminationRHS)); + unrolledBlk = codeMP->New(); + unrolledBlk->AddStatement(remDoloop); + } } else { + // generate code to calculate the remainder loop trip count which is + // (endexpr - startexpr) % times (increment assumed to be 1) + BaseNode *startExpr = doloop->GetStartExpr(); + BaseNode *condExpr = doloop->GetCondExpr(); + BaseNode *endExpr = condExpr->Opnd(1); + BaseNode *tripsExpr = codeMP->New(OP_sub, ivPrimType, + endExpr->CloneTree(*preEmit->GetCodeMPAlloc()), + startExpr->CloneTree(*preEmit->GetCodeMPAlloc())); + if (condExpr->GetOpCode() == OP_ge || condExpr->GetOpCode() == OP_le) { + tripsExpr = codeMP->New(OP_add, ivPrimType, tripsExpr, + mirBuilder->CreateIntConst(1, ivPrimType)); + } + tripsExpr = codeMP->New(OP_rem, ivPrimType, tripsExpr, + mirBuilder->CreateIntConst(times, ivPrimType)); + BaseNode *remLoopEndExpr = codeMP->New(OP_add, ivPrimType, + startExpr->CloneTree(*preEmit->GetCodeMPAlloc()), tripsExpr); + // store in a preg + regIdx = lfoFunc->meFunc->GetMirFunc()->GetPregTab()->CreatePreg(ivPrimType); + RegassignNode *rass = mirBuilder->CreateStmtRegassign(ivPrimType, regIdx, remLoopEndExpr); + unrolledBlk = codeMP->New(); + unrolledBlk->AddStatement(rass); + DoloopNode *remDoloop = doloop->CloneTree(*preEmit->GetCodeMPAlloc()); // generate remDoloop's termination - BaseNode *terminationRHS = codeMP->New(OP_add, ivPrimType, - doloop->GetStartExpr()->CloneTree(*preEmit->GetCodeMPAlloc()), - mirBuilder->CreateIntConst(remainderTripCount, ivPrimType)); + BaseNode *terminationRHS = mirBuilder->CreateExprRegread(ivPrimType, regIdx); remDoloop->SetContExpr(codeMP->New(OP_lt, PTY_i32, ivPrimType, CloneIVNode(), terminationRHS)); - unrolledBlk = codeMP->New(); unrolledBlk->AddStatement(remDoloop); } + // form the unrolled loop DoloopNode *unrolledDoloop = doloop->CloneTree(*preEmit->GetCodeMPAlloc()); uint32 i = 1; @@ -113,9 +145,15 @@ BlockNode *LfoUnrollOneLoop::DoUnroll(size_t times, size_t tripCount) { unrolledDoloop->GetDoBody()->InsertBlockAfter(*nextIterBlk, unrolledDoloop->GetDoBody()->GetLast()); i++; } while (i != times); - if (remainderTripCount != 0) { // update startExpr - BaseNode *newStartExpr = codeMP->New(OP_add, ivPrimType, unrolledDoloop->GetStartExpr(), - mirBuilder->CreateIntConst(remainderTripCount, ivPrimType)); + // update startExpr + if (tripCount != 0) { + if (remainderTripCount != 0) { + BaseNode *newStartExpr = codeMP->New(OP_add, ivPrimType, unrolledDoloop->GetStartExpr(), + mirBuilder->CreateIntConst(remainderTripCount, ivPrimType)); + unrolledDoloop->SetStartExpr(newStartExpr); + } + } else { + BaseNode *newStartExpr = mirBuilder->CreateExprRegread(ivPrimType, regIdx); unrolledDoloop->SetStartExpr(newStartExpr); } // update incrExpr @@ -199,16 +237,13 @@ void LfoUnrollOneLoop::Process() { tripCount++; } } - if (tripCount == 0) { - return; // NYI handling of variable trip count - } size_t unrollTimes = 1; size_t unrolledStmtCount = stmtCount; while (unrolledStmtCount < unrolledSizeLimit && unrollTimes < unrollMax) { unrollTimes++; unrolledStmtCount += stmtCount; } - bool fullUnroll = tripCount < (unrollTimes * 2); + bool fullUnroll = tripCount != 0 && tripCount < (unrollTimes * 2); BlockNode *unrolledBlk = nullptr; if (fullUnroll) { unrolledBlk = DoFullUnroll(tripCount); @@ -236,6 +271,7 @@ bool MELfoUnroll::PhaseRun(MeFunction &f) { LfoDepInfo *lfoDepInfo = GET_ANALYSIS(MELfoDepTest, f); ASSERT(lfoDepInfo != nullptr, "lfo dep test phase has problem"); LfoFunction *lfoFunc = f.GetLfoFunc(); + uint32 savedCountOfLoopsUnrolled = LfoUnrollOneLoop::countOfLoopsUnrolled; MapleMap::iterator mapit = lfoDepInfo->doloopInfoMap.begin(); for (; mapit != lfoDepInfo->doloopInfoMap.end(); mapit++) { @@ -245,6 +281,10 @@ bool MELfoUnroll::PhaseRun(MeFunction &f) { LfoUnrollOneLoop unroll(lfoFunc, preEmit, mapit->second); unroll.Process(); } + if (DEBUGFUNC_NEWPM(f) && savedCountOfLoopsUnrolled != LfoUnrollOneLoop::countOfLoopsUnrolled) { + LogInfo::MapleLogger() << "\n**** After lfo loop unrolling ****\n"; + f.GetMirFunc()->Dump(); + } return false; } diff --git a/src/mapleall/maple_me/src/me_autovec.cpp b/src/mapleall/maple_me/src/me_autovec.cpp index 741fceb950..ea7f6cf40e 100644 --- a/src/mapleall/maple_me/src/me_autovec.cpp +++ b/src/mapleall/maple_me/src/me_autovec.cpp @@ -65,7 +65,6 @@ bool MEAutoVectorization::PhaseRun(MeFunction &f) { void MEAutoVectorization::GetAnalysisDependence(maple::AnalysisDep &aDep) const { aDep.AddRequired(); aDep.AddRequired(); - aDep.PreservedAllExcept(); aDep.PreservedAllExcept(); aDep.PreservedAllExcept(); } diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 48f6650a68..80ace937e7 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -36,7 +36,7 @@ void MeFuncPM::DumpMEIR(MeFunction &f, const std::string phaseName, bool isBefor } if ((MeOption::dumpAfter || dumpPhase) && dumpFunc && !isBefore) { LogInfo::MapleLogger() << ">>>>> Dump after " << phaseName << " <<<<<\n"; - if (phaseName != "meemit") { + if (phaseName != "meemit" && phaseName != "lfounroll") { f.Dump(false); } else { f.DumpFunctionNoSSA(); -- Gitee