From 78a05d1a53373f1e2224a0c5925eb8e000ea60c8 Mon Sep 17 00:00:00 2001 From: Grigorii Gusev Date: Sun, 15 Oct 2023 15:27:54 +0300 Subject: [PATCH] private_removing: add check for indirect array usage + structural code changes --- .../_src/Transformations/private_removing.cpp | 727 ++++++++++++------ .../_src/Transformations/private_removing.h | 4 +- .../experts/Sapfor_2017/_src/Utils/errors.h | 3 +- .../_src/Utils/russian_errors_text.txt | 2 +- 4 files changed, 500 insertions(+), 236 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp index 69b8a2b..c5ab83f 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.cpp @@ -22,49 +22,84 @@ struct FixedSubscript { }; // DefUseStmtsPair represents pair of DEF and USE statements for private variable -using DefUseStmtsPair = pair; +using DefUseStmtsPair = pair; // privatesToRemoveGlobal stores the result of PRIVATE_REMOVING_ANALYSIS, // 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: * * ******************************* */ -// fillArrayReferences fill all var references of var in exp into refs -static void fillArrayReferences(SgExpression* exp, SgSymbol* arraySymbol, vector& refs) +// fillDirectArrayRefs fills all direct arraySym references in exp into refs +static void fillDirectArrayRefs(SgExpression* exp, SgSymbol* arraySym, vector& refs) { if (exp == nullptr) return; - if (exp->symbol() != nullptr) + if (exp->variant() == ARRAY_REF && exp->symbol() != nullptr && isEqSymbols(exp->symbol(), arraySym)) { - if (isEqSymbols(exp->symbol(), arraySymbol)) - refs.push_back((SgArrayRefExp*)exp); - + refs.push_back((SgArrayRefExp*)exp); return; } - fillArrayReferences(exp->lhs(), arraySymbol, refs); - fillArrayReferences(exp->rhs(), arraySymbol, refs); + fillDirectArrayRefs(exp->lhs(), arraySym, refs); + fillDirectArrayRefs(exp->rhs(), arraySym, refs); } -// getArrayReferences returns all array references of array in stmt -static vector getArrayReferences(SgStatement* stmt, SgSymbol* arraySymbol) +// getDirectArrayRefs returns all direct arraySym references in stmt, +// except VAR_DECL statements +static vector getDirectArrayRefs(SgStatement* stmt, SgSymbol* arraySym) { vector arrayRefs; - for (SgStatement* st = stmt; st != stmt->lastNodeOfStmt(); st = st->lexNext()) - for (int i = 0; i < 3; ++i) - fillArrayReferences(st->expr(i), arraySymbol, arrayRefs); + if (stmt == nullptr) + return arrayRefs; + + SgStatement* st = stmt; + while (true) + { + if (st->variant() != VAR_DECL && st->variant() != VAR_DECL_90) // skip var declaration stmt + for (int i = 0; i < 3; ++i) + fillDirectArrayRefs(st->expr(i), arraySym, arrayRefs); + + if (st == stmt->lastNodeOfStmt()) + break; + else + st = st->lexNext(); + } return arrayRefs; } +static bool isArrayRefInVector(SgArrayRefExp* ref, const vector& arrayRefs) +{ + for (SgArrayRefExp* arrayRef : arrayRefs) + if (arrayRef->id() == ref->id()) + return true; + + return false; +} + // getShortFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef static vector getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, - const vector& fixedDimensions) + const vector& fixedDimensions) { vector subscriptsVector; for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) @@ -181,7 +216,7 @@ static void addMessageRecursiveDependency(vector& messages, string var varName.c_str(), lineNum); wstring messageE, messageR; - __spf_printToLongBuf(messageE, L"cannot remove private var '%s' - it has recursive dependency", + __spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - it has recursive dependency", to_wstring(varName).c_str()); __spf_printToLongBuf(messageR, R189, to_wstring(varName).c_str()); @@ -201,7 +236,7 @@ static void addMessageDependOnNonInvariant(vector& messages, string va messages.push_back(Messages(typeMessage::WARR, lineNum, messageR, messageE, 2017)); } -static void addMessageDoesNotMachMask(vector& messages, string varName, int loopLineNum) +static void addMessageDoesNotMatchMask(vector& messages, string varName, int loopLineNum) { __spf_print(1, "WARR: cannot remove private var '%s' in loop %d - it doesn't match any fixed dimensions mask\n", varName.c_str(), loopLineNum); @@ -214,17 +249,18 @@ static void addMessageDoesNotMachMask(vector& messages, string varName messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2016)); } -static void addMessageUsageInFunctionCall(vector& messages, string varName, int loopLineNum, int lineNum) +static void addMessageUsageInFunctionCall(vector& messages, string varName, + string funcName, int loopLineNum, int stmtLineNum) { - __spf_print(1, "WARR: cannot remove private var '%s' in loop %d - it is used in function call in line %d\n", - varName.c_str(), loopLineNum, lineNum); + __spf_print(1, "WARR: cannot remove private var '%s' in loop %d - it is used in the call of function '%s' in line %d\n", + varName.c_str(), loopLineNum, funcName.c_str(), stmtLineNum); wstring messageE, messageR; - __spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - it is used in function call in line %d", - to_wstring(varName).c_str(), lineNum); - __spf_printToLongBuf(messageR, R203, to_wstring(varName).c_str(), lineNum); + __spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - it is used in the call of function '%s'", + to_wstring(varName).c_str(), to_wstring(funcName).c_str()); + __spf_printToLongBuf(messageR, R203, to_wstring(varName).c_str(), to_wstring(funcName).c_str()); - messages.push_back(Messages(typeMessage::WARR, lineNum, messageR, messageE, 2025)); + messages.push_back(Messages(typeMessage::WARR, stmtLineNum, messageR, messageE, 2025)); } /* ****************************************** * @@ -241,13 +277,12 @@ static string getDimensionVarName(SgSymbol* var, const vector& subscripts, const vector& fixedDimensions) { string result = var->identifier(); - int currentDim = 0; result += "("; for (int i = 0; i < fixedDimensions.size(); ++i) { if (fixedDimensions[i]) - result += std::to_string(subscripts[currentDim]); + result += std::to_string(subscripts[i]); else result += "*"; @@ -259,6 +294,27 @@ static string getDimensionVarName(SgSymbol* var, const vector& subscripts, return result; } +// getDimensionVarName returns var name in style A(1, 2, *) +static string getDimensionVarName(SgSymbol* var, const vector& fixedSubscripts) +{ + string result = var->identifier(); + + result += "("; + for (int i = 0; i < fixedSubscripts.size(); ++i) + { + if (fixedSubscripts[i].isFixed) + result += std::to_string(fixedSubscripts[i].value); + else + result += "*"; + + if (i != fixedSubscripts.size() - 1) + result += ", "; + } + result += ")"; + + return result; +} + // findExpByVar returns expression related to var in varToExpMap static SgExpression* findExpByVar(SgSymbol* var, const map& varToExpMap) { @@ -316,7 +372,7 @@ static SgExpression* substituteExpressions(SgExpression* exp, static bool isVarReadInLoop(SgSymbol* var, SgForStmt* loopStmt) { - for (SgStatement* st = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) + for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) { int i = 0; if (st->variant() == ASSIGN_STAT && isEqSymbols(st->expr(0)->symbol(), var)) @@ -343,7 +399,7 @@ static void removeDeadCodeFromLoop(LoopGraph* loop) privates.insert(OriginalSymbol((SgSymbol*)symbol)->identifier()); vector stmtsToDelete; - for (SgStatement* st = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) + for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) { if (st->variant() != ASSIGN_STAT) continue; @@ -373,7 +429,7 @@ static void fillReadShortFixedSumscripts(SgExpression* exp, const PrivateToRemov if (exp->symbol() != nullptr) { - if (isEqSymbols(exp->symbol(), var.var)) + if (isEqSymbols(exp->symbol(), var.varSymbol)) { auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var.fixedDimensions); fixedSubscripts.insert(subscripts); @@ -391,10 +447,10 @@ static void fillReadShortFixedSumscripts(SgExpression* exp, const PrivateToRemov static set> getReadShortFixedSumscripts(const PrivateToRemove& var, SgForStmt* loopStmt) { set> fixedSubscripts; - for (SgStatement* st = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) + for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) { int i = 0; - if (st->variant() == ASSIGN_STAT && isEqSymbols(st->expr(0)->symbol(), var.var)) + if (st->variant() == ASSIGN_STAT && isEqSymbols(st->expr(0)->symbol(), var.varSymbol)) i = 1; for (; i < 3; ++i) @@ -412,12 +468,12 @@ static void removeExcessiveDefs(const PrivateToRemove& var) set> usedFixedSubscripts = getReadShortFixedSumscripts(var, loopStmt); vector stmtsToRemove; - for (SgStatement* st = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) + for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) { if (st->variant() != ASSIGN_STAT) continue; - if (st->expr(0)->symbol() == nullptr || !isEqSymbols(st->expr(0)->symbol(), var.var)) + if (st->expr(0)->symbol() == nullptr || !isEqSymbols(st->expr(0)->symbol(), var.varSymbol)) continue; auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var.fixedDimensions); @@ -508,44 +564,54 @@ static map getVarToExpMap(SgArrayRefExp* defRef, SgArr // removeArray removes array by substituting it in DEF-USE pairs. // Returns set of removed fixed subscripts -static set> removeArray(string filename, const PrivateToRemove& varToRemove) +static set> removeArray(string filename, const PrivateToRemove& arrayToRemove) { set> removedFixedSubscripts; - auto& fixedDimensions = varToRemove.fixedDimensions; - for (auto& defUsePair : varToRemove.defUseStmtsPairs) + auto& fixedDimensions = arrayToRemove.fixedDimensions; + for (auto& defUsePair : arrayToRemove.defUseStmtsPairs) { map refToExpMap; SgAssignStmt* defStmt = defUsePair.first; - SgAssignStmt* useStmt = defUsePair.second; + SgStatement* useStmt = defUsePair.second; SgArrayRefExp* defRef = (SgArrayRefExp*)defStmt->lhs(); vector defFixedSubscripts = getShortFixedSubscriptsVector(defRef, fixedDimensions); - vector arrayUseRefs; - fillArrayReferences(useStmt->rhs(), defRef->symbol(), arrayUseRefs); - for (SgArrayRefExp* useRef : arrayUseRefs) + int startIndex = 0; + if (useStmt->variant() == ASSIGN_STAT) + startIndex = 1; + + for (int i = startIndex; i < 3; ++i) { - vector useFixedSubscripts = getShortFixedSubscriptsVector(useRef, fixedDimensions); - if (defFixedSubscripts != useFixedSubscripts) - continue; // because useRef and defRef can be different in subscripts of fixed dimensions + vector arrayUseRefs; + fillDirectArrayRefs(useStmt->expr(i), arrayToRemove.varSymbol, arrayUseRefs); + if (arrayUseRefs.empty()) + continue; - removedFixedSubscripts.insert(useFixedSubscripts); + for (SgArrayRefExp* useRef : arrayUseRefs) + { + vector useFixedSubscripts = getShortFixedSubscriptsVector(useRef, fixedDimensions); + if (defFixedSubscripts != useFixedSubscripts) + continue; // because useRef and defRef can be different in subscripts of fixed dimensions - auto varToExpMap = getVarToExpMap(defRef, useRef, fixedDimensions); + removedFixedSubscripts.insert(useFixedSubscripts); - SgExpression* expToSubst = defStmt->rhs()->copyPtr(); - expToSubst = replaceVarsWithExps(expToSubst, varToExpMap); + auto varToExpMap = getVarToExpMap(defRef, useRef, fixedDimensions); - refToExpMap.insert(make_pair(useRef->unparse(), expToSubst)); + SgExpression* expToSubst = defStmt->rhs()->copyPtr(); + expToSubst = replaceVarsWithExps(expToSubst, varToExpMap); + + refToExpMap.insert(make_pair(useRef->unparse(), expToSubst)); + } + + SgExpression* substExp = substituteExpressions(useStmt->expr(i), refToExpMap); + useStmt->setExpression(i, *substExp); + + // don't revert substitutions in useStmt: + cancelRevertionForStatement(filename, useStmt, i); } - - SgExpression* substExp = substituteExpressions(useStmt->rhs(), refToExpMap); - useStmt->replaceRhs(*substExp); - - // don't revert substitutions in useStmt: - cancelRevertionForStatement(filename, useStmt, 1); } return removedFixedSubscripts; @@ -566,13 +632,13 @@ void removePrivates(SgFile* file, vector& messages, int& countOfTransf removeEmptyLoops(varToRemove.loop, messages); SgForStmt* loopStmt = (SgForStmt*)varToRemove.loop->loop->GetOriginal(); - vector varRefs = getArrayReferences(loopStmt, varToRemove.var); + vector varRefs = getDirectArrayRefs(loopStmt, varToRemove.varSymbol); int loopLineNum = varToRemove.loop->lineNum; - string varName = varToRemove.var->identifier(); + string varName = varToRemove.varSymbol->identifier(); auto& fixedDimensions = varToRemove.fixedDimensions; if (varRefs.empty()) { - removeVarFromPrivateAttributes(varToRemove.var, varToRemove.loop); + removeVarFromPrivateAttributes(varToRemove.varSymbol, varToRemove.loop); addMessageRemovePrivateVar(messages, varName, loopLineNum); } else @@ -583,7 +649,7 @@ void removePrivates(SgFile* file, vector& messages, int& countOfTransf vector subscripts = getShortFixedSubscriptsVector(varRef, fixedDimensions); if (removedDimensions.find(subscripts) != removedDimensions.end()) { - varName = getDimensionVarName(varToRemove.var, subscripts, fixedDimensions); + varName = getDimensionVarName(varToRemove.varSymbol, subscripts, fixedDimensions); addMessageRemovePrivateVarPart(messages, varName, loopLineNum); } @@ -592,7 +658,7 @@ void removePrivates(SgFile* file, vector& messages, int& countOfTransf for (auto& removedDimension : removedDimensions) { - varName = getDimensionVarName(varToRemove.var, removedDimension, fixedDimensions); + varName = getDimensionVarName(varToRemove.varSymbol, removedDimension, fixedDimensions); addMessageRemovePrivateVar(messages, varName, loopLineNum); } } @@ -670,79 +736,36 @@ static vector::const_iterator findInsertedStmt(const vectorsymbol() != nullptr && (exp->variant() == FUNC_CALL || exp->variant() == PROC_CALL)) - return isSymbolInExpression(var, exp); - - return isVarUsedInFunctionCall(var, exp->lhs()) || isVarUsedInFunctionCall(var, exp->rhs()); -} - -// isArrayUsedInFunctionCall checks if arraySym is used in any function call in stmt (as argument) -// and writes message if true -static bool isArrayUsedInFunctionCall(SgSymbol* arraySym, SgStatement* stmt, vector& messages) -{ - for (SgStatement* st = stmt; st != stmt->lastNodeOfStmt(); st = st->lexNext()) - { - bool isUsed = false; - if (st->variant() == PROC_STAT) - for (int i = 0; i < 3; ++i) - if (isSymbolInExpression(arraySym, st->expr(i))) - isUsed = true; - - if (!isUsed) - for (int i = 0; i < 3; ++i) - if (isVarUsedInFunctionCall(arraySym, st->expr(i))) - isUsed = true; - - if (isUsed) - { - addMessageUsageInFunctionCall(messages, arraySym->identifier(), - stmt->lineNumber(), st->lineNumber()); - return true; - } - } - - return false; -} - // matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension -// and writes found mismatches to messages -static bool matchesFixedDimensionsMask(const vector& arrayRefs, - const vector& fixedDimensions) +static bool checkFixedDimensionsMaskMatching(Context* ctx) { - for (SgArrayRefExp* ref : arrayRefs) - for (int i = 0; i < fixedDimensions.size(); ++i) - if (fixedDimensions[i] && ref->subscript(i)->variant() != INT_VAL) + for (SgArrayRefExp* ref : ctx->explicitArrayRefs) + for (int i = 0; i < ctx->fixedDimensionsMask.size(); ++i) + if (ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() != INT_VAL) return false; return true; } -// defStmtRefsMatchesMask checks if all DEF array refs have INT_VAL value in fixed dimensions +// checkDefStmtRefsMatchesMask checks if all DEF array refs have INT_VAL value in fixed dimensions // and VAR_REF in non-fixed dimensions -static bool defStmtRefsMatchesMask(SgStatement* loopStmt, const vector& fixedDimensions, - SgSymbol* arraySym) +static bool checkDefStmtRefsMatchesMask(Context* ctx) { // TODO: , VAR_REF - // , a * i + b, i - for (SgStatement* st = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) + for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext()) { if (st->variant() != ASSIGN_STAT) continue; - if (isEqSymbols(st->expr(0)->symbol(), arraySym)) // DEF statement + if (isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol)) // DEF statement { SgArrayRefExp* ref = (SgArrayRefExp*)st->expr(0); - for (int i = 0; i < fixedDimensions.size(); ++i) + for (int i = 0; i < ctx->fixedDimensionsMask.size(); ++i) { - if (fixedDimensions[i] && ref->subscript(i)->variant() == INT_VAL) + if (ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == INT_VAL) continue; - if (!fixedDimensions[i] && ref->subscript(i)->variant() == VAR_REF) + if (!ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == VAR_REF) continue; return false; @@ -762,7 +785,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 @@ -787,34 +810,268 @@ static string sunparseFixedDimensionsVector(const vector& fixedDimensions) // getFixedDimensionsMask finds fixed dimensions vector with minimum number of fixed dimensions // and writes messages if array doesn't have fixed dimensions -static vector getFixedDimensionsMask(const vector& arrayRefs, - vector& messages, int loopLineNum) +static vector getFixedDimensionsMask(Context* ctx) { - int numberOfDimensions = arrayRefs[0]->numberOfSubscripts(); - if (numberOfDimensions == 0) // invalid array reference - return vector{}; - - for (const auto arrayRef : arrayRefs) - if (arrayRef->numberOfSubscripts() != numberOfDimensions) // invalid array reference - return vector{}; - - vector resultMask(numberOfDimensions, true); - for (const auto arrayRef : arrayRefs) + vector resultMask(ctx->dimensionsNum, true); + for (const auto arrayRef : ctx->explicitArrayRefs) { vector fixedDimensions = getFixedDimensionsVector(arrayRef); - for (int i = 0; i < numberOfDimensions; ++i) + for (int i = 0; i < ctx->dimensionsNum; ++i) resultMask[i] = resultMask[i] && fixedDimensions[i]; } - const char* arrayIdent = arrayRefs[0]->symbol()->identifier(); - string unparsedFixedDimensions = sunparseFixedDimensionsVector(resultMask); __spf_print(1, "NOTE: found fixed subsripts mask %s for array '%s' in loop %d\n", - unparsedFixedDimensions.c_str(), arrayIdent, loopLineNum); + unparsedFixedDimensions.c_str(), ctx->arraySymbol->identifier(), ctx->loop->lineNum); return resultMask; } +// getFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef +// true - subscript is fixed, false - it isn't +static vector getFixedSubscriptsVector(SgArrayRefExp* arrayRef, int dimensionsNum = 0) +{ + if (arrayRef->numberOfSubscripts() == 0) + return vector(dimensionsNum); + + vector subscriptsVector; + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) + { + if (arrayRef->subscript(i)->variant() == INT_VAL) + subscriptsVector.push_back(FixedSubscript{ true, arrayRef->subscript(i)->valueInteger() }); + else + subscriptsVector.push_back(FixedSubscript{ false, 0 }); + } + + return subscriptsVector; +} + +static FuncInfo* findFunc(string fileName, string funcName, const map>& allFuncInfo) +{ + auto fileInfo = allFuncInfo.find(fileName); + if (fileInfo == allFuncInfo.end()) + return nullptr; + + for (auto funcInfo : fileInfo->second) + if (funcInfo->funcName == funcName) + return funcInfo; + + return nullptr; +} + +static FuncInfo* getCurrectFunc(SgStatement* stmt, const map>& allFuncInfo) +{ + auto fileInfo = allFuncInfo.find(stmt->fileName()); + if (fileInfo == allFuncInfo.end()) + return nullptr; + + int stmtLine = stmt->lineNumber(); + for (auto funcInfo : fileInfo->second) + if (funcInfo->linesNum.first <= stmtLine && stmtLine <= funcInfo->linesNum.second) + return funcInfo; + + return nullptr; +} + +// checkImplicitDirectUsage returns masks of array implicit usage (as out argument) +// in any function call in exp and writes message about each usage +static void checkImplicitDirectUsage(Context* ctx, SgExpression* exp, int stmtLineNum, + vector>& fixedSubscripts) +{ + if (exp == nullptr) + return; + + if (exp->variant() == FUNC_CALL) + { + SgFunctionCallExp* funcCallExp = (SgFunctionCallExp*)exp; + string funcName = funcCallExp->funName()->identifier(); + auto funcInfo = findFunc(ctx->loopStmt->fileName(), funcName, ctx->allFuncInfo); + for (int i = 0; i < funcCallExp->numberOfArgs(); ++i) + { + SgExpression* funcArg = funcCallExp->arg(i); + if (funcInfo->funcParams.isArgOut(i) + && funcArg->symbol() != nullptr + && isEqSymbols(funcArg->symbol(), ctx->arraySymbol)) + { + auto fixedVec = getFixedSubscriptsVector((SgArrayRefExp*)funcArg, ctx->dimensionsNum); + fixedSubscripts.push_back(fixedVec); + addMessageUsageInFunctionCall(ctx->messages, getDimensionVarName(ctx->arraySymbol, fixedVec), + funcName, ctx->loop->lineNum, stmtLineNum); + } + } + } + + checkImplicitDirectUsage(ctx, exp->lhs(), stmtLineNum, fixedSubscripts); + checkImplicitDirectUsage(ctx, exp->rhs(), stmtLineNum, fixedSubscripts); +} + +// checkImplicitDirectUsage returns masks of array implicit usage (as out argument) +// and reference to whole array (like fcall(A, 1)) in any function call in loop +// and writes message about each usage +static vector> checkImplicitDirectUsage(Context* ctx) +{ + vector> fixedSubscripts; + for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext()) + { + if (st->variant() != PROC_STAT) + { + for (int i = 0; i < 3; ++i) + checkImplicitDirectUsage(ctx, st->expr(i), st->lineNumber(), fixedSubscripts); + + continue; + } + + // st->variant() == PROC_STAT: + 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 + callArg->lhs() == nullptr) // reference to whole array + { + auto& mask = getFixedSubscriptsVector((SgArrayRefExp*)callArg, ctx->dimensionsNum); + fixedSubscripts.push_back(mask); + addMessageUsageInFunctionCall(ctx->messages, getDimensionVarName(ctx->arraySymbol, mask), + procName, ctx->loop->lineNum, st->lineNumber()); + } + } + } + + return fixedSubscripts; +} + +static vector getCommonBlockGroupedVar(FuncInfo* curFunc, SgSymbol* varSymbol, + const map& commonBlocks) +{ + for (auto& block : commonBlocks) + { + for (auto& groupedVar : block.second->getGroupedVars()) + { + for (Variable* var : groupedVar.second) + { + for (const CommonVariableUse& varUse : var->getAllUse()) + { + + if (varUse.getFileName() == curFunc->fileName && + varUse.getFunctionName() == curFunc->funcName && + isEqSymbols(varUse.getUseS(), varSymbol)) + { + return groupedVar.second; + } + } + } + } + } + + return vector{}; +} + +// checkIndirectUsage returns masks of array indirect usage in function +// (indirect usage is usage through common blocks) and writes messages about it +static void checkIndirectUsage(Context* ctx, FuncInfo* curFunc, vector commonBlockGroupedVar, + set& visitedFuncs, vector>& indirectUsageMasks) +{ + if (visitedFuncs.find(curFunc->funcName) != visitedFuncs.end()) + return; + + visitedFuncs.insert(curFunc->funcName); + + for (Variable* commonBlockVar : commonBlockGroupedVar) + { + for (const CommonVariableUse& varUse : commonBlockVar->getAllUse()) + { + if (varUse.getFileName() != curFunc->fileName || varUse.getFunctionName() != curFunc->funcName) + continue; + + vector directArrayRefs = getDirectArrayRefs(varUse.getFunction(), varUse.getUseS()); + for (auto arrayRef : directArrayRefs) + { + auto& mask = getFixedSubscriptsVector(arrayRef, ctx->dimensionsNum); + indirectUsageMasks.push_back(mask); + addMessageUsageInFunctionCall(ctx->messages, getDimensionVarName(ctx->arraySymbol, mask), + curFunc->funcName, ctx->loop->lineNum, ctx->loop->lineNum); + } + } + } + + for (FuncInfo* calledFunc : curFunc->callsFromV) + checkIndirectUsage(ctx, calledFunc, commonBlockGroupedVar, visitedFuncs, indirectUsageMasks); +} + +// checkIndirectUsage returns masks of array indirect usage in any function call in loop +// (indirect usage is usage through common blocks) and writes messages about it +static vector> checkIndirectUsage(Context* ctx) +{ + vector> indirectUsageMasks; + FuncInfo* currentFunc = getCurrectFunc(ctx->loopStmt, ctx->allFuncInfo); + if (currentFunc == nullptr) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + vector commonBlockGroupedVar = getCommonBlockGroupedVar(currentFunc, ctx->arraySymbol, ctx->commonBlocks); + if (commonBlockGroupedVar.empty()) + return indirectUsageMasks; + + + set visitedFunctions = { currentFunc->funcName }; + for (FuncInfo* calledFunc : currentFunc->callsFromV) + checkIndirectUsage(ctx, calledFunc, commonBlockGroupedVar, visitedFunctions, indirectUsageMasks); + + return indirectUsageMasks; +} + +// checkImplicitAndIndirectUsage returns masks of implicit or indirect array usage in loop +static vector> checkImplicitAndIndirectUsage(Context* ctx) +{ + vector> implicitMasks = checkImplicitDirectUsage(ctx); + vector> indirectMasks = checkIndirectUsage(ctx); + + implicitMasks.insert(implicitMasks.end(), indirectMasks.begin(), indirectMasks.end()); + return implicitMasks; +} + +// filterArrayRefs removes from arrayRefs all refs that are not different from fixedVectors +static void filterArrayRefs(Context* ctx, vector& arrayRefs, + const vector>& masks) +{ + if (masks.empty()) + return; + + vector filteredArrayRefs; + for (auto arrayRef : arrayRefs) + { + vector arrayRefVec = getFixedSubscriptsVector(arrayRef, ctx->dimensionsNum); + + bool isDifferent = false; + for (auto& mask : masks) + { + for (int i = 0; i < arrayRefVec.size(); i++) + { + if (arrayRefVec[i].isFixed && mask[i].isFixed && arrayRefVec[i].value != mask[i].value) + { + isDifferent = true; + break; + } + } + + if (isDifferent) + break; + } + + if (isDifferent) + filteredArrayRefs.push_back(arrayRef); + } + + arrayRefs.swap(filteredArrayRefs); +} + // getReducedArrayVarName returns name for new reduced array variable, // made by symbol and subscripts: arr, [1, 2] -> arr_1_2 static string getReducedArrayVarName(SgSymbol* symbol, const vector& subscripts) @@ -830,19 +1087,16 @@ static string getReducedArrayVarName(SgSymbol* symbol, const vector& subscr return name; } -// getReducedArrayVars makes reduced array variables for arrayRefs -static ReducedArrayVars getReducedArrayVars(const vector& arrayRefs, - const vector& fixedDimensions, - SgStatement* scope) +// getReducedArrayVars makes reduced array vars for arrayRefs +static ReducedArrayVars getReducedArrayVars(Context* ctx) { ReducedArrayVars reducedArrayVars; - if (arrayRefs.empty()) - return reducedArrayVars; - SgType* type = arrayRefs[0]->type(); - for (SgArrayRefExp* ref : arrayRefs) + SgType* type = ctx->explicitArrayRefs[0]->type(); + SgStatement* scope = ctx->loopStmt->getScopeForDeclare(); + for (SgArrayRefExp* ref : ctx->explicitArrayRefs) { - vector subscripts = getShortFixedSubscriptsVector(ref, fixedDimensions); + vector subscripts = getShortFixedSubscriptsVector(ref, ctx->fixedDimensionsMask); if (reducedArrayVars.find(subscripts) == nullptr) { string name = getReducedArrayVarName(ref->symbol(), subscripts); @@ -863,7 +1117,7 @@ static ReducedArrayVars getReducedArrayVars(const vector& arrayR static set getVarsToDependOn(SgForStmt* loopStmt, SgSymbol* var) { set dependOn; - for (SgStatement* st = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) + for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) if (st->variant() == ASSIGN_STAT && isEqSymbols(st->expr(0)->symbol(), var)) getVariables(st->expr(1), dependOn, { VAR_REF, ARRAY_REF }); @@ -908,40 +1162,48 @@ static InsertedStatement getUseStmtForReducedArray(SgArrayRefExp* arrayRef, // insertReducedArrayVarStmts inserts in loop assignment statements with reduced vars, // returns vector of inserted statements -static vector insertReducedArrayVarStmts(SgForStmt* loopStmt, SgSymbol* arraySym, - const vector& fixedDimensions, +static vector insertReducedArrayVarStmts(Context* ctx, const ReducedArrayVars& reducedArrayVars, SgSymbol* receiverVar) { vector insertedStmts; - for (SgStatement* st = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) + for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext()) { - if (st->variant() != ASSIGN_STAT) - continue; - bool isUseStmt = false; - if (isSymbolInExpression(arraySym, st->expr(1))) // reading from array - USE - { - vector arrayRefs; - fillArrayReferences(st->expr(1), arraySym, arrayRefs); - arrayRefs = removeDuplicateArrayRefs(arrayRefs, fixedDimensions); - if (!arrayRefs.empty()) - isUseStmt = true; - for (SgArrayRefExp* arrayRef : arrayRefs) + int startIndex = 0; + if (st->variant() == ASSIGN_STAT) + startIndex = 1; + for (int i = startIndex; i < 3; ++i) + { + if (isSymbolInExpression(ctx->arraySymbol, st->expr(i))) // reading from array - USE stmt { - InsertedStatement useStmt = getUseStmtForReducedArray(arrayRef, fixedDimensions, - reducedArrayVars, receiverVar); - useStmt.relatedToStmt = st; - st->insertStmtBefore(*useStmt.insertedStmt, *st->controlParent()); - insertedStmts.push_back(useStmt); + vector arrayRefs; + fillDirectArrayRefs(st->expr(i), ctx->arraySymbol, arrayRefs); + arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask); + if (!arrayRefs.empty()) + isUseStmt = true; + + for (SgArrayRefExp* arrayRef : arrayRefs) + { + if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs)) + continue; + + InsertedStatement useStmt = getUseStmtForReducedArray(arrayRef, ctx->fixedDimensionsMask, + reducedArrayVars, receiverVar); + useStmt.relatedToStmt = st; + st->insertStmtBefore(*useStmt.insertedStmt, *st->controlParent()); + insertedStmts.push_back(useStmt); + } } } - if (isEqSymbols(st->expr(0)->symbol(), arraySym)) // assignment to array - DEF + if (st->variant() == ASSIGN_STAT && + 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), - fixedDimensions, reducedArrayVars); + ctx->fixedDimensionsMask, reducedArrayVars); defStmt.relatedToStmt = st; defStmt.isRecursive = isUseStmt; st->insertStmtBefore(*defStmt.insertedStmt, *st->controlParent()); @@ -952,21 +1214,20 @@ static vector insertReducedArrayVarStmts(SgForStmt* loopStmt, return insertedStmts; } -// makeTmpVar returns new var with provided type and name like tmp_N -static SgSymbol* makeTmpVar(SgType* type, SgStatement* scope) +// makeTmpVar returns new temporary var with name like tmp_N +static SgSymbol* makeTmpVar(Context* ctx) { + SgStatement* scope = ctx->loopStmt->getScopeForDeclare(); string varName = "tmp_"; int nameNumber = checkSymbNameAndCorrect(varName, 0); varName = "tmp_" + std::to_string(nameNumber); - return new SgSymbol(VARIABLE_NAME, varName.c_str(), type, scope); + return new SgSymbol(VARIABLE_NAME, varName.c_str(), ctx->explicitArrayRefs[0]->type(), scope); } // buildDefUsePairs builds pairs of DEF and USE statements for array -static vector buildDefUsePairs(const CFG_Type& CFGraph, - const vector& insertedStmts, - vector& messages, - SgSymbol* arrayToRemove) +static vector buildDefUsePairs(Context* ctx, const CFG_Type& CFGraph, + const vector& insertedStmts) { vector defUsePairs; @@ -985,7 +1246,7 @@ static vector buildDefUsePairs(const CFG_Type& CFGraph, const auto& RD_forUseArg = RD_In.find(useArg); if (RD_forUseArg == RD_In.end()) // cannot find reaching definitions for argument { - addMessageCannotFindRD(messages, arrayToRemove->identifier(), relLineNum); + addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), relLineNum); continue; } @@ -1004,13 +1265,13 @@ static vector buildDefUsePairs(const CFG_Type& CFGraph, if (RD_defArgs.size() == 0) // argument is not initialized { - addMessageCannotFindRD(messages, arrayToRemove->identifier(), relLineNum); + addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), relLineNum); continue; } if (RD_defArgs.size() > 1) // more than one reaching definition { - addMessageMoreThanOneRD(messages, arrayToRemove->identifier(), relLineNum); + addMessageMoreThanOneRD(ctx->messages, ctx->arraySymbol->identifier(), relLineNum); continue; } @@ -1021,14 +1282,14 @@ static vector buildDefUsePairs(const CFG_Type& CFGraph, auto defInsertedStmt = findInsertedStmt(insertedStmts, defStmt); if (defInsertedStmt == insertedStmts.end()) { - addMessageCannotFindRD(messages, arrayToRemove->identifier(), relLineNum); + addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), relLineNum); continue; } //don't substitute def stmt into use, if def is recursive if (defInsertedStmt->isRecursive) { - addMessageRecursiveDependency(messages, arrayToRemove->identifier(), relLineNum); + addMessageRecursiveDependency(ctx->messages, ctx->arraySymbol->identifier(), relLineNum); continue; } @@ -1049,6 +1310,20 @@ static SgForStmt* getScopeLoopStmt(SgStatement* stmt) return (SgForStmt*)stmt; } +static int getDimension(SgSymbol* arraySym) +{ + SgStatement* declarationStmt = arraySym->declaredInStmt(); + if (declarationStmt == nullptr) + return 0; + + SgExprListExp* expList = (SgExprListExp*)declarationStmt->expr(0); + for (int i = 0; i < expList->length(); ++i) + if (expList->elem(i)->symbol()->identifier() == arraySym->identifier()) + return ((SgExprListExp*)expList->elem(i)->lhs())->length(); + + return 0; +} + // findChildLoop returns LoopGraph for provided loop statement static LoopGraph* findLoop(LoopGraph* outerLoop, SgForStmt* loopStmt) { @@ -1110,22 +1385,6 @@ static LoopGraph* leastCommonAncestor(LoopGraph* a, LoopGraph* b, LoopGraph* par return a; } -// getFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef -// true - subscript is fixed, false - it isn't -static vector getFixedSubscriptsVector(SgArrayRefExp* arrayRef) -{ - vector subscriptsVector; - for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) - { - if (arrayRef->subscript(i)->variant() == INT_VAL) - subscriptsVector.push_back(FixedSubscript{ true, arrayRef->subscript(i)->valueInteger() }); - else - subscriptsVector.push_back(FixedSubscript{ false, 0 }); - } - - return subscriptsVector; -} - // fillFullFixedSubscriptsVectorsOfAllVars return vector of pairs (name of var, its fixed subscripts vector) // of all VAR_REF and ARRAY_REF vars in exp static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp, @@ -1211,21 +1470,19 @@ static void fillIterationVars(SgStatement *stmt, SgStatement* outerLoopStmt, set // checkDefUsePair checks if def statement from pair can be substituted into use statement // and creates messages -static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_Type& CFGraph, - const vector& fixedDimensions, vector& messages) +static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type& CFGraph) { if (defUse.first->lineNumber() > defUse.second->lineNumber()) return false; - vector>> dependOnVars; + string arrayName = ctx->arraySymbol->identifier(); + vector>> dependOnVars; SgArrayRefExp* defRef = (SgArrayRefExp*)defUse.first->expr(0); - string varToRemoveName = defRef->symbol()->identifier(); - vector arrayUseRefs; - fillArrayReferences(defUse.second->rhs(), defRef->symbol(), arrayUseRefs); + vector arrayUseRefs = getDirectArrayRefs(defUse.second, ctx->arraySymbol); for (auto useRef : arrayUseRefs) { - map varToExpMap = getVarToExpMap(defRef, useRef, fixedDimensions); + map varToExpMap = getVarToExpMap(defRef, useRef, ctx->fixedDimensionsMask); SgExpression* expToSubst = defUse.first->rhs()->copyPtr(); expToSubst = replaceVarsWithExps(expToSubst, varToExpMap); @@ -1233,7 +1490,7 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T } set iterationVars{}; - fillIterationVars(defUse.second, loop->loop->GetOriginal(), iterationVars); + fillIterationVars(defUse.second, ctx->loopStmt, iterationVars); auto defInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.first); const auto& defRD_In = defInsAndBlock.second->getRD_In(); @@ -1255,7 +1512,7 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T if (defArg.second.size() != 1 || useArg.second.size() != 1 || *defArg.second.begin() != *useArg.second.begin()) { - addMessageDependOnNonInvariant(messages, varToRemoveName, + addMessageDependOnNonInvariant(ctx->messages, arrayName, var.first, defUse.first->lineNumber()); return false; } @@ -1279,6 +1536,7 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T auto defLoopStmt = getScopeLoopStmt(defUse.first); auto useLoopStmt = getScopeLoopStmt(defUse.second); + LoopGraph* loop = ctx->loop; while (loop->perfectLoop != 1) // (what is it? - ) loop = loop->children[0]; @@ -1329,7 +1587,7 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T { if (st->variant() == ASSIGN_STAT && !isDifferentRefs(st->expr(0), var)) { - addMessageDependOnNonInvariant(messages, varToRemoveName, + addMessageDependOnNonInvariant(ctx->messages, arrayName, var.first, defUse.first->lineNumber()); return false; } @@ -1340,9 +1598,9 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T } // getPrivateArraysFromUserDirs returns private arrays from user directives ANALYSIS PRIVATE -static vector getPrivateArraysForLoop(LoopGraph* loop, const UsersDirectives& dirs) +static set getPrivateArraysForLoop(LoopGraph* loop, const UsersDirectives& dirs) { - vector privateArrays; + set privateArrays; auto loopDirectives = dirs.find(make_pair(loop->fileName.c_str(), loop->lineNum)); if (loopDirectives == dirs.end()) // no directives for loop @@ -1358,7 +1616,7 @@ static vector getPrivateArraysForLoop(LoopGraph* loop, const UsersDir for (Symbol* var : privateVars) if (var->type()->variant() == T_ARRAY) - privateArrays.push_back(var->GetOriginal()); + privateArrays.insert(var->GetOriginal()); return privateArrays; } @@ -1375,23 +1633,19 @@ void removePrivatesAnalysis(vector& loopGraphs, continue; SgForStmt* loopStmt = (SgForStmt*)loop->loop->GetOriginal(); - vector privateArrays = getPrivateArraysForLoop(loop, usersDirectives); + set privateArrays = getPrivateArraysForLoop(loop, usersDirectives); if (privateArrays.empty()) continue; - set arraysToCheck; - for (SgSymbol* privateArray : privateArrays) - arraysToCheck.insert(privateArray); - while (true) { SgSymbol* arrayToRemove = nullptr; vector arrayRefs; // choose arrayToRemove: - for (SgSymbol* arrayToCheck : arraysToCheck) + for (SgSymbol* arrayToCheck : privateArrays) { - arrayRefs = getArrayReferences(loopStmt, arrayToCheck); + arrayRefs = getDirectArrayRefs(loopStmt, arrayToCheck); if (arrayRefs.empty()) // no references to array continue; @@ -1399,14 +1653,14 @@ void removePrivatesAnalysis(vector& loopGraphs, bool skip = false; for (string dependOnVar : dependOnVars) - for (SgSymbol* notChecked : arraysToCheck) + for (SgSymbol* notChecked : privateArrays) if (dependOnVar == notChecked->identifier() && !isEqSymbols(arrayToCheck, notChecked)) skip = true; if (skip) // check this array again later continue; - arraysToCheck.erase(arrayToCheck); + privateArrays.erase(arrayToCheck); arrayToRemove = arrayToCheck; break; // arrayToRemove is chosen } @@ -1414,54 +1668,63 @@ void removePrivatesAnalysis(vector& loopGraphs, if (arrayToRemove == nullptr) // no array to remove break; - if (isArrayUsedInFunctionCall(arrayToRemove, loopStmt, messages)) + Context context = Context{allFuncInfo, commonBlocks, messages}; + context.loop = loop; + context.loopStmt = loopStmt; + context.dimensionsNum = getDimension(arrayToRemove); + context.arraySymbol = arrayToRemove; + + auto& filterMasks = checkImplicitAndIndirectUsage(&context); + filterArrayRefs(&context, arrayRefs, filterMasks); + context.explicitArrayRefs.swap(arrayRefs); + + if (context.explicitArrayRefs.empty()) continue; - vector fixedDimensionsMask = getFixedDimensionsMask(arrayRefs, messages, loop->lineNum); - if (fixedDimensionsMask.empty() || - !matchesFixedDimensionsMask(arrayRefs, fixedDimensionsMask) || - !defStmtRefsMatchesMask(loopStmt, fixedDimensionsMask, arrayToRemove)) + context.fixedDimensionsMask = getFixedDimensionsMask(&context); + + if (context.fixedDimensionsMask.empty() || + !checkFixedDimensionsMaskMatching(&context) || + !checkDefStmtRefsMatchesMask(&context)) { - addMessageDoesNotMachMask(messages, arrayToRemove->identifier(), loop->lineNum); + addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(), context.loop->lineNum); continue; } - arrayRefs = removeDuplicateArrayRefs(arrayRefs, fixedDimensionsMask); - // inserting assignment to reduced array variables for getting reaching definitions analysis: - SgStatement* scope = loopStmt->getScopeForDeclare(); - auto reducedArrayVars = getReducedArrayVars(arrayRefs, fixedDimensionsMask, scope); - SgSymbol* receiverVar = makeTmpVar(arrayRefs[0]->type(), scope); - auto insertedStmts = insertReducedArrayVarStmts(loopStmt, arrayToRemove, fixedDimensionsMask, - reducedArrayVars, receiverVar); + 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(loopStmt, reducedArrayVars.getAllVars(), nullptr) + makeDeclaration(context.loopStmt, reducedArrayVars.getAllVars(), nullptr) )); insertedStmts.push_back(InsertedStatement( TypeOfInsertedStmt::DECLARATION, - makeDeclaration(loopStmt, vector {receiverVar}, nullptr) + makeDeclaration(context.loopStmt, vector {receiverVar}, nullptr) )); - CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(loopStmt, SAPFOR::CFG_Settings(true, true), commonBlocks, allFuncInfo); + 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(CFG_ForFunc, insertedStmts, messages, arrayToRemove); + auto defUseStmtsPairs = buildDefUsePairs(&context, CFG_ForFunc, insertedStmts); if (!defUseStmtsPairs.empty()) // DEF-USE pairs were build successfully { vector resultDefUsePairs; for (auto& pair : defUseStmtsPairs) - if (checkDefUsePair(pair, loop, CFG_ForFunc, fixedDimensionsMask, messages)) + if (checkDefUsePair(&context, pair, CFG_ForFunc)) resultDefUsePairs.push_back(pair); PrivateToRemove newPrivateToRemove; - newPrivateToRemove.loop = loop; - newPrivateToRemove.var = arrayToRemove; + newPrivateToRemove.loop = context.loop; + newPrivateToRemove.varSymbol = context.arraySymbol; newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs); - newPrivateToRemove.fixedDimensions.swap(fixedDimensionsMask); + newPrivateToRemove.fixedDimensions.swap(context.fixedDimensionsMask); privatesToRemoveGlobal.push_back(newPrivateToRemove); } diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h index e2d1930..395375e 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/private_removing.h @@ -10,8 +10,8 @@ // fixedDimensions is used for comparison of DEF and USE statements struct PrivateToRemove { LoopGraph* loop; - SgSymbol* var; - std::vector> defUseStmtsPairs; + SgSymbol* varSymbol; + std::vector> defUseStmtsPairs; std::vector fixedDimensions; }; diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/errors.h b/sapfor/experts/Sapfor_2017/_src/Utils/errors.h index db929b3..85662ac 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/errors.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/errors.h @@ -101,6 +101,7 @@ enum typeMessage { WARR, ERROR, NOTE }; // 22 "cannot transform ..." // 23 "cannot transform ..." // 24 "loop on line %d was removed" +// 25 "Cannot remove private var '%s' - it is used in the call of function '%s'" // 30xx PARALLEL GROUP // 01 "add across dependencies by array '%s' to loop" @@ -531,7 +532,7 @@ static const wchar_t *R197 = L"R197:"; //2024 static const wchar_t *R198 = L"R198:%d"; //2025 -static const wchar_t *R203 = L"R203:%s%d"; +static const wchar_t *R203 = L"R203:%s%s"; //3001 static const wchar_t *R108 = L"R108:%s"; diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/russian_errors_text.txt b/sapfor/experts/Sapfor_2017/_src/Utils/russian_errors_text.txt index 967276f..671062c 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/russian_errors_text.txt +++ b/sapfor/experts/Sapfor_2017/_src/Utils/russian_errors_text.txt @@ -243,7 +243,7 @@ R197 = "Преобразование не может быть выполнено //2024 R198 = "Цикл на строке %d был удалён" //2025 -R203 = "Нельзя удалить приватную переменную '%s' - она используется в вызове функции на строке %d" +R203 = "Нельзя удалить приватную переменную '%s' - она используется в вызове функции %s" //3001 R108 = "Добавлена across-зависимость к массиву '%s' в цикле"