diff --git a/src/mapleall/maple_me/include/lfo_iv_canon.h b/src/mapleall/maple_me/include/lfo_iv_canon.h index b341830de17c2df8d2483dd9ea759c4a7b7e0126..5b2b73acdd7a2ef693ceead6ce7a7b3a361c4e46 100644 --- a/src/mapleall/maple_me/include/lfo_iv_canon.h +++ b/src/mapleall/maple_me/include/lfo_iv_canon.h @@ -29,6 +29,7 @@ class IVDesc { PrimType primType; MeExpr *initExpr = nullptr; int32 stepValue = 0; + bool canBePrimary = true; explicit IVDesc(OriginalSt *o) : ost(o) { @@ -59,7 +60,7 @@ class IVCanon { aloop(ldesc), loopID(id), whileInfo(winfo), ivvec(alloc.Adapter()) {} virtual ~IVCanon() = default; bool ResolveExprValue(MeExpr *x, ScalarMeExpr *philhs); - int32 ComputeIncrAmt(MeExpr *x, ScalarMeExpr *philhs, int32 *appearances); + int32 ComputeIncrAmt(MeExpr *x, ScalarMeExpr *philhs, int32 *appearances, bool &canBePrimary); void CharacterizeIV(ScalarMeExpr *initversion, ScalarMeExpr *loopbackversion, ScalarMeExpr *philhs); void FindPrimaryIV(); bool IsLoopInvariant(MeExpr *x); diff --git a/src/mapleall/maple_me/src/lfo_iv_canon.cpp b/src/mapleall/maple_me/src/lfo_iv_canon.cpp index fed13132b7193dff9472c8d1d2e8e051672149f0..a378ed455dbb0d304ddde6d0e8b4ef834b613a86 100644 --- a/src/mapleall/maple_me/src/lfo_iv_canon.cpp +++ b/src/mapleall/maple_me/src/lfo_iv_canon.cpp @@ -63,8 +63,10 @@ bool IVCanon::ResolveExprValue(MeExpr *x, ScalarMeExpr *phiLHS) { } // appearances accumulates the number of appearances of the induction variable; -// it is negative if it is subtracted -int32 IVCanon::ComputeIncrAmt(MeExpr *x, ScalarMeExpr *phiLHS, int32 *appearances) { +// it is negative if it is subtracted; +// canBePrimary is set to false if it takes more than one increment statements +// to get to phiLHS +int32 IVCanon::ComputeIncrAmt(MeExpr *x, ScalarMeExpr *phiLHS, int32 *appearances, bool &canBePrimary) { switch (x->GetMeOp()) { case kMeOpConst: { MIRConst *konst = static_cast(x)->GetConstVal(); @@ -81,15 +83,24 @@ int32 IVCanon::ComputeIncrAmt(MeExpr *x, ScalarMeExpr *phiLHS, int32 *appearance ScalarMeExpr *scalar = static_cast(x); CHECK_FATAL(scalar->GetDefBy() == kDefByStmt, "ComputeIncrAmt: cannot be here"); AssignMeStmt *defstmt = static_cast(scalar->GetDefStmt()); - return ComputeIncrAmt(defstmt->GetRHS(), phiLHS, appearances); + return ComputeIncrAmt(defstmt->GetRHS(), phiLHS, appearances, canBePrimary); } case kMeOpOp: { CHECK_FATAL(x->GetOp() == OP_add || x->GetOp() == OP_sub, "ComputeIncrAmt: cannot be here"); OpMeExpr *opexp = static_cast(x); int32 appear0 = 0; - int64 incrAmt0 = ComputeIncrAmt(opexp->GetOpnd(0), phiLHS, &appear0); + if (canBePrimary) { + if ((opexp->GetOpnd(0)->GetMeOp() == kMeOpVar || opexp->GetOpnd(0)->GetMeOp() == kMeOpReg) && + opexp->GetOpnd(0) != phiLHS) { + canBePrimary = false; + } else if ((opexp->GetOpnd(1)->GetMeOp() == kMeOpVar || opexp->GetOpnd(1)->GetMeOp() == kMeOpReg) && + opexp->GetOpnd(1) != phiLHS) { + canBePrimary = false; + } + } + int64 incrAmt0 = ComputeIncrAmt(opexp->GetOpnd(0), phiLHS, &appear0, canBePrimary); int32 appear1 = 0; - int64 incrAmt1 = ComputeIncrAmt(opexp->GetOpnd(1), phiLHS, &appear1); + int64 incrAmt1 = ComputeIncrAmt(opexp->GetOpnd(1), phiLHS, &appear1, canBePrimary); if (x->GetOp() == OP_sub) { *appearances = appear0 - appear1; return incrAmt0 - incrAmt1; @@ -122,7 +133,7 @@ void IVCanon::CharacterizeIV(ScalarMeExpr *initversion, ScalarMeExpr *loopbackve ivdesc->initExpr = initversion; } int32 appearances = 0; - ivdesc->stepValue = ComputeIncrAmt(loopbackversion, philhs, &appearances); + ivdesc->stepValue = ComputeIncrAmt(loopbackversion, philhs, &appearances, ivdesc->canBePrimary); if (appearances == 1) { ivvec.push_back(ivdesc); } @@ -131,6 +142,9 @@ void IVCanon::CharacterizeIV(ScalarMeExpr *initversion, ScalarMeExpr *loopbackve void IVCanon::FindPrimaryIV() { for (uint32 i = 0; i < ivvec.size(); i++) { IVDesc *ivdesc = ivvec[i]; + if (!ivdesc->canBePrimary) { + continue; + } if (ivdesc->stepValue == 1) { bool injected = false; if (ivdesc->ost->IsSymbolOst() &&