diff --git a/src/mapleall/maple_me/src/lfo_iv_canon.cpp b/src/mapleall/maple_me/src/lfo_iv_canon.cpp index 59434b6a361d5c418294a842e5b6443371c66c82..cf0e08ea6cea83bc61e028d9f56428b95daf2744 100644 --- a/src/mapleall/maple_me/src/lfo_iv_canon.cpp +++ b/src/mapleall/maple_me/src/lfo_iv_canon.cpp @@ -247,21 +247,37 @@ void IVCanon::ComputeTripCount() { // make the side that consists of a single IV the left operand // check left operand ScalarMeExpr *iv = dynamic_cast(testExpr->GetOpnd(0)); + bool cvtDetected = false; + if (iv == nullptr && testExpr->GetOpnd(0)->GetOp() == OP_cvt) { + iv = dynamic_cast(testExpr->GetOpnd(0)->GetOpnd(0)); + cvtDetected = true; + } IVDesc *ivdesc = nullptr; if (iv) { for (uint32 i = 0; i < ivvec.size(); i++) { if (iv->GetOst() == ivvec[i]->ost) { ivdesc = ivvec[i]; + if (cvtDetected) { + ivdesc->canBePrimary = false; + } break; } } } if (ivdesc == nullptr) { // check second operand + cvtDetected = false; iv = dynamic_cast(testExpr->GetOpnd(1)); + if (iv == nullptr && testExpr->GetOpnd(1)->GetOp() == OP_cvt) { + iv = dynamic_cast(testExpr->GetOpnd(1)->GetOpnd(0)); + cvtDetected = true; + } if (iv) { for (uint32 i = 0; i < ivvec.size(); i++) { if (iv->GetOst() == ivvec[i]->ost) { ivdesc = ivvec[i]; + if (cvtDetected) { + ivdesc->canBePrimary = false; + } break; } } @@ -311,15 +327,22 @@ void IVCanon::ComputeTripCount() { } // form the trip count expression - PrimType primTypeUsed = (!ivdesc->initExpr->IsZero()) ? - GetSignedPrimType(testExpr->GetOpnd(0)->GetPrimType()) : testExpr->GetOpnd(0)->GetPrimType(); + MeExpr *testExprLHS = testExpr->GetOpnd(0); + MeExpr *testExprRHS = testExpr->GetOpnd(1); + PrimType primTypeUsed = testExprRHS->GetPrimType(); + if (GetPrimTypeSize(testExprLHS->GetPrimType()) > GetPrimTypeSize(primTypeUsed)) { + primTypeUsed = testExprLHS->GetPrimType(); + } + if (!ivdesc->initExpr->IsZero()) { + primTypeUsed = GetSignedPrimType(primTypeUsed); + } PrimType divPrimType = primTypeUsed; if (ivdesc->stepValue < 0) { divPrimType = GetSignedPrimType(divPrimType); } // add: t = bound + (stepValue +/-1) OpMeExpr add(-1, OP_add, primTypeUsed, 2); - add.SetOpnd(0, testExpr->GetOpnd(1)); // IV bound + add.SetOpnd(0, testExprRHS); // IV bound if (CompareHasEqual(condbr->GetOpnd()->GetOp())) { // if cond has equal operand, t = bound + stepValue add.SetOpnd(1, irMap->CreateIntConstMeExpr(ivdesc->stepValue, primTypeUsed)); @@ -329,6 +352,13 @@ void IVCanon::ComputeTripCount() { primTypeUsed)); } MeExpr *subx = irMap->HashMeExpr(add); + // insert a CVT for ivdesc->initExpr if needed + if (GetPrimTypeSize(ivdesc->initExpr->GetPrimType()) != GetPrimTypeSize(primTypeUsed) && ivdesc->initExpr->GetMeOp() != kMeOpConst) { + OpMeExpr cvtx(-1, OP_cvt, primTypeUsed, 1); + cvtx.SetOpnd(0, ivdesc->initExpr); + cvtx.SetOpndType(ivdesc->initExpr->GetPrimType()); + ivdesc->initExpr = func->GetIRMap()->HashMeExpr(cvtx); + } if (!ivdesc->initExpr->IsZero()) { // sub: t = t - initExpr OpMeExpr subtract(-1, OP_sub, primTypeUsed, 2); @@ -513,6 +543,11 @@ void IVCanon::PerformIVCanon() { CharacterizeIV(initVersion, loopbackVersion, philhs); } } + CanonEntryValues(); + ComputeTripCount(); + if (tripCount == nullptr) { + return; + } FindPrimaryIV(); if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "****** while loop at label " << "@" @@ -529,11 +564,6 @@ void IVCanon::PerformIVCanon() { LogInfo::MapleLogger() << endl; } } - CanonEntryValues(); - ComputeTripCount(); - if (tripCount == nullptr) { - return; - } if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "****** trip count is: "; tripCount->Dump(func->GetIRMap(), 0); diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 0ee46371b959b622fb10d541e447618f614b2503..0ad8eea30c351de738250535e95a82b4e0872820 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -764,6 +764,16 @@ DoloopNode *PreMeEmitter::EmitPreMeDoloop(BB *mewhilebb, BlockNode *curblk, PreM CondGotoMeStmt *condGotostmt = static_cast(lastmestmt); Doloopnode->SetStartExpr(EmitPreMeExpr(whileInfo->initExpr, Doloopnode)); Doloopnode->SetContExpr(EmitPreMeExpr(condGotostmt->GetOpnd(), Doloopnode)); + CompareNode *compare = static_cast(Doloopnode->GetCondExpr()); + if (compare->Opnd(0)->GetOpCode() == OP_cvt && compare->Opnd(0)->Opnd(0)->GetOpCode() == OP_cvt) { + PrimType resPrimType = compare->Opnd(0)->GetPrimType(); + PrimType opndPrimType = static_cast(compare->Opnd(0))->FromType(); + TypeCvtNode *secondCvtX = static_cast(compare->Opnd(0)->Opnd(0)); + if (IsNoCvtNeeded(resPrimType, secondCvtX->FromType()) && + IsNoCvtNeeded(opndPrimType, secondCvtX->GetPrimType())) { + compare->SetOpnd(secondCvtX->Opnd(0), 0); + } + } BlockNode *dobodyNode = codeMP->New(); Doloopnode->SetDoBody(dobodyNode); PreMeMIRExtension *doloopExt = preMeMP->New(Doloopnode);