diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp index b2215fe..dc721c2 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp @@ -21,6 +21,14 @@ struct FixedSubscript { int value; }; +// RegularExpr represents expressions like ( coefA * I + coefB ), +// where I is a variable and coefA or coefB can be equal to zero +struct RegularExpr { + int coefA; + int coefB; + SgSymbol* varSymbol; +}; + // DefUseStmtsPair represents pair of DEF and USE statements for private variable using DefUseStmtsPair = pair; @@ -28,21 +36,6 @@ using DefUseStmtsPair = pair; // used in PRIVATE_REMOVING pass - private vars that can be removed static vector privatesToRemoveGlobal; -// Context stores general info about current loop and array to remove -struct Context { - const map>& allFuncInfo; - const map& commonBlocks; - vector& messages; - - LoopGraph* loop; - SgForStmt* loopStmt; - SgSymbol* arraySymbol; - int dimensionsNum; - // string arrayName; // TODO: может быть можно заменить arraySym на arrayName - vector explicitArrayRefs; - vector fixedDimensionsMask; -}; - /* ******************************* * * Block of common used functions: * @@ -97,26 +90,112 @@ static bool isArrayRefInVector(SgArrayRefExp* ref, const vector& return false; } +// checkAndFillRegularExpr checks if expr is regular and fills regularExpr struct +// with info about expr +static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr) +{ + regularExpr.coefA = 0; + regularExpr.coefB = 0; + regularExpr.varSymbol = nullptr; + + if (expr->variant() == INT_VAL) // expr is like ( coefB ) + { + regularExpr.coefB = expr->valueInteger(); + return true; + } + + if (expr->variant() == VAR_REF) // expr is like ( I ) + { + regularExpr.coefA = 1; + regularExpr.varSymbol = expr->symbol(); + 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; +} + // getShortFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef static vector getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, - const vector& fixedDimensions) + const vector& fixedDimensionsMask, + Regime regime) { - vector subscriptsVector; - for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) - if (fixedDimensions[i]) - subscriptsVector.push_back(arrayRef->subscript(i)->valueInteger()); + if (regime == Regime::DEFLT) + { + vector subscriptsVector; + for (int i = 0; i < fixedDimensionsMask.size(); ++i) + if (fixedDimensionsMask[i]) + subscriptsVector.push_back(arrayRef->subscript(i)->valueInteger()); - return subscriptsVector; + return subscriptsVector; + } + else if (regime == Regime::REGULAR_INDEXES) + { + vector subscriptsVector; + SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs(); + for (int i = 0; i < indexExprList->length(); ++i) + { + SgExpression* indexExpr = indexExprList->elem(i); + RegularExpr regularExpr; + if (!checkAndFillRegularExpr(indexExpr, regularExpr)) + return vector{}; + + subscriptsVector.push_back(regularExpr.coefA); + subscriptsVector.push_back(regularExpr.coefB); + } + + return subscriptsVector; + } + + return vector{}; } // removeDuplicateArrayRefs returns unique array refereces in fixed dimensions static vector removeDuplicateArrayRefs(const vector& arrayRefs, - const vector& fixedDimensions) + const vector& fixedDimensionsMask, + Regime regime) { map, SgArrayRefExp*> uniqueRefs; for (SgArrayRefExp* ref : arrayRefs) { - vector subscripts = getShortFixedSubscriptsVector(ref, fixedDimensions); + vector subscripts = getShortFixedSubscriptsVector(ref, fixedDimensionsMask, regime); if (uniqueRefs.find(subscripts) == uniqueRefs.end()) uniqueRefs.insert(make_pair(subscripts, ref)); } @@ -274,20 +353,52 @@ static void addMessageUsageInFunctionCall(vector& messages, string var // getDimensionVarName returns var name in style A(1, 2, *) static string getDimensionVarName(SgSymbol* var, const vector& subscripts, - const vector& fixedDimensions) + const vector& fixedDimensions, Regime regime) { string result = var->identifier(); result += "("; - for (int i = 0; i < fixedDimensions.size(); ++i) + if (regime == Regime::DEFLT) { - if (fixedDimensions[i]) - result += std::to_string(subscripts[i]); - else - result += "*"; + for (int i = 0; i < fixedDimensions.size(); ++i) + { + if (fixedDimensions[i]) + result += std::to_string(subscripts[i]); + else + result += "*"; - if (i != fixedDimensions.size() - 1) - result += ", "; + if (i != fixedDimensions.size() - 1) + result += ", "; + } + } + else if (regime == Regime::REGULAR_INDEXES) + { + for (int i = 0; i < subscripts.size(); i += 2) { + if (subscripts[i] == 0 && subscripts[(size_t)i + 1] == 0) + result += "0"; + else + { + if (subscripts[i] != 0) + { + if (subscripts[i] != 1) + result += "I_" + std::to_string(i / 2 + 1); + else + result += std::to_string(subscripts[i]) + " * I_" + std::to_string(i / 2 + 1); + + if (subscripts[(size_t)i + 1] > 0) + result += " + "; + else if (subscripts[(size_t)i + 1] < 0) + result += " - "; + } + + + if (subscripts[(size_t)i + 1] != 0) + result += std::to_string(std::abs(subscripts[(size_t)i + 1])); + } + + if (i != subscripts.size() - 2) + result += ", "; + } } result += ")"; @@ -386,6 +497,17 @@ static bool isVarReadInLoop(SgSymbol* var, SgForStmt* loopStmt) return false; } +// isVarChangedBetween checks if the var is changed between first and second statement +// by assignment to var (it doesn't check if the var is indirectly or implicitly by function call) +static bool isVarChangedBetween(string var, SgStatement* first, SgStatement* second) +{ + for (SgStatement* st = first->lexNext(); st != second; st = st->lexNext()) + if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol()->identifier() == var) + return true; + + return false; +} + // removeDeadCodeFromLoop removes assign statements to private scalar vars which are not read in loop static void removeDeadCodeFromLoop(LoopGraph* loop) { @@ -421,7 +543,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 fillReadShortFixedSumscripts(SgExpression* exp, const PrivateToRemove& var, +static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemove& var, set>& fixedSubscripts) { if (exp == nullptr) @@ -431,19 +553,19 @@ static void fillReadShortFixedSumscripts(SgExpression* exp, const PrivateToRemov { if (isEqSymbols(exp->symbol(), var.varSymbol)) { - auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var.fixedDimensions); + auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var.fixedDimensions, var.regime); fixedSubscripts.insert(subscripts); return; } } - fillReadShortFixedSumscripts(exp->lhs(), var, fixedSubscripts); - fillReadShortFixedSumscripts(exp->rhs(), var, fixedSubscripts); + fillReadShortFixedSubscripts(exp->lhs(), var, fixedSubscripts); + fillReadShortFixedSubscripts(exp->rhs(), var, fixedSubscripts); } -// getReadShortFixedSumscripts return set of all short fixed subscripts vectors of array var from loop, +// getReadShortFixedSubscripts return set of all short fixed subscripts vectors of array var from loop, // which are used for reading from array var -static set> getReadShortFixedSumscripts(const PrivateToRemove& var, SgForStmt* loopStmt) +static set> getReadShortFixedSubscripts(const PrivateToRemove& var, SgForStmt* loopStmt) { set> fixedSubscripts; for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) @@ -453,7 +575,7 @@ static set> getReadShortFixedSumscripts(const PrivateToRemove& var, i = 1; for (; i < 3; ++i) - fillReadShortFixedSumscripts(st->expr(i), var, fixedSubscripts); + fillReadShortFixedSubscripts(st->expr(i), var, fixedSubscripts); } return fixedSubscripts; @@ -464,7 +586,7 @@ static set> getReadShortFixedSumscripts(const PrivateToRemove& var, static void removeExcessiveDefs(const PrivateToRemove& var) { SgForStmt* loopStmt = (SgForStmt*)var.loop->loop->GetOriginal(); - set> usedFixedSubscripts = getReadShortFixedSumscripts(var, loopStmt); + set> usedFixedSubscripts = getReadShortFixedSubscripts(var, loopStmt); vector stmtsToRemove; for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) @@ -475,7 +597,8 @@ 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); + auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var.fixedDimensions, + var.regime); if (usedFixedSubscripts.find(subscripts) == usedFixedSubscripts.end()) stmtsToRemove.push_back(st); } @@ -576,7 +699,8 @@ static set> removeArray(string filename, const PrivateToRemove& arra SgStatement* useStmt = defUsePair.second; SgArrayRefExp* defRef = (SgArrayRefExp*)defStmt->lhs(); - vector defFixedSubscripts = getShortFixedSubscriptsVector(defRef, fixedDimensions); + vector defFixedSubscripts = getShortFixedSubscriptsVector(defRef, fixedDimensions, + arrayToRemove.regime); int startIndex = 0; if (useStmt->variant() == ASSIGN_STAT) @@ -591,7 +715,8 @@ static set> removeArray(string filename, const PrivateToRemove& arra for (SgArrayRefExp* useRef : arrayUseRefs) { - vector useFixedSubscripts = getShortFixedSubscriptsVector(useRef, fixedDimensions); + vector useFixedSubscripts = getShortFixedSubscriptsVector(useRef, fixedDimensions, + arrayToRemove.regime); if (defFixedSubscripts != useFixedSubscripts) continue; // because useRef and defRef can be different in subscripts of fixed dimensions @@ -626,7 +751,7 @@ void removePrivates(SgFile* file, vector& messages, int& countOfTransf auto removedDimensions = removeArray(file->filename(), varToRemove); countOfTransform++; - removeDeadCodeFromLoop(varToRemove.loop); + //removeDeadCodeFromLoop(varToRemove.loop); // TODO: problem with reverting substitution removeExcessiveDefs(varToRemove); removeEmptyLoops(varToRemove.loop, messages); @@ -642,13 +767,14 @@ void removePrivates(SgFile* file, vector& messages, int& countOfTransf } else { - varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions); + varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime); for (auto& varRef : varRefs) { - vector subscripts = getShortFixedSubscriptsVector(varRef, fixedDimensions); + vector subscripts = getShortFixedSubscriptsVector(varRef, fixedDimensions, varToRemove.regime); if (removedDimensions.find(subscripts) != removedDimensions.end()) { - varName = getDimensionVarName(varToRemove.varSymbol, subscripts, fixedDimensions); + varName = getDimensionVarName(varToRemove.varSymbol, subscripts, + fixedDimensions, varToRemove.regime); addMessageRemovePrivateVarPart(messages, varName, loopLineNum); } @@ -657,8 +783,9 @@ void removePrivates(SgFile* file, vector& messages, int& countOfTransf for (auto& removedDimension : removedDimensions) { - varName = getDimensionVarName(varToRemove.varSymbol, removedDimension, fixedDimensions); - addMessageRemovePrivateVar(messages, varName, loopLineNum); + varName = getDimensionVarName(varToRemove.varSymbol, removedDimension, + fixedDimensions, varToRemove.regime); + addMessageRemovePrivateVarPart(messages, varName, loopLineNum); } } } @@ -673,9 +800,26 @@ void removePrivates(SgFile* file, vector& messages, int& countOfTransf * PRIVATE_REMOVING_ANALYSIS block of functions: * * ********************************************* */ +// Context stores general info about current loop and array to remove +struct Context { + const map>& allFuncInfo; + const map& commonBlocks; + vector& messages; + + Regime regime; + LoopGraph* loop; + SgForStmt* loopStmt; + SgSymbol* arraySymbol; + int dimensionsNum; + // string arrayName; // TODO: может быть можно заменить arraySym на arrayName + vector explicitArrayRefs; + //vector> regularIndexRefs; + vector fixedDimensionsMask; +}; + // ReducedArrayVars represents mapping of array reference to reduced scalar var: // arr(1, i) -> pair, SgSymbol*>: [1], arr_1 -class ReducedArrayVars { +class ReducedArrayVarsMap { map, SgSymbol*> arrayMap; public: @@ -784,7 +928,7 @@ static vector getFixedDimensionsVector(SgArrayRefExp* arrayRef) if (arrayRef->subscript(i)->variant() == INT_VAL) fixedDimensions[i] = true; -return fixedDimensions; + return fixedDimensions; } // sunparseFixedDimensionsVector unparses fixed dimensions vector as string @@ -807,6 +951,49 @@ 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; + } + + return true; +} + // getFixedDimensionsMask finds fixed dimensions vector with minimum number of fixed dimensions // and writes messages if array doesn't have fixed dimensions static vector getFixedDimensionsMask(Context* ctx) @@ -927,16 +1114,15 @@ static vector> checkImplicitDirectUsage(Context* ctx) SgCallStmt* callStmt = (SgCallStmt*)st; string procName = callStmt->name()->identifier(); FuncInfo* funcInfo = findFunc(callStmt->fileName(), procName, ctx->allFuncInfo); - if (funcInfo == nullptr) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); for (int i = 0; i < callStmt->numberOfArgs(); ++i) { SgExpression* callArg = callStmt->arg(i); if (callArg->symbol() == nullptr || !isEqSymbols(callArg->symbol(), ctx->arraySymbol)) continue; - - if (funcInfo->funcParams.isArgOut(i) || // implicit direct usage + + if (funcInfo == nullptr || // no info about function + funcInfo->funcParams.isArgOut(i) || // implicit direct usage callArg->lhs() == nullptr) // reference to whole array { auto mask = getFixedSubscriptsVector((SgArrayRefExp*)callArg, ctx->dimensionsNum); @@ -1084,21 +1270,26 @@ static string getReducedArrayVarName(SgSymbol* symbol, const vector& subscr name.reserve(name.size() + subscripts.size() * 3); for (int i : subscripts) - name += "_" + std::to_string(i); + { + if (i < 0) + name += "_M" + std::to_string((-1) * i); + else + name += "_" + std::to_string(i); + } return name; } // getReducedArrayVars makes reduced array vars for arrayRefs -static ReducedArrayVars getReducedArrayVars(Context* ctx) +static ReducedArrayVarsMap getReducedArrayVars(Context* ctx) { - ReducedArrayVars reducedArrayVars; + ReducedArrayVarsMap reducedArrayVars; SgType* type = ctx->explicitArrayRefs[0]->type(); SgStatement* scope = ctx->loopStmt->getScopeForDeclare(); for (SgArrayRefExp* ref : ctx->explicitArrayRefs) { - vector subscripts = getShortFixedSubscriptsVector(ref, ctx->fixedDimensionsMask); + vector subscripts = getShortFixedSubscriptsVector(ref, ctx->fixedDimensionsMask, ctx->regime); if (reducedArrayVars.find(subscripts) == nullptr) { string name = getReducedArrayVarName(ref->symbol(), subscripts); @@ -1127,11 +1318,10 @@ static set getVarsToDependOn(SgForStmt* loopStmt, SgSymbol* var) } // getDefStmtForReducedArray returns DFE statement for reduced array variable -static InsertedStatement getDefStmtForReducedArray(SgArrayRefExp* arrayRef, - const vector& fixedDimensions, - const ReducedArrayVars& reducedArrayVars) +static InsertedStatement getDefStmtForReducedArray(Context* ctx, SgArrayRefExp* arrayRef, + const ReducedArrayVarsMap& reducedArrayVars) { - vector subscriptVector = getShortFixedSubscriptsVector(arrayRef, fixedDimensions); + vector subscriptVector = getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime); SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector); if (reducedVar == nullptr) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); @@ -1145,12 +1335,11 @@ static InsertedStatement getDefStmtForReducedArray(SgArrayRefExp* arrayRef, // getUseStmtForReducedArray returns USE statement for reduced array variable // (assignment to receiverVar) -static InsertedStatement getUseStmtForReducedArray(SgArrayRefExp* arrayRef, - const vector& fixedDimensions, - const ReducedArrayVars& reducedArrayVars, +static InsertedStatement getUseStmtForReducedArray(Context* ctx, SgArrayRefExp* arrayRef, + const ReducedArrayVarsMap& reducedArrayVars, SgSymbol* receiverVar) { - vector subscriptVector = getShortFixedSubscriptsVector(arrayRef, fixedDimensions); + vector subscriptVector = getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime); SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector); if (reducedVar == nullptr) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); @@ -1165,7 +1354,7 @@ static InsertedStatement getUseStmtForReducedArray(SgArrayRefExp* arrayRef, // insertReducedArrayVarStmts inserts in loop assignment statements with reduced vars, // returns vector of inserted statements static vector insertReducedArrayVarStmts(Context* ctx, - const ReducedArrayVars& reducedArrayVars, + const ReducedArrayVarsMap& reducedArrayVars, SgSymbol* receiverVar) { vector insertedStmts; @@ -1182,7 +1371,7 @@ static vector insertReducedArrayVarStmts(Context* ctx, { vector arrayRefs; fillDirectArrayRefs(st->expr(i), ctx->arraySymbol, arrayRefs); - arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask); + arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask, ctx->regime); if (!arrayRefs.empty()) isUseStmt = true; @@ -1191,7 +1380,7 @@ static vector insertReducedArrayVarStmts(Context* ctx, if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs)) continue; - InsertedStatement useStmt = getUseStmtForReducedArray(arrayRef, ctx->fixedDimensionsMask, + InsertedStatement useStmt = getUseStmtForReducedArray(ctx, arrayRef, reducedArrayVars, receiverVar); useStmt.relatedToStmt = st; st->insertStmtBefore(*useStmt.insertedStmt, *st->controlParent()); @@ -1204,8 +1393,8 @@ static vector insertReducedArrayVarStmts(Context* ctx, isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol) && // assignment to array - DEF stmt isArrayRefInVector((SgArrayRefExp*)st->expr(0), ctx->explicitArrayRefs)) { - InsertedStatement defStmt = getDefStmtForReducedArray((SgArrayRefExp*)st->expr(0), - ctx->fixedDimensionsMask, reducedArrayVars); + InsertedStatement defStmt = getDefStmtForReducedArray(ctx, (SgArrayRefExp*)st->expr(0), + reducedArrayVars); defStmt.relatedToStmt = st; defStmt.isRecursive = isUseStmt; st->insertStmtBefore(*defStmt.insertedStmt, *st->controlParent()); @@ -1233,6 +1422,7 @@ static vector buildDefUsePairs(Context* ctx, const CFG_Type& CF { vector defUsePairs; + string arrayName = ctx->arraySymbol->identifier(); for (const InsertedStatement& useInsertedStmt : insertedStmts) { if (useInsertedStmt.type != TypeOfInsertedStmt::USE) // analysis for USE stmt @@ -1248,7 +1438,7 @@ static vector buildDefUsePairs(Context* ctx, const CFG_Type& CF const auto& RD_forUseArg = RD_In.find(useArg); if (RD_forUseArg == RD_In.end()) // cannot find reaching definitions for argument { - addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); + addMessageCannotFindRD(ctx->messages, arrayName, useLineNum); continue; } @@ -1275,19 +1465,21 @@ static vector buildDefUsePairs(Context* ctx, const CFG_Type& CF if (RD_defArgs.size() == 0) // argument is not initialized { - addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); + addMessageCannotFindRD(ctx->messages, arrayName, useLineNum); continue; } - if (RD_defArgs.find(SAPFOR::CFG_VAL::UNINIT) != RD_defArgs.end()) // argument is not initialized - { - bool uninitArgIsOk = false; - if (RD_defArgs.size() == 2) - { - RD_defArgs.erase(SAPFOR::CFG_VAL::UNINIT); - int defArgNum = *RD_defArgs.begin(); + SgStatement* defStmt = nullptr; - auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArgNum); + if (RD_defArgs.size() > 1) + { + bool defIsFound = false; + for (int defArg : RD_defArgs) // try to find the real definition from RD_defArgs + { + if (defArg == SAPFOR::CFG_VAL::UNINIT) + continue; + + auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArg); if (defInsAndBlock.first == nullptr) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); @@ -1295,38 +1487,54 @@ static vector buildDefUsePairs(Context* ctx, const CFG_Type& CF if (defInsertedStmt->relatedToStmt->lineNumber() < useLineNum && useInsAndBlock.second->getNumber() == defInsAndBlock.second->getNumber()) { - uninitArgIsOk = true; // argument isn't really uninitialized + defIsFound = true; + auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArg); + defStmt = defInsAndBlock.first->getOperator(); + break; } } - - if (!uninitArgIsOk) + + if (!defIsFound) { - addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); + // try to find definition not from RD_defArgs: + string defVarName = useInsertedStmt.insertedStmt->expr(1)->symbol()->identifier(); + SgStatement* blockStart = useInsAndBlock.second->getInstructions().front()->getInstruction()->getOperator(); + SgStatement* blockEnd = useInsAndBlock.second->getInstructions().back()->getInstruction()->getOperator(); + for (SgStatement* st = blockStart; st != blockEnd; st = st->lexNext()) + { + if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol()->identifier() == defVarName && + !isVarChangedBetween(defVarName, st, useInsertedStmt.insertedStmt)) + { + defIsFound = true; + defStmt = st; + break; + } + } + } + + if (!defIsFound) + { + addMessageCannotFindRD(ctx->messages, arrayName, useLineNum); continue; } } - - if (RD_defArgs.size() > 1) // more than one reaching definition + else { - addMessageMoreThanOneRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); - continue; + auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, *RD_defArgs.begin()); + defStmt = defInsAndBlock.first->getOperator(); } - int defArgNum = *RD_defArgs.begin(); - - auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArgNum); - SgStatement* defStmt = defInsAndBlock.first->getOperator(); auto defInsertedStmt = findInsertedStmt(insertedStmts, defStmt); if (defInsertedStmt == insertedStmts.end()) { - addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); + addMessageCannotFindRD(ctx->messages, arrayName, useLineNum); continue; } //don't substitute def stmt into use, if def is recursive if (defInsertedStmt->isRecursive) { - addMessageRecursiveDependency(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); + addMessageRecursiveDependency(ctx->messages, arrayName, useLineNum); continue; } @@ -1347,18 +1555,6 @@ static SgForStmt* getScopeLoopStmt(SgStatement* stmt) return (SgForStmt*)stmt; } -static int getDimension(SgSymbol* arraySym) -{ - SgExpression* declExpr = arraySym->makeDeclExpr(); - if (declExpr == nullptr) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - int dimensionNum = ((SgExprListExp*)declExpr->lhs())->length(); - delete declExpr; - - return dimensionNum; -} - // findChildLoop returns LoopGraph for provided loop statement static LoopGraph* findLoop(LoopGraph* outerLoop, SgForStmt* loopStmt) { @@ -1489,20 +1685,6 @@ pair> findVarInRDSet(map return make_pair(nullptr, set{}); } -// 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); -} - // checkDefUsePair checks if def statement from pair can be substituted into use statement // and creates messages static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type& CFGraph) @@ -1547,6 +1729,10 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type if (defArg.second.size() != 1 || useArg.second.size() != 1 || *defArg.second.begin() != *useArg.second.begin()) { + if (defInsAndBlock.second->getNumber() == useInsAndBlock.second->getNumber()) + if (!isVarChangedBetween(var.first, defUse.first, defUse.second)) + continue; + addMessageDependOnNonInvariant(ctx->messages, arrayName, var.first, defUse.first->lineNumber()); return false; @@ -1656,6 +1842,54 @@ static set getPrivateArraysForLoop(LoopGraph* loop, const UsersDirect return privateArrays; } +void removePrivateAnalyze(Context *ctx) +{ + // inserting assignment to reduced array variables for getting reaching definitions analysis: + auto reducedArrayVars = getReducedArrayVars(ctx); + SgSymbol* receiverVar = makeTmpVar(ctx); + auto insertedStmts = insertReducedArrayVarStmts(ctx, reducedArrayVars, receiverVar); + + // declare reduced array variables and receiver: + insertedStmts.push_back(InsertedStatement( + TypeOfInsertedStmt::DECLARATION, + makeDeclaration(ctx->loopStmt, reducedArrayVars.getAllVars(), nullptr) + )); + insertedStmts.push_back(InsertedStatement( + TypeOfInsertedStmt::DECLARATION, + makeDeclaration(ctx->loopStmt, vector {receiverVar}, nullptr) + )); + + CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(ctx->loopStmt, + SAPFOR::CFG_Settings(true, true), + ctx->commonBlocks, ctx->allFuncInfo); + if (CFG_ForFunc.empty()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + auto defUseStmtsPairs = buildDefUsePairs(ctx, CFG_ForFunc, insertedStmts); + if (!defUseStmtsPairs.empty()) // DEF-USE pairs were build successfully + { + vector resultDefUsePairs; + for (auto& pair : defUseStmtsPairs) + if (checkDefUsePair(ctx, pair, CFG_ForFunc)) + resultDefUsePairs.push_back(pair); + + PrivateToRemove newPrivateToRemove; + newPrivateToRemove.loop = ctx->loop; + newPrivateToRemove.varSymbol = ctx->arraySymbol; + newPrivateToRemove.regime = ctx->regime; + newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs); + newPrivateToRemove.fixedDimensions.swap(ctx->fixedDimensionsMask); + + privatesToRemoveGlobal.push_back(newPrivateToRemove); + } + + // delete inserted statements: + for (auto& stmt : insertedStmts) + stmt.insertedStmt->deleteStmt(); + + deleteCFG(CFG_ForFunc); +} + void removePrivatesAnalysis(vector& loopGraphs, vector& messages, const UsersDirectives& usersDirectives, @@ -1704,9 +1938,10 @@ void removePrivatesAnalysis(vector& loopGraphs, break; Context context = Context{allFuncInfo, commonBlocks, messages}; + context.regime = Regime::DEFLT; context.loop = loop; context.loopStmt = loopStmt; - context.dimensionsNum = getDimension(arrayToRemove); + context.dimensionsNum = ((SgArrayType*)arrayToRemove->type())->dimension(); context.arraySymbol = arrayToRemove; auto filterMasks = checkImplicitAndIndirectUsage(&context); @@ -1718,57 +1953,23 @@ void removePrivatesAnalysis(vector& loopGraphs, context.fixedDimensionsMask = getFixedDimensionsMask(&context); - if (context.fixedDimensionsMask.empty() || - !checkFixedDimensionsMaskMatching(&context) || - !checkDefStmtRefsMatchesMask(&context)) + if (!context.fixedDimensionsMask.empty() && + checkFixedDimensionsMaskMatching(&context) && + checkDefStmtRefsMatchesMask(&context)) { - addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(), context.loop->lineNum); - continue; + removePrivateAnalyze(&context); } - - // inserting assignment to reduced array variables for getting reaching definitions analysis: - auto reducedArrayVars = getReducedArrayVars(&context); - SgSymbol* receiverVar = makeTmpVar(&context); - auto insertedStmts = insertReducedArrayVarStmts(&context, reducedArrayVars, receiverVar); - - // declare reduced array variables and receiver: - insertedStmts.push_back(InsertedStatement( - TypeOfInsertedStmt::DECLARATION, - makeDeclaration(context.loopStmt, reducedArrayVars.getAllVars(), nullptr) - )); - insertedStmts.push_back(InsertedStatement( - TypeOfInsertedStmt::DECLARATION, - makeDeclaration(context.loopStmt, vector {receiverVar}, nullptr) - )); - - CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(context.loopStmt, - SAPFOR::CFG_Settings(true, true), - commonBlocks, context.allFuncInfo); - if (CFG_ForFunc.empty()) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - auto defUseStmtsPairs = buildDefUsePairs(&context, CFG_ForFunc, insertedStmts); - if (!defUseStmtsPairs.empty()) // DEF-USE pairs were build successfully + else { - vector resultDefUsePairs; - for (auto& pair : defUseStmtsPairs) - if (checkDefUsePair(&context, pair, CFG_ForFunc)) - resultDefUsePairs.push_back(pair); - - PrivateToRemove newPrivateToRemove; - newPrivateToRemove.loop = context.loop; - newPrivateToRemove.varSymbol = context.arraySymbol; - newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs); - newPrivateToRemove.fixedDimensions.swap(context.fixedDimensionsMask); - - privatesToRemoveGlobal.push_back(newPrivateToRemove); + if (checkRegularIndexRefs(&context)) + { + context.regime = Regime::REGULAR_INDEXES; + context.fixedDimensionsMask = vector{}; + removePrivateAnalyze(&context); + } + else + addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(), context.loop->lineNum); } - - // delete inserted statements: - for (auto& stmt : insertedStmts) - stmt.insertedStmt->deleteStmt(); - - deleteCFG(CFG_ForFunc); } } diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h index 395375e..8ff66ef 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h @@ -5,12 +5,16 @@ #include "../CFGraph/CFGraph.h" #include "../CFGraph/RD_subst.h" +// Regime defines the regime of private removing +enum class Regime { DEFLT = 1, REGULAR_INDEXES }; + // PrivateToRemove represents private variable of loop, that can be removed // by substitution of its definition statements (DEF) into usage statements (USE). // fixedDimensions is used for comparison of DEF and USE statements struct PrivateToRemove { LoopGraph* loop; SgSymbol* varSymbol; + Regime regime; std::vector> defUseStmtsPairs; std::vector fixedDimensions; };