diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp index dc721c2..303b7f0 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp @@ -3,6 +3,7 @@ #include "../Utils/errors.h" #include "../Utils/SgUtils.h" #include "../Utils/utils.h" +#include "../ExpressionTransform/expr_transform.h" using std::make_pair; using std::map; @@ -26,7 +27,6 @@ struct FixedSubscript { struct RegularExpr { int coefA; int coefB; - SgSymbol* varSymbol; }; // DefUseStmtsPair represents pair of DEF and USE statements for private variable @@ -57,7 +57,7 @@ static void fillDirectArrayRefs(SgExpression* exp, SgSymbol* arraySym, vectorrhs(), arraySym, refs); } -// getDirectArrayRefs returns all direct arraySym references in stmt, +// getDirectArrayRefs returns all direct arraySym references in compound stmt, // except VAR_DECL statements static vector getDirectArrayRefs(SgStatement* stmt, SgSymbol* arraySym) { @@ -81,6 +81,22 @@ static vector getDirectArrayRefs(SgStatement* stmt, SgSymbol* ar return arrayRefs; } +// getDirectArrayRefs returns all direct arraySym references in single stmt, +// except VAR_DECL statements +static vector getDirectArrayRefsFromSingleStmt(SgStatement* stmt, SgSymbol* arraySym) +{ + vector arrayRefs; + if (stmt == nullptr) + return arrayRefs; + + if (stmt->variant() != VAR_DECL && stmt->variant() != VAR_DECL_90) // skip var declaration stmt + for (int i = 0; i < 3; ++i) + fillDirectArrayRefs(stmt->expr(i), arraySym, arrayRefs); + + + return arrayRefs; +} + static bool isArrayRefInVector(SgArrayRefExp* ref, const vector& arrayRefs) { for (SgArrayRefExp* arrayRef : arrayRefs) @@ -92,62 +108,20 @@ static bool isArrayRefInVector(SgArrayRefExp* ref, const vector& // checkAndFillRegularExpr checks if expr is regular and fills regularExpr struct // with info about expr -static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr) +static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr, SgSymbol* iterationVar) { - regularExpr.coefA = 0; - regularExpr.coefB = 0; - regularExpr.varSymbol = nullptr; + pair retCoefs; + getCoefsOfSubscript(retCoefs, expr, iterationVar); - if (expr->variant() == INT_VAL) // expr is like ( coefB ) - { - regularExpr.coefB = expr->valueInteger(); + regularExpr.coefA = retCoefs.first; + regularExpr.coefB = retCoefs.second; + + if (retCoefs.first != 0 || retCoefs.second != 0) return true; - } - if (expr->variant() == VAR_REF) // expr is like ( I ) - { - regularExpr.coefA = 1; - regularExpr.varSymbol = expr->symbol(); + // check if expr is like ( 0 ), because we cannot separate zero const int expr from incorrect expr: + if (expr->variant() == INT_VAL) return true; - } - - // is expr like ( coefA * I ): - if (expr->variant() == MULT_OP) - { - if (expr->lhs()->variant() == INT_VAL && expr->rhs()->variant() == VAR_REF) - { - regularExpr.coefA = expr->lhs()->valueInteger(); - regularExpr.varSymbol = expr->rhs()->symbol(); - return true; - } - } - - if ((expr->variant() == ADD_OP || expr->variant() == SUBT_OP) && expr->rhs()->variant() == INT_VAL) - { - if (expr->variant() == ADD_OP) - regularExpr.coefB = expr->rhs()->valueInteger(); - else // expr->variant() == SUBT_OP - regularExpr.coefB = (-1) * expr->rhs()->valueInteger(); - - if (expr->lhs()->variant() == MULT_OP) // is expr like ( coefA * I + coefB ) - { - if (expr->lhs()->lhs()->variant() == INT_VAL && expr->lhs()->rhs()->variant() == VAR_REF) - { - regularExpr.coefA = expr->lhs()->lhs()->valueInteger(); - regularExpr.varSymbol = expr->lhs()->rhs()->symbol(); - return true; - } - } - else // is expr like ( I + coefB ): - { - if (expr->lhs()->variant() == VAR_REF) - { - regularExpr.coefA = 1; - regularExpr.varSymbol = expr->lhs()->symbol(); - return true; - } - } - } return false; } @@ -155,7 +129,7 @@ static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr // getShortFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef static vector getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, const vector& fixedDimensionsMask, - Regime regime) + Regime regime, vector iterationVars) { if (regime == Regime::DEFLT) { @@ -170,11 +144,14 @@ static vector getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, { vector subscriptsVector; SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs(); + if (iterationVars.size() < indexExprList->length()) + return vector{}; + for (int i = 0; i < indexExprList->length(); ++i) { SgExpression* indexExpr = indexExprList->elem(i); RegularExpr regularExpr; - if (!checkAndFillRegularExpr(indexExpr, regularExpr)) + if (!checkAndFillRegularExpr(indexExpr, regularExpr, iterationVars[i])) return vector{}; subscriptsVector.push_back(regularExpr.coefA); @@ -187,17 +164,39 @@ static vector getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, return vector{}; } +static vector getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, const PrivateToRemove& varToRemove) +{ + vector iterationVars; + if (varToRemove.regime == Regime::REGULAR_INDEXES) + { + auto vars = varToRemove.arrayRefToIterationVarsMap.find(arrayRef); + if (vars != varToRemove.arrayRefToIterationVarsMap.end()) + iterationVars = vars->second; + } + return getShortFixedSubscriptsVector(arrayRef, varToRemove.fixedDimensions, + varToRemove.regime, iterationVars); +} + // removeDuplicateArrayRefs returns unique array refereces in fixed dimensions static vector removeDuplicateArrayRefs(const vector& arrayRefs, const vector& fixedDimensionsMask, - Regime regime) + Regime regime, + const map>& arrayRefToIterVarsMap) { map, SgArrayRefExp*> uniqueRefs; - for (SgArrayRefExp* ref : arrayRefs) + for (SgArrayRefExp* arrayRef : arrayRefs) { - vector subscripts = getShortFixedSubscriptsVector(ref, fixedDimensionsMask, regime); + vector iterationVars; + if (regime == Regime::REGULAR_INDEXES) + { + auto vars = arrayRefToIterVarsMap.find(arrayRef); + if (vars != arrayRefToIterVarsMap.end()) + iterationVars = vars->second; + } + + vector subscripts = getShortFixedSubscriptsVector(arrayRef, fixedDimensionsMask, regime, iterationVars); if (uniqueRefs.find(subscripts) == uniqueRefs.end()) - uniqueRefs.insert(make_pair(subscripts, ref)); + uniqueRefs.insert(make_pair(subscripts, arrayRef)); } vector result; @@ -543,7 +542,7 @@ static void removeDeadCodeFromLoop(LoopGraph* loop) // fillReadShortFixedSumscripts fills all short fixed subscripts vectors of array var, // which are used for reading from array var in exp -static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemove& var, +static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemove& var, set>& fixedSubscripts) { if (exp == nullptr) @@ -553,7 +552,7 @@ static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemov { if (isEqSymbols(exp->symbol(), var.varSymbol)) { - auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var.fixedDimensions, var.regime); + auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var); fixedSubscripts.insert(subscripts); return; } @@ -597,8 +596,7 @@ static void removeExcessiveDefs(const PrivateToRemove& var) if (st->expr(0)->symbol() == nullptr || !isEqSymbols(st->expr(0)->symbol(), var.varSymbol)) continue; - auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var.fixedDimensions, - var.regime); + auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var); if (usedFixedSubscripts.find(subscripts) == usedFixedSubscripts.end()) stmtsToRemove.push_back(st); } @@ -699,8 +697,7 @@ static set> removeArray(string filename, const PrivateToRemove& arra SgStatement* useStmt = defUsePair.second; SgArrayRefExp* defRef = (SgArrayRefExp*)defStmt->lhs(); - vector defFixedSubscripts = getShortFixedSubscriptsVector(defRef, fixedDimensions, - arrayToRemove.regime); + vector defFixedSubscripts = getShortFixedSubscriptsVector(defRef, arrayToRemove); int startIndex = 0; if (useStmt->variant() == ASSIGN_STAT) @@ -715,8 +712,7 @@ static set> removeArray(string filename, const PrivateToRemove& arra for (SgArrayRefExp* useRef : arrayUseRefs) { - vector useFixedSubscripts = getShortFixedSubscriptsVector(useRef, fixedDimensions, - arrayToRemove.regime); + vector useFixedSubscripts = getShortFixedSubscriptsVector(useRef, arrayToRemove); if (defFixedSubscripts != useFixedSubscripts) continue; // because useRef and defRef can be different in subscripts of fixed dimensions @@ -767,10 +763,11 @@ void removePrivates(SgFile* file, vector& messages, int& countOfTransf } else { - varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime); + varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime, + varToRemove.arrayRefToIterationVarsMap); for (auto& varRef : varRefs) { - vector subscripts = getShortFixedSubscriptsVector(varRef, fixedDimensions, varToRemove.regime); + vector subscripts = getShortFixedSubscriptsVector(varRef, varToRemove); if (removedDimensions.find(subscripts) != removedDimensions.end()) { varName = getDimensionVarName(varToRemove.varSymbol, subscripts, @@ -811,10 +808,9 @@ struct Context { SgForStmt* loopStmt; SgSymbol* arraySymbol; int dimensionsNum; - // string arrayName; // TODO: может быть можно заменить arraySym на arrayName vector explicitArrayRefs; - //vector> regularIndexRefs; vector fixedDimensionsMask; + map> arrayRefToIterationVarsMap; }; // ReducedArrayVars represents mapping of array reference to reduced scalar var: @@ -879,6 +875,33 @@ static vector::const_iterator findInsertedStmt(const vector getShortFixedSubscriptsVector(Context* ctx, SgArrayRefExp* arrayRef) +{ + vector iterationVars; + if (ctx->regime == Regime::REGULAR_INDEXES) + { + auto vars = ctx->arrayRefToIterationVarsMap.find(arrayRef); + if (vars != ctx->arrayRefToIterationVarsMap.end()) + iterationVars = vars->second; + } + + return getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime, iterationVars); +} + +// fillIterationVariables fill vars set with iteration variables of all loops +// from stmt to outerLoopStmt +static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, vector& vars) +{ + if (stmt == nullptr) + return; + + if (stmt->variant() == FOR_NODE) + vars.push_back(((SgForStmt*)stmt)->doName()); + + if (stmt->id() != outerLoopStmt->id()) + fillIterationVars(stmt->controlParent(), outerLoopStmt, vars); +} + // matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension static bool checkFixedDimensionsMaskMatching(Context* ctx) { @@ -894,13 +917,14 @@ static bool checkFixedDimensionsMaskMatching(Context* ctx) // and VAR_REF in non-fixed dimensions static bool checkDefStmtRefsMatchesMask(Context* ctx) { - // TODO: сделать проверку, что все VAR_REF - это итерационные переменные цикла - // потом переделать, что может быть выражение a * i + b, но i не используется в правой части for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext()) { if (st->variant() != ASSIGN_STAT) continue; + vector iterationVars; + fillIterationVars(st, ctx->loopStmt, iterationVars); + if (isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol)) // DEF statement { SgArrayRefExp* ref = (SgArrayRefExp*)st->expr(0); @@ -908,8 +932,19 @@ static bool checkDefStmtRefsMatchesMask(Context* ctx) { if (ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == INT_VAL) continue; + if (!ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == VAR_REF) + { + bool isIterationVar = false; + for (auto iterationvVar : iterationVars) + if (isEqSymbols(ref->subscript(i)->symbol(), iterationvVar)) + isIterationVar = true; + + if (!isIterationVar) + return false; + continue; + } return false; } @@ -951,44 +986,40 @@ static string sunparseFixedDimensionsVector(const vector& fixedDimensions) return result; } -// fillIterationVariables fill vars set with iteration variables of all loops -// from stmt to outerLoopStmt -static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, set& vars) -{ - if (stmt == nullptr) - return; - - if (stmt->variant() == FOR_NODE) - vars.insert(((SgForStmt*)stmt)->doName()->identifier()); - - if (stmt->id() != outerLoopStmt->id()) - fillIterationVars(stmt->controlParent(), outerLoopStmt, vars); -} - static bool checkRegularIndexRefs(Context* ctx) { - for (auto arrayRef : ctx->explicitArrayRefs) - { - SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs(); - for (int i = 0; i < ctx->dimensionsNum; ++i) - { - SgExpression* indexExpr = indexExprList->elem(i); - RegularExpr regularExpr; - if (!checkAndFillRegularExpr(indexExpr, regularExpr)) - return false; - - //ctx->regularIndexRefs.push_back(make_pair(arrayRef, regularExpr)); - } - } - vector newArrayRefsVector; for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext()) { - if (st->variant() != ASSIGN_STAT || !isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol)) - continue; - - if (isSymbolInExpression(ctx->arraySymbol, st->expr(1))) - return false; + vector iterationVars; + fillIterationVars(st, ctx->loopStmt, iterationVars); + + vector arrayRefs = getDirectArrayRefsFromSingleStmt(st, ctx->arraySymbol); + for (auto arrayRef : arrayRefs) + { + if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs)) + continue; + + SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs(); + if (iterationVars.size() < indexExprList->length()) + return false; + + for (int i = 0; i < indexExprList->length(); ++i) + { + SgExpression* indexExpr = indexExprList->elem(i); + RegularExpr regularExpr; + if (!checkAndFillRegularExpr(indexExpr, regularExpr, iterationVars[i])) + return false; + } + + if (st->variant() == ASSIGN_STAT && isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol)) + for (auto iterationVar : iterationVars) + if (isSymbolInExpression(iterationVar, st->expr(1))) + return false; + + iterationVars.resize(indexExprList->length()); + ctx->arrayRefToIterationVarsMap.insert(make_pair(arrayRef, iterationVars)); + } } return true; @@ -1128,7 +1159,7 @@ static vector> checkImplicitDirectUsage(Context* ctx) auto mask = getFixedSubscriptsVector((SgArrayRefExp*)callArg, ctx->dimensionsNum); fixedSubscripts.push_back(mask); addMessageUsageInFunctionCall(ctx->messages, getDimensionVarName(ctx->arraySymbol, mask), - procName, ctx->loop->lineNum, st->lineNumber()); + procName, ctx->loop->lineNum, st->lineNumber()); } } } @@ -1287,12 +1318,12 @@ static ReducedArrayVarsMap getReducedArrayVars(Context* ctx) SgType* type = ctx->explicitArrayRefs[0]->type(); SgStatement* scope = ctx->loopStmt->getScopeForDeclare(); - for (SgArrayRefExp* ref : ctx->explicitArrayRefs) + for (SgArrayRefExp* arrayRef : ctx->explicitArrayRefs) { - vector subscripts = getShortFixedSubscriptsVector(ref, ctx->fixedDimensionsMask, ctx->regime); + vector subscripts = getShortFixedSubscriptsVector(ctx, arrayRef); if (reducedArrayVars.find(subscripts) == nullptr) { - string name = getReducedArrayVarName(ref->symbol(), subscripts); + string name = getReducedArrayVarName(arrayRef->symbol(), subscripts); int nameNumber = checkSymbNameAndCorrect(name + "__", 0); if (nameNumber != 0) @@ -1321,7 +1352,7 @@ static set getVarsToDependOn(SgForStmt* loopStmt, SgSymbol* var) static InsertedStatement getDefStmtForReducedArray(Context* ctx, SgArrayRefExp* arrayRef, const ReducedArrayVarsMap& reducedArrayVars) { - vector subscriptVector = getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime); + vector subscriptVector = getShortFixedSubscriptsVector(ctx, arrayRef); SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector); if (reducedVar == nullptr) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); @@ -1339,7 +1370,7 @@ static InsertedStatement getUseStmtForReducedArray(Context* ctx, SgArrayRefExp* const ReducedArrayVarsMap& reducedArrayVars, SgSymbol* receiverVar) { - vector subscriptVector = getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime); + vector subscriptVector = getShortFixedSubscriptsVector(ctx, arrayRef); SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector); if (reducedVar == nullptr) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); @@ -1371,7 +1402,8 @@ static vector insertReducedArrayVarStmts(Context* ctx, { vector arrayRefs; fillDirectArrayRefs(st->expr(i), ctx->arraySymbol, arrayRefs); - arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask, ctx->regime); + arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask, ctx->regime, + ctx->arrayRefToIterationVarsMap); if (!arrayRefs.empty()) isUseStmt = true; @@ -1696,7 +1728,7 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type vector>> dependOnVars; SgArrayRefExp* defRef = (SgArrayRefExp*)defUse.first->expr(0); - vector arrayUseRefs = getDirectArrayRefs(defUse.second, ctx->arraySymbol); + vector arrayUseRefs = getDirectArrayRefsFromSingleStmt(defUse.second, ctx->arraySymbol); for (auto useRef : arrayUseRefs) { map varToExpMap = getVarToExpMap(defRef, useRef, ctx->fixedDimensionsMask); @@ -1706,7 +1738,7 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type fillFixedSubscriptsVectorsOfAllVars(expToSubst, dependOnVars); } - set iterationVars{}; + vector iterationVars{}; fillIterationVars(defUse.second, ctx->loopStmt, iterationVars); auto defInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.first); @@ -1718,7 +1750,17 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type if (var.second.size() == 0) // check scalar vars { // iteration var doesn't obstruct the removing: - if (iterationVars.find(var.first) != iterationVars.end()) + bool isIterationVar = false; + for (auto iterationVar : iterationVars) + { + if (iterationVar->identifier() == var.first) + { + isIterationVar = true; + break; + } + } + + if (isIterationVar) continue; auto defArg = findVarInRDSet(defRD_In, var.first); @@ -1879,6 +1921,7 @@ void removePrivateAnalyze(Context *ctx) newPrivateToRemove.regime = ctx->regime; newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs); newPrivateToRemove.fixedDimensions.swap(ctx->fixedDimensionsMask); + newPrivateToRemove.arrayRefToIterationVarsMap = ctx->arrayRefToIterationVarsMap; privatesToRemoveGlobal.push_back(newPrivateToRemove); } @@ -1975,4 +2018,4 @@ void removePrivatesAnalysis(vector& loopGraphs, for (LoopGraph* loop : loopGraphs) removePrivatesAnalysis(loop->children, messages, usersDirectives, commonBlocks, allFuncInfo); -} \ No newline at end of file +} diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h index 8ff66ef..84c0584 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h @@ -17,6 +17,7 @@ struct PrivateToRemove { Regime regime; std::vector> defUseStmtsPairs; std::vector fixedDimensions; + std::map> arrayRefToIterationVarsMap; }; // removePrivates removes all privates from vector privatesToRemoveGloval