From 43b1f102715f868358af719c91373ac7a5618b35 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 29 Jul 2021 20:36:13 -0700 Subject: [PATCH 1/2] Improved dependence testing to allow arrays with arbitrary base. Loops with pointer expressions are not screened out as long as the expressions are loop invariant. --- src/mapleall/maple_ir/include/mir_type.h | 4 + src/mapleall/maple_me/include/lfo_dep_test.h | 6 +- .../src/demand_driven_alias_analysis.cpp | 4 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 89 +++++++++++-------- src/mapleall/maple_me/src/lfo_loop_vec.cpp | 2 +- src/mapleall/maple_me/src/me_ssa_lpre.cpp | 10 +-- 6 files changed, 66 insertions(+), 49 deletions(-) diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index aff6f1b2fc..f3d8e2e439 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -69,6 +69,10 @@ inline bool IsPossible32BitAddress(PrimType tp) { return (tp == PTY_ptr || tp == PTY_ref || tp == PTY_u32 || tp == PTY_a32); } +inline bool MustBeAddress(PrimType tp) { + return (tp == PTY_ptr || tp == PTY_ref || tp == PTY_a64 || tp == PTY_a32); +} + inline bool IsPrimitivePureScalar(PrimitiveType primitiveType) { return primitiveType.IsInteger() && !primitiveType.IsAddress() && !primitiveType.IsDynamic() && !primitiveType.IsVector(); diff --git a/src/mapleall/maple_me/include/lfo_dep_test.h b/src/mapleall/maple_me/include/lfo_dep_test.h index 478071a4fb..ad3074daff 100644 --- a/src/mapleall/maple_me/include/lfo_dep_test.h +++ b/src/mapleall/maple_me/include/lfo_dep_test.h @@ -70,8 +70,8 @@ class DoloopInfo { 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 hasOtherCtrlFlow = false; // give up dep testing if true + bool hasPtrAccess = 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 @@ -90,8 +90,8 @@ class DoloopInfo { ~DoloopInfo() = default; bool IsLoopInvariant(MeExpr *x); SubscriptDesc *BuildOneSubscriptDesc(BaseNode *subsX); - ArrayAccessDesc *BuildOneArrayAccessDesc(ArrayNode *arr, bool isRHS); - void CreateRHSArrayAccessDesc(BaseNode *x); + ArrayAccessDesc *BuildOneArrayAccessDesc(ArrayNode *arr, BaseNode *parent); + void CreateRHSArrayAccessDesc(BaseNode *x, BaseNode *parent); void CreateArrayAccessDesc(BlockNode *block); void CreateDepTestLists(); void TestDependences(MapleVector *depTestList, bool bothLHS); diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index 1974af4cdc..0437615474 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -238,7 +238,7 @@ PEGBuilder::PtrValueRecorder PEGBuilder::BuildPEGNodeOfAdd(const BinaryNode *bin auto *constVal = static_cast(binaryNode->Opnd(1))->GetConstVal(); ASSERT(constVal->GetKind() == kConstInt, "pointer cannot add/sub a non-integer value"); constexpr int kBitNumInOneByte = 8; - int64 offsetValue = static_cast(constVal)->GetValue() * kBitNumInOneByte; + int64 offsetValue = static_cast(static_cast(constVal)->GetValue()) * kBitNumInOneByte; if (binaryNode->GetOpCode() == OP_sub) { offset = ptrNode.offset + (-offsetValue); } else if (binaryNode->GetOpCode() == OP_add) { @@ -1041,4 +1041,4 @@ bool DemandDrivenAliasAnalysis::MayAlias(OriginalSt *ostA, OriginalSt *ostB) { } return aliasAccordingDDAA; } -} // namespace maple \ No newline at end of file +} // namespace maple diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index 00322aac6a..2d6070c8cc 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -128,8 +128,7 @@ bool DoloopInfo::IsLoopInvariant(MeExpr *x) { } SubscriptDesc *DoloopInfo::BuildOneSubscriptDesc(BaseNode *subsX) { - LfoPart *lfopart = depInfo->preEmit->GetLfoExprPart(subsX); - MeExpr *meExpr = lfopart->GetMeExpr(); + MeExpr *meExpr = depInfo->preEmit->GetMexpr(subsX); SubscriptDesc *subsDesc = alloc->GetMemPool()->New(meExpr); if (IsLoopInvariant(meExpr)) { subsDesc->loopInvariant = true; @@ -198,37 +197,45 @@ SubscriptDesc *DoloopInfo::BuildOneSubscriptDesc(BaseNode *subsX) { return subsDesc; } -ArrayAccessDesc *DoloopInfo::BuildOneArrayAccessDesc(ArrayNode *arr, bool isRHS) { -#if 0 +ArrayAccessDesc *DoloopInfo::BuildOneArrayAccessDesc(ArrayNode *arr, BaseNode *parent) { MIRType *atype = arr->GetArrayType(GlobalTables::GetTypeTable()); ASSERT(atype->GetKind() == kTypeArray, "type was wrong"); MIRArrayType *arryty = static_cast(atype); size_t dim = arryty->GetDim(); CHECK_FATAL(dim == arr->NumOpnds() - 1, "BuildOneArrayAccessDesc: inconsistent array dimension"); -#else - size_t dim = arr->NumOpnds() - 1; -#endif + // ensure array base is loop invariant + OpMeExpr *arrayMeExpr = static_cast(depInfo->preEmit->GetMexpr(arr)); + if (!IsLoopInvariant(arrayMeExpr->GetOpnd(0))) { + hasPtrAccess = true; + return nullptr; + } // determine arrayOst - LfoPart *lfopart = depInfo->preEmit->GetLfoExprPart(arr); - OpMeExpr *arrayMeExpr = static_cast(lfopart->GetMeExpr()); + IvarMeExpr *ivarMeExpr = nullptr; 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(); + if (parent->op == OP_iread) { + ivarMeExpr = static_cast(depInfo->preEmit->GetMexpr(parent)); + CHECK_FATAL(ivarMeExpr->GetMu() != nullptr, "BuildOneArrayAccessDesc: no mu corresponding to iread"); + arryOst = ivarMeExpr->GetMu()->GetOst(); + } else if (parent->op == OP_iassign) { + IassignMeStmt *iassMeStmt = static_cast(depInfo->preEmit->GetMeStmt(static_cast(parent)->GetStmtID())); + ivarMeExpr = iassMeStmt->GetLHSVal(); + if (ivarMeExpr->GetMu()) { + arryOst = ivarMeExpr->GetMu()->GetOst(); } else { - hasPtrAccess = true; - return nullptr; + MapleMap *chiList = iassMeStmt->GetChiList(); + CHECK_FATAL(!chiList->empty(), "BuildOneArrayAccessDesc: no chi corresponding to iassign"); + arryOst = depInfo->lfoFunc->meFunc->GetMeSSATab()->GetOriginalStFromID(chiList->begin()->first); } + } else { + hasPtrAccess = true; + return nullptr; } + ArrayAccessDesc *arrDesc = alloc->GetMemPool()->New(alloc, arr, arryOst); - if (isRHS) { - rhsArrays.push_back(arrDesc); - } else { + if (parent->op == OP_iassign) { lhsArrays.push_back(arrDesc); + } else { + rhsArrays.push_back(arrDesc); } for (size_t i = 0; i < dim; i++) { SubscriptDesc *subs = BuildOneSubscriptDesc(arr->GetIndex(i)); @@ -237,12 +244,20 @@ ArrayAccessDesc *DoloopInfo::BuildOneArrayAccessDesc(ArrayNode *arr, bool isRHS) return arrDesc; } -void DoloopInfo::CreateRHSArrayAccessDesc(BaseNode *x) { +void DoloopInfo::CreateRHSArrayAccessDesc(BaseNode *x, BaseNode *parent) { if (x->GetOpCode() == OP_array) { - BuildOneArrayAccessDesc(static_cast(x), true /* isRHS */); + if (parent->GetOpCode() != OP_iread) { // skip arrays not underneath iread unless loop-invariant + if (IsLoopInvariant(depInfo->preEmit->GetMexpr(x))) { + return; + } + hasPtrAccess = true; + } else { + BuildOneArrayAccessDesc(static_cast(x), parent); + } + return; } for (size_t i = 0; i < x->NumOpnds(); i++) { - CreateRHSArrayAccessDesc(x->Opnd(i)); + CreateRHSArrayAccessDesc(x->Opnd(i), x); } } @@ -259,7 +274,7 @@ void DoloopInfo::CreateArrayAccessDesc(BlockNode *block) { break; } case OP_if: { - CreateRHSArrayAccessDesc(stmt->Opnd(0)); + CreateRHSArrayAccessDesc(stmt->Opnd(0), stmt); IfStmtNode *ifstmtnode = static_cast(stmt); if (ifstmtnode->GetThenPart()) CreateArrayAccessDesc(ifstmtnode->GetThenPart()); @@ -269,17 +284,16 @@ void DoloopInfo::CreateArrayAccessDesc(BlockNode *block) { } case OP_dowhile: case OP_while: { - CreateRHSArrayAccessDesc(stmt->Opnd(0)); + CreateRHSArrayAccessDesc(stmt->Opnd(0), stmt); CreateArrayAccessDesc(static_cast(stmt)->GetBody()); break; } case OP_iassign: { IassignNode *iass = static_cast(stmt); if (iass->addrExpr->GetOpCode() == OP_array) { - ArrayAccessDesc *adesc = BuildOneArrayAccessDesc(static_cast(iass->addrExpr), false /* isRHS */); - if (adesc == nullptr) { - hasMayDef = true; - } else { + ArrayAccessDesc *adesc = BuildOneArrayAccessDesc(static_cast(iass->addrExpr), iass); + if (adesc != nullptr) { + CHECK_FATAL(adesc->arrayOst, "CreateArrayAccessDesc: arrayOst not valid"); // check if the chi list has only the same array LfoPart *lfopart = depInfo->preEmit->GetLfoStmtPart(iass->GetStmtID()); IassignMeStmt *iassMeStmt = static_cast(lfopart->GetMeStmt()); @@ -296,18 +310,18 @@ void DoloopInfo::CreateArrayAccessDesc(BlockNode *block) { } else { hasPtrAccess = true; } - CreateRHSArrayAccessDesc(iass->rhs); + CreateRHSArrayAccessDesc(iass->rhs, iass); break; } case OP_dassign: case OP_regassign: { hasScalarAssign = true; - CreateRHSArrayAccessDesc(stmt->Opnd(0)); + CreateRHSArrayAccessDesc(stmt->Opnd(0), stmt); break; } default: { for (size_t i = 0; i < stmt->NumOpnds(); i++) { - CreateRHSArrayAccessDesc(stmt->Opnd(i)); + CreateRHSArrayAccessDesc(stmt->Opnd(i), stmt); } break; } @@ -420,6 +434,9 @@ void LfoDepInfo::PerformDepTest() { if (!doloopInfo->children.empty()) { continue; // only handling innermost doloops } + if (doloopInfo->hasOtherCtrlFlow) { + continue; + } doloopInfo->CreateArrayAccessDesc(doloopInfo->doloop->GetDoBody()); if (DEBUGFUNC(lfoFunc->meFunc)) { LogInfo::MapleLogger() << "Innermost Doloop:"; @@ -450,8 +467,7 @@ void LfoDepInfo::PerformDepTest() { LogInfo::MapleLogger() << " [messy]"; } else { LogInfo::MapleLogger() << " [" << subs->coeff << "*"; - LfoPart *lfopart = preEmit->GetLfoExprPart(subs->iv); - ScalarMeExpr *scalar = static_cast(lfopart->GetMeExpr()); + ScalarMeExpr *scalar = static_cast(preEmit->GetMexpr(subs->iv)); scalar->GetOst()->Dump(); LogInfo::MapleLogger() << "+" << subs->additiveConst << "]"; } @@ -471,8 +487,7 @@ void LfoDepInfo::PerformDepTest() { LogInfo::MapleLogger() << " [messy]"; } else { LogInfo::MapleLogger() << " [" << subs->coeff << "*"; - LfoPart *lfopart = preEmit->GetLfoExprPart(subs->iv); - ScalarMeExpr *scalar = static_cast(lfopart->GetMeExpr()); + ScalarMeExpr *scalar = static_cast(preEmit->GetMexpr(subs->iv)); scalar->GetOst()->Dump(); LogInfo::MapleLogger() << "+" << subs->additiveConst << "]"; } diff --git a/src/mapleall/maple_me/src/lfo_loop_vec.cpp b/src/mapleall/maple_me/src/lfo_loop_vec.cpp index 2f8ca65ad8..a938661f1b 100644 --- a/src/mapleall/maple_me/src/lfo_loop_vec.cpp +++ b/src/mapleall/maple_me/src/lfo_loop_vec.cpp @@ -465,7 +465,7 @@ bool LoopVectorization::ExprVectorizable( bool canVec = ExprVectorizable(doloopInfo, x->Opnd(0)); if (canVec) { IreadNode *iread = static_cast(x); - if (iread->GetFieldID() != 0 && iread->Opnd(0)->GetOpCode() == OP_array) { + if ((iread->GetFieldID() != 0 || MustBeAddress(iread->GetPrimType())) && iread->Opnd(0)->GetOpCode() == OP_array) { MeExpr *meExpr = depInfo->preEmit->GetLfoExprPart(iread->Opnd(0))->GetMeExpr(); canVec = doloopInfo->IsLoopInvariant(meExpr); } diff --git a/src/mapleall/maple_me/src/me_ssa_lpre.cpp b/src/mapleall/maple_me/src/me_ssa_lpre.cpp index 9e18a6a496..84874dedcb 100644 --- a/src/mapleall/maple_me/src/me_ssa_lpre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_lpre.cpp @@ -327,12 +327,10 @@ void MeSSALPre::BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr &meExpr, if (preKind != kAddrPre) { break; } - if (mirModule->IsJavaModule()) { - auto *addrOfMeExpr = static_cast(&meExpr); - const OriginalSt *ost = ssaTab->GetOriginalStFromID(addrOfMeExpr->GetOstIdx()); - if (ost->IsLocal()) { // skip lpre for stack addresses as they are cheap and need keep for rc - break; - } + auto *addrOfMeExpr = static_cast(&meExpr); + const OriginalSt *ost = ssaTab->GetOriginalStFromID(addrOfMeExpr->GetOstIdx()); + if (ost->IsLocal()) { // skip lpre for stack addresses as they are cheap and need keep for rc + break; } (void)CreateRealOcc(meStmt, seqStmt, meExpr, false); break; -- Gitee From 3f3d333b1e55ee67aadcf00d0866ee3ff9afaa22 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 30 Jul 2021 23:48:34 -0700 Subject: [PATCH 2/2] handle cvt in array subscripts Fixed inliner issue I3YF7Y --- src/mapleall/maple_ipa/src/inline.cpp | 2 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mapleall/maple_ipa/src/inline.cpp b/src/mapleall/maple_ipa/src/inline.cpp index 25b8f6be46..9b8ebbd2ef 100644 --- a/src/mapleall/maple_ipa/src/inline.cpp +++ b/src/mapleall/maple_ipa/src/inline.cpp @@ -776,7 +776,7 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo PrimType formalPrimType = newFormal->GetType()->GetPrimType(); PrimType realArgPrimType = currBaseNode->GetPrimType(); // If realArg's type is different from formal's type, use cvt - if (formalPrimType != realArgPrimType) { + if (formalPrimType != realArgPrimType && MustBeAddress(formalPrimType) != MustBeAddress(realArgPrimType)) { bool intTrunc = (IsPrimitiveInteger(formalPrimType) && IsPrimitiveInteger(realArgPrimType) && GetPrimTypeSize(realArgPrimType) > GetPrimTypeSize(formalPrimType)); // For dassign, if rhs-expr is a primitive integer type, the assigned variable may be smaller, resulting in a diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index 2d6070c8cc..67e30b40e2 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -159,13 +159,13 @@ SubscriptDesc *DoloopInfo::BuildOneSubscriptDesc(BaseNode *subsX) { } // process mainTerm BaseNode *varNode = nullptr; - if (op != OP_mul) { + if (mainTerm->GetOpCode() != OP_mul) { varNode = mainTerm; } else { BinaryNode *mulbinnode = static_cast(mainTerm); BaseNode *mulopnd0 = mulbinnode->Opnd(0); BaseNode *mulopnd1 = mulbinnode->Opnd(1); - if (mulopnd0->GetOpCode() != OP_dread) { + if (mulopnd0->GetOpCode() != OP_dread && mulopnd0->GetOpCode() != OP_cvt) { subsDesc->tooMessy = true; return subsDesc; } @@ -186,6 +186,9 @@ SubscriptDesc *DoloopInfo::BuildOneSubscriptDesc(BaseNode *subsX) { } } // process varNode + if (varNode->GetOpCode() == OP_cvt) { + varNode = varNode->Opnd(0); + } if (varNode->GetOpCode() == OP_dread) { DreadNode *dnode = static_cast(varNode); if (dnode->GetStIdx() == doloop->GetDoVarStIdx()) { -- Gitee