diff --git a/sapfor/experts/Sapfor_2017/CMakeLists.txt b/sapfor/experts/Sapfor_2017/CMakeLists.txt index 438cb1a..2a26a8a 100644 --- a/sapfor/experts/Sapfor_2017/CMakeLists.txt +++ b/sapfor/experts/Sapfor_2017/CMakeLists.txt @@ -257,6 +257,7 @@ set(DIRA _src/DirectiveProcessing/directive_analyzer.cpp _src/DirectiveProcessing/spf_directive_preproc.cpp) set(DISTR _src/Distribution/Array.cpp + _src/Distribution/ArrayAnalysis.cpp _src/Distribution/Array.h _src/Distribution/Arrays.h _src/Distribution/CreateDistributionDirs.cpp diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access.cpp b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access.cpp index 0510f48..67e35a1 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access.cpp +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access.cpp @@ -23,6 +23,7 @@ #include "../Utils/SgUtils.h" #include "../Distribution/Arrays.h" #include "../GraphCall/graph_calls.h" +#include "../GraphCall/graph_calls_func.h" #include "../GraphLoop/graph_loops_func.h" #include "remote_access.h" @@ -863,8 +864,16 @@ void addRemoteLink(const LoopGraph* loop, const map& funcMap, } } -ArrayRefExp* createRemoteLink(const DIST::Array* forArray) +ArrayRefExp* createRemoteLink(const LoopGraph* currLoop, const DIST::Array* forArray) { + SgFile* file = current_file; + + const set allFiles = getAllFilesInProject(); + SgStatement* realStat = (SgStatement*)currLoop->getRealStat(file->filename()); + const map> byUseInFunc = moduleRefsByUseInFunction(realStat); + SgStatement* parentFunc = getFuncStat(realStat); + const pair lineRange = make_pair(parentFunc->lineNumber(), parentFunc->lastNodeOfStmt()->lineNumber()); + SgExpression* ex = new SgExpression(EXPR_LIST); SgExpression* p = ex; for (int z = 0; z < forArray->GetDimSize(); ++z) @@ -880,21 +889,17 @@ ArrayRefExp* createRemoteLink(const DIST::Array* forArray) auto decls = forArray->GetDeclInfoWithSymb(); const string fName = current_file->filename(); - for (auto& decl : decls) + /*for (auto& decl : decls) { if (decl.first.first == fName) { newRem = new SgArrayRefExp(*decl.second->GetOriginal(), *ex); break; } - } + }*/ if (!newRem) - { - auto arrayT = new SgType(T_ARRAY); - auto tmpS = findSymbolOrCreate(current_file, forArray->GetShortName(), arrayT); - newRem = new SgArrayRefExp(*tmpS, *ex); - } + newRem = new SgArrayRefExp(*getFromModule(byUseInFunc, forArray->GetDeclSymbol(fName, lineRange, allFiles)->GetOriginal()), *ex); return new ArrayRefExp(newRem); } diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access.h b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access.h index 786602d..41d3dab 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access.h +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access.h @@ -29,7 +29,7 @@ void addRemoteLink(const LoopGraph* loop, const std::map const std::set& remotesInParallel, std::set& addedRemotes, const std::vector& mapToLoop, std::vector& messages, const int line, bool bindToLoopDistribution = true); -ArrayRefExp* createRemoteLink(const DIST::Array* forArray); +ArrayRefExp* createRemoteLink(const LoopGraph* currLoop, const DIST::Array* forArray); std::vector checkArrayRefInLoopForRemoteStatus(bool ifUnknownArrayAssignFound, diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access_base.cpp b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access_base.cpp index ac55b16..c81ddbf 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access_base.cpp +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/remote_access_base.cpp @@ -86,7 +86,7 @@ static void createRemoteInParallel(const pairGetShortName().c_str()); } } diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/shadow.cpp b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/shadow.cpp index a8bccba..aa895da 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/shadow.cpp +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/shadow.cpp @@ -309,7 +309,7 @@ static void replaceShadowByRemote(SgExpression *specInDir, SgStatement *stat, void devourShadowByRemote(void *file_, const map& funcMap, const vector& loops, const map> &arrayLinksByFuncCalls) -{ +{ SgFile* file = static_cast(file_); map loopByLine; createMapLoopGraph(loops, loopByLine); diff --git a/sapfor/experts/Sapfor_2017/_src/Distribution/Array.cpp b/sapfor/experts/Sapfor_2017/_src/Distribution/Array.cpp index 6b79697..4149bda 100644 --- a/sapfor/experts/Sapfor_2017/_src/Distribution/Array.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Distribution/Array.cpp @@ -122,7 +122,7 @@ namespace Distribution return retVal; } - void TemplateLink::AddRule(const int dimNum, int dimTempl, const pair &rule, Array *templateArray_) + void TemplateLink::AddRule(const int dimNum, int dimTempl, const pair& rule, Array* templateArray_) { linkWithTemplate[dimNum] = dimTempl; alignRuleWithTemplate[dimNum] = rule; @@ -132,7 +132,7 @@ namespace Distribution const vector>& Array::GetSizes() { if (templateDimsOrder.size() == 0) - return sizes; + return sizes; else { if (orderedSizes.size() == 0) @@ -141,7 +141,7 @@ namespace Distribution } } - const vector>, pair>>>& + const vector>, pair>>>& Array::GetSizesExpr() { if (templateDimsOrder.size() == 0) @@ -154,7 +154,7 @@ namespace Distribution } } - void printArrayInfo(const string &file, const map, pair> &declaredArrays) + void printArrayInfo(const string& file, const map, pair>& declaredArrays) { FILE* out = fopen(file.c_str(), "w"); if (out == NULL) @@ -180,7 +180,7 @@ namespace Distribution locN = "LOCAL (save) of "; else if (loc.first == l_STRUCT) locN = "STRUCT "; - else + else locN = "UNKN "; locN += "'" + loc.second + "'"; @@ -189,7 +189,7 @@ namespace Distribution { fprintf(out, " FOR FILE '%s':\n", convertFileName(byFile.first.c_str()).c_str()); for (auto& byLine : byFile.second) - for (auto &onLine : byLine.second) + for (auto& onLine : byLine.second) fprintf(out, " %s\n", onLine.PrintInfo().c_str()); } fprintf(out, "=============== \n\n"); @@ -198,8 +198,8 @@ namespace Distribution fclose(out); } - void fixTypeOfArrayInfoWithCallGraph(map, pair> &declaredArrays, - const map &allFuncs) + void fixTypeOfArrayInfoWithCallGraph(map, pair>& declaredArrays, + const map& allFuncs) { for (auto& elem : declaredArrays) { diff --git a/sapfor/experts/Sapfor_2017/_src/Distribution/ArrayAnalysis.cpp b/sapfor/experts/Sapfor_2017/_src/Distribution/ArrayAnalysis.cpp new file mode 100644 index 0000000..c56f3a4 --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/Distribution/ArrayAnalysis.cpp @@ -0,0 +1,766 @@ +#include "Array.h" +#include "../Utils/errors.h" +#include "../Utils/utils.h" +#include "../GraphCall/graph_calls.h" +#include "../Utils/SgUtils.h" +#include "../DirectiveProcessing/directive_parser.h" +#include "../DirectiveProcessing/directive_omp_parser.h" +#include "../LoopAnalyzer/loop_analyzer.h" + +using namespace std; + +extern int ignoreIO; +extern map> tableOfUniqNamesByArray; +static set> checkedArraysForWrongLocation; + +static bool findOmpThreadPrivDecl(SgStatement* st, map>& ompThreadPrivate, SgSymbol* toFind) +{ + + auto it = ompThreadPrivate.find(st); + if (it == ompThreadPrivate.end()) + { + it = ompThreadPrivate.insert(it, make_pair(st, set())); + + SgStatement* lastN = st->lastNodeOfStmt(); + set dummy; + do + { + st = st->lexNext(); + + auto res = parseOmpInStatement(st, dummy); + for (auto& dir : res) + for (auto& var : dir.threadPrivVars) + it->second.insert(var); + } while (st != lastN && !isSgExecutableStatement(st) && st->variant() != CONTAINS_STMT); + } + + if (it->second.find(toFind->identifier()) != it->second.end()) + return true; + else + return false; +} + +static bool hasAssingOpInDecl(SgSymbol* symb) +{ + vector allDecls; + SgStatement* decl = declaratedInStmt(symb, &allDecls); + + for (auto& elem : allDecls) + { + if (elem->variant() == VAR_DECL_90) + { + SgExpression* list = elem->expr(0); + while (list) + { + if (list->lhs()->variant() == ASSGN_OP) + if (list->lhs()->lhs()->symbol() && OriginalSymbol(list->lhs()->lhs()->symbol()) == symb) + return true; + list = list->rhs(); + } + } + } + + return false; +} + +static string getNameWithScope(SgStatement* scope, const string& currFunctionName) +{ + if (scope && isSgProgHedrStmt(scope) && scope->symbol()->identifier() != currFunctionName) + return scope->symbol()->identifier(); + else + return currFunctionName; +} + +struct findInfo +{ + findInfo(const string fName, SgExpression* ex, int parN, bool isWrite) : + fName(fName), ex(ex), parN(parN), isWrite(isWrite) + { } + + SgExpression* ex; + string fName; + int parN; + bool isWrite; +}; + +static void findArrayRefs (SgExpression* ex, SgStatement* st, string fName, int parN, bool isWrite, + const map>& commonBlocks, + map, pair>& declaredArrays, + map>>& declaratedArraysSt, + const set& privates, const set& deprecatedByIO, + bool isExecutable, const string& currFunctionName, + const vector& inRegion, + const set& funcParNames, + map>& ompThreadPrivate, + const map& distrStateFromGUI, + const bool saveAllLocals, + map>& currMessages, + int& errorCount) +{ + const string globalFile = current_file->filename(); + const set filesInProj = getAllFilesInProject(); + + if (ex == NULL) + return; + stack queue; + queue.push(findInfo(fName, ex, parN, isWrite)); + + while (!queue.empty()) + { + const findInfo& curQ = queue.top(); + ex = curQ.ex; + fName = curQ.fName; + parN = curQ.parN; + isWrite = curQ.isWrite; + + queue.pop(); + + if (isArrayRef(ex)) + { + SgSymbol* symb = OriginalSymbol(ex->symbol()); + const bool inDataStat = (symb->attributes() & DATA_BIT) != 0 || ((ex->symbol())->attributes() & DATA_BIT); + checkNull(symb->type(), convertFileName(__FILE__).c_str(), __LINE__); + + const int typeSize = getSizeOfType(symb->type()->baseType()); + if (typeSize == 0) + { + //__spf_print(1, "Wrong type size for array %s\n", symb->identifier()); + //printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + + SgStatement* decl = declaratedInStmt(symb); + if (decl->variant() == DVM_VAR_DECL || decl->variant() == HPF_TEMPLATE_STAT) + { + const string tmp(decl->unparse()); + if (tmp.find("!DVM$ TEMPLATE") != string::npos) + { + auto sTemp = symb->identifier(); + tuple uniqKey; + bool found = false; + for (auto& elem : declaredArrays) + { + if (elem.second.first->GetShortName() == sTemp) + { + uniqKey = elem.first; + found = true; + } + } + + if (found) + { + auto itDecl = declaratedArraysSt.find(decl); + if (itDecl == declaratedArraysSt.end()) + itDecl = declaratedArraysSt.insert(itDecl, make_pair(decl, set>())); + itDecl->second.insert(uniqKey); + + return; + } + } + } + + auto uniqKey = getUniqName(commonBlocks, decl, symb); + + SgStatement* scope = symb->scope(); + pair arrayLocation; + + string typePrefix = ""; + while (scope && scope->variant() == STRUCT_DECL) + { + if (typePrefix == "") + typePrefix = scope->symbol()->identifier(); + else + typePrefix += scope->symbol()->identifier() + string("::"); + scope = scope->controlParent(); + } + + if ((ex->symbol() && symb != ex->symbol()) || (scope && scope->variant() == MODULE_STMT)) + { + if (scope) + { + string modName = scope->symbol()->identifier(); + arrayLocation = make_pair(DIST::l_MODULE, (typePrefix == "") ? modName : modName + "::" + typePrefix); + } + else //TODO: find module name with another way + arrayLocation = make_pair(DIST::l_MODULE, "UNREC_MODULE_NAME"); + } + else if (get<1>(uniqKey).find("common_") != string::npos) + arrayLocation = make_pair(DIST::l_COMMON, get<1>(uniqKey).substr(strlen("common_"))); + else if (funcParNames.find(symb->identifier()) != funcParNames.end()) + arrayLocation = make_pair(DIST::l_PARAMETER, getNameWithScope(scope, currFunctionName)); + else + { + if (saveAllLocals || ((symb->attributes() & SAVE_BIT) != 0) || hasAssingOpInDecl(symb)) + arrayLocation = make_pair(DIST::l_LOCAL_SAVE, getNameWithScope(scope, currFunctionName)); + else + arrayLocation = make_pair(DIST::l_LOCAL, getNameWithScope(scope, currFunctionName)); + } + + auto itNew = declaredArrays.find(uniqKey); + if (itNew == declaredArrays.end()) + { + DIST::Array* arrayToAdd = + new DIST::Array(getShortName(uniqKey), symb->identifier(), ((SgArrayType*)(symb->type()))->dimension(), + getUniqArrayId(), decl->fileName(), decl->lineNumber(), arrayLocation, new Symbol(symb), + findOmpThreadPrivDecl(scope, ompThreadPrivate, symb), false, false, + inRegion, typeSize, sharedMemoryParallelization ? DIST::NO_DISTR : DIST::DISTR); + + itNew = declaredArrays.insert(itNew, make_pair(uniqKey, make_pair(arrayToAdd, new DIST::ArrayAccessInfo()))); + + vector> sizes; + map> arrayLinksByFuncCallsNotReady; + map> allFuncInfoNoReady; + auto sizesExpr = getArraySizes(sizes, symb, decl, arrayLinksByFuncCallsNotReady, allFuncInfoNoReady); + arrayToAdd->SetSizes(sizes); + arrayToAdd->SetSizesExpr(sizesExpr); + tableOfUniqNamesByArray[arrayToAdd] = uniqKey; + } + else // check the same location from include! + { + auto prevLocation = itNew->second.first->GetLocation(); + if (prevLocation != arrayLocation) + { + if (checkedArraysForWrongLocation.find(uniqKey) == checkedArraysForWrongLocation.end()) + { + checkedArraysForWrongLocation.insert(uniqKey); + __spf_print(1, "can not change declaration area of array '%s' on line %d\n", symb->identifier(), st->lineNumber()); + + wstring messageE, messageR; + __spf_printToLongBuf(messageE, L"Array '%s' has declaration area conflict, it might be worth applying the Include inlining pass", to_wstring(symb->identifier()).c_str()); + __spf_printToLongBuf(messageR, R184, to_wstring(symb->identifier()).c_str()); + + currMessages[st->fileName()].push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1061)); + } + errorCount++; + } + } + + if ((symb->attributes() & EQUIVALENCE_BIT) != 0) + itNew->second.first->SetEquvalence(true); + + for (auto& reg : inRegion) + itNew->second.first->SetRegionPlace(reg); + + const auto oldVal = itNew->second.first->GetDistributeFlagVal(); + bool isarrayInModule = (itNew->second.first->GetLocation().first == DIST::l_MODULE); + + if (oldVal == DIST::DISTR || oldVal == DIST::NO_DISTR) + { + if (itNew->second.first->IsOmpThreadPrivate()) + itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); + else if (privates.find(symb->identifier()) != privates.end() || isarrayInModule) + { + //check in module + if (itNew->second.first->GetLocation().first == DIST::l_MODULE) + { + for (auto& data : getAttributes(decl, set{ SPF_ANALYSIS_DIR })) + { + set privatesS; + fillPrivatesFromComment(new Statement(data), privatesS); + if (privatesS.find(symb->identifier()) != privatesS.end()) + { + itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); + break; + } + } + + auto prev = decl->lexPrev(); + checkNull(prev, convertFileName(__FILE__).c_str(), __LINE__); + + set privatesS; + fillPrivatesFromComment(new Statement(prev), privatesS); + if (privatesS.find(symb->identifier()) != privatesS.end()) + itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); + } + else + itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); + } + else if (deprecatedByIO.find(symb->identifier()) != deprecatedByIO.end()) + itNew->second.first->SetDistributeFlag(DIST::IO_PRIV); + else if (isSgConstantSymb(symb) || inDataStat) + itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); + else + { + auto it = distrStateFromGUI.find(itNew->second.first->GetIndepUniqName()); + if (it != distrStateFromGUI.end()) + { + if (it->second != oldVal) + { + itNew->second.first->SetDistributeFlag((DIST::distFlag)it->second); + __spf_print(1, "change flag for array from cache '%s': %d -> %d\n", it->first.c_str(), oldVal, it->second); + } + } + else + itNew->second.first->SetDistributeFlag(DIST::DISTR); + } + } + + if (typeSize == 0) // unknown + itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); + + + if (!isExecutable) + itNew->second.first->AddDeclInfo(make_pair(st->fileName(), st->lineNumber()), filesInProj, globalFile, new Symbol(symb)); + + if (isExecutable) + { + if (st->variant() != ALLOCATE_STMT && st->variant() != DEALLOCATE_STMT) + { + itNew->second.second->AddAccessInfo(st->fileName(), make_pair(st->lineNumber(), isWrite ? 1 : 0), fName, parN); + itNew->second.first->AddUsagePlace(st->fileName(), st->lineNumber()); + } + } + + auto itDecl = declaratedArraysSt.find(decl); + if (itDecl == declaratedArraysSt.end()) + itDecl = declaratedArraysSt.insert(itDecl, make_pair(decl, set>())); + itDecl->second.insert(uniqKey); + + if (decl->variant() == DVM_VAR_DECL || decl->variant() == HPF_TEMPLATE_STAT) + { + const string tmp(decl->unparse()); + if (tmp.find("!DVM$ TEMPLATE") != string::npos) + { + itNew->second.first->SetTemplateFlag(true); + //TODO: analyze align mapping + for (int z = 0; z < itNew->second.first->GetDimSize(); ++z) + itNew->second.first->SetMappedDim(z); + } + } + } + + if (ex->variant() == FUNC_CALL) + { + SgFunctionCallExp* funcExp = (SgFunctionCallExp*)ex; + const string fName = funcExp->funName()->identifier(); + bool intr = (isIntrinsicFunctionName(fName.c_str()) == 1); + for (int z = 0; z < funcExp->numberOfArgs(); ++z) + { + //assume all arguments of function as OUT, except for inctrinsics + bool isWriteN = intr ? false : true; + //need to correct W/R usage with GraphCall map later + findArrayRefs(funcExp->arg(z), st, fName, z, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount); + } + } + else + { + bool isWriteN = false; + if (ex->lhs()) + queue.push(findInfo("", ex->lhs(), -1, isWriteN)); + if (ex->rhs()) + queue.push(findInfo("", ex->rhs(), -1, isWriteN)); + //findArrayRefs(ex->lhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount); + //findArrayRefs(ex->rhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount); + } + } +} + +static void findArrayRefInIO(SgExpression* ex, set& deprecatedByIO, SgStatement* st, map>& currMessages) +{ + if (ex) + { + if (ex->variant() == ARRAY_REF) + { + auto symb = ex->symbol(); + if (symb->type()) + { + if (symb->type()->variant() == T_ARRAY) + { + auto found = deprecatedByIO.find(OriginalSymbol(symb)->identifier()); + if (found == deprecatedByIO.end()) + { + deprecatedByIO.insert(found, OriginalSymbol(symb)->identifier()); + + wstring messageE, messageR; + __spf_printToLongBuf(messageE, L"Array '%s' can not be distributed because of DVM's I/O constraints", to_wstring(symb->identifier()).c_str()); + __spf_printToLongBuf(messageR, R68, to_wstring(symb->identifier()).c_str()); + + currMessages[st->fileName()].push_back(Messages(WARR, st->lineNumber(), messageR, messageE, 1037)); + + __spf_print(1, "Array '%s' at line %d can not be distributed because of DVM's I/O constraints\n", symb->identifier(), st->lineNumber()); + } + } + } + } + + findArrayRefInIO(ex->lhs(), deprecatedByIO, st, currMessages); + findArrayRefInIO(ex->rhs(), deprecatedByIO, st, currMessages); + } +} + +static void findReshape(SgStatement* st, set& privates, map>& currMessages) +{ + if (st->variant() == ASSIGN_STAT) + { + SgExpression* exL = st->expr(0); + SgExpression* exR = st->expr(1); + + if (exR->variant() == FUNC_CALL && exL->variant() == ARRAY_REF) + { + if (exR->symbol()->identifier() == string("reshape")) + { + if (privates.find(exL->symbol()->identifier()) == privates.end()) + { + privates.insert(exL->symbol()->identifier()); + + wstring messageE, messageR; + __spf_printToLongBuf(messageE, L"Array '%s' can not be distributed because of RESHAPE", to_wstring(exL->symbol()->identifier()).c_str()); + __spf_printToLongBuf(messageR, R90, to_wstring(exL->symbol()->identifier()).c_str()); + currMessages[st->fileName()].push_back(Messages(NOTE, st->lineNumber(), messageR, messageE, 1047)); + } + } + } + } +} + +static void findConstructorRef(SgStatement* st, set& privates, map>& currMessages) +{ + if (st->variant() == ASSIGN_STAT) + { + SgExpression* exL = st->expr(0); + SgExpression* exR = st->expr(1); + + if (exR->variant() == CONSTRUCTOR_REF && exL->variant() == ARRAY_REF) + { + if (privates.find(exL->symbol()->identifier()) == privates.end()) + { + privates.insert(exL->symbol()->identifier()); + + wstring messageE, messageR; + __spf_printToLongBuf(messageE, L"Array '%s' can not be distributed because of initializer list", to_wstring(exL->symbol()->identifier()).c_str()); + __spf_printToLongBuf(messageR, R164, to_wstring(exL->symbol()->identifier()).c_str()); + currMessages[st->fileName()].push_back(Messages(NOTE, st->lineNumber(), messageR, messageE, 1047)); + } + } + } +} + +static void addPrivates(SgStatement* st, set& privates, map>& reductions, + map>>& reductionsLoc) +{ + //after SPF preprocessing + for (auto& data : getAttributes(st, set{ SPF_ANALYSIS_DIR })) + { + set privatesS; + fillPrivatesFromComment(new Statement(data), privatesS); + fillReductionsFromComment(new Statement(data), reductions); + fillReductionsFromComment(new Statement(data), reductionsLoc); + + for (auto& elem : privatesS) + privates.insert(elem->GetOriginal()->identifier()); + } + + //before SPF preprocessing + if (st->variant() == SPF_ANALYSIS_DIR) + { + set privatesS; + fillPrivatesFromComment(new Statement(st), privatesS); + fillReductionsFromComment(new Statement(st), reductions); + fillReductionsFromComment(new Statement(st), reductionsLoc); + + for (auto& elem : privatesS) + privates.insert(elem->GetOriginal()->identifier()); + } +} + +int getAllDeclaredArrays(SgFile* file, map, pair>& declaredArrays, + map>>& declaratedArraysSt, map>& currMessages, + const vector& regions, const map& distrStateFromGUI) +{ + int countErrors = 0; + + vector modules; + findModulesInFile(file, modules); + + map> privatesByModule; + for (auto& mod : modules) + { + const string modName = mod->symbol()->identifier(); + privatesByModule[modName] = set(); + auto it = privatesByModule.find(modName); + + for (SgStatement* iter = mod; iter != mod->lastNodeOfStmt(); iter = iter->lexNext()) + { + if (iter->variant() == CONTAINS_STMT) + break; + + //after SPF preprocessing + for (auto& data : getAttributes(iter, set{ SPF_ANALYSIS_DIR })) + fillPrivatesFromComment(new Statement(data), it->second); + + //before SPF preprocessing + if (iter->variant() == SPF_ANALYSIS_DIR) + fillPrivatesFromComment(new Statement(iter), it->second); + } + } + + map> ompThreadPrivate; + + for (int i = 0; i < file->numberOfFunctions(); ++i) + { + bool saveAllLocals = false; + + SgStatement* st = file->functions(i); + SgStatement* lastNode = st->lastNodeOfStmt(); + map> commonBlocks; + const string currFunctionName = st->symbol()->identifier(); + + getCommonBlocksRef(commonBlocks, st, lastNode); + set privates; + set deprecatedByIO; + map> reductions; + map>> reductionsLoc; + set funcParNames; + + if (st->variant() != PROG_HEDR) + { + SgProcHedrStmt* func = (SgProcHedrStmt*)st; + for (int z = 0; z < func->numberOfParameters(); ++z) + funcParNames.insert(func->parameter(z)->identifier()); + + if (func->nameWithContains() != func->name().identifier()) // added contains args + { + SgProcHedrStmt* cp = (SgProcHedrStmt*)func->controlParent(); + checkNull(cp, convertFileName(__FILE__).c_str(), __LINE__); + + for (int z = 0; z < cp->numberOfParameters(); ++z) + funcParNames.insert(cp->parameter(z)->identifier()); + } + } + + for (SgStatement* iter = st; iter != lastNode; iter = iter->lexNext()) + { + if (iter->variant() == CONTAINS_STMT) + break; + + addPrivates(iter, privates, reductions, reductionsLoc); + + if (iter->variant() == USE_STMT) + fillFromModule(iter->symbol(), privatesByModule, privates); + + if (iter->variant() == SAVE_DECL) + if (!iter->expr(0) && !iter->expr(1) && !iter->expr(2)) + saveAllLocals = true; + } + + for (SgStatement* iter = st; iter != lastNode; iter = iter->lexNext()) + { + if (iter->variant() == CONTAINS_STMT) + break; + + findReshape(iter, privates, currMessages); + findConstructorRef(iter, privates, currMessages); + } + + SgStatement* tmpModFind = st; + while (tmpModFind->variant() != GLOBAL) + { + tmpModFind = tmpModFind->controlParent(); + if (tmpModFind->variant() == MODULE_STMT) + fillFromModule(tmpModFind->symbol(), privatesByModule, privates); + } + + SgStatement* currF = st; + SgStatement* contains = isSgProgHedrStmt(currF->controlParent()); + if (contains) + { + for (SgStatement* loc = contains; loc; loc = loc->lexNext()) + { + if (isSgExecutableStatement(loc)) + break; + if (loc->variant() == CONTAINS_STMT) + break; + + if (loc->variant() == USE_STMT) + fillFromModule(loc->symbol(), privatesByModule, privates); + } + } + + for (auto& elem : reductions) + for (auto& setElem : elem.second) + privates.insert(setElem->identifier()); + + for (auto& elem : reductionsLoc) + { + for (auto& setElem : elem.second) + { + privates.insert(get<0>(setElem)->identifier()); + privates.insert(get<1>(setElem)->identifier()); + } + } + + //analyze IO operations + if (!ignoreIO) + { + for (SgStatement* iter = st; iter != lastNode; iter = iter->lexNext()) + { + if (iter->variant() == CONTAINS_STMT) + break; + + SgInputOutputStmt* stIO = isSgInputOutputStmt(iter); + set currRegs = getAllRegionsByLine(regions, iter->fileName(), iter->lineNumber()); + if (stIO && currRegs.size()) // deprecate to distribute arrays only in regions + { + int countOfItems = 0; + for (SgExpression* items = stIO->itemList(); items; items = items->rhs(), ++countOfItems); + + //TODO: need to add more checkers! + if (countOfItems > 1) + { + for (SgExpression* items = stIO->itemList(); items; items = items->rhs()) + findArrayRefInIO(items->lhs(), deprecatedByIO, stIO, currMessages); + } + else if (countOfItems == 1) + { + auto list = stIO->specList(); + bool ok = true; + //exclude FMT='format' + while (list) + { + if (list->lhs() && list->lhs()->variant() == SPEC_PAIR) + { + auto ex = list->lhs(); + if (ex->lhs() && ex->rhs()) + { + if (ex->lhs()->variant() == KEYWORD_VAL) + { + SgKeywordValExp* key = (SgKeywordValExp*)(ex->lhs()); + if (key->value() == string("fmt")) + if (ex->rhs()->variant() == STRING_VAL) + ok = false; + } + } + } + + if (!ok) + break; + list = list->rhs(); + } + + //check A(i,j) for example + auto item = stIO->itemList()->lhs(); + if (item->rhs() || item->lhs()) + ok = false; + + if (!ok) + findArrayRefInIO(item, deprecatedByIO, stIO, currMessages); + } + } + } + } + + while (st != lastNode) + { + if (st->variant() == CONTAINS_STMT) + break; + + if (!isSPF_stat(st) && !isDVM_stat(st)) + { + set currRegs = getAllRegionsByLine(regions, st->fileName(), st->lineNumber()); + vector regNames; + for (auto& reg : currRegs) + regNames.push_back(reg->GetName()); + if (regNames.size() == 0) + regNames.push_back("default"); + + if (st->variant() == PROC_STAT) + { + SgCallStmt* funcExp = (SgCallStmt*)st; + const string fName = funcExp->symbol()->identifier(); + for (int z = 0; z < funcExp->numberOfArgs(); ++z) + { + findArrayRefs(funcExp->arg(z), st, fName, z, true, + commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, + isSgExecutableStatement(st) ? true : false, currFunctionName, + regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, + currMessages, countErrors); + } + } + else + { + for (int i = 0; i < 3; ++i) + findArrayRefs(st->expr(i), st, "", -1, (st->variant() == ASSIGN_STAT && i == 0) ? true : false, + commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, + isSgExecutableStatement(st) ? true : false, currFunctionName, + regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, + currMessages, countErrors); + } + } + st = st->lexNext(); + } + } + + //preprocess only module declaration + for (auto& mod : modules) + { + SgStatement* st = mod->lexNext(); + SgStatement* lastNode = mod->lastNodeOfStmt(); + map> commonBlocks; + set privates; + set deprecatedByIO; + set funcParNames; + + fillFromModule(st->symbol(), privatesByModule, privates); + + while (st != lastNode) + { + if (st->variant() == CONTAINS_STMT) + break; + + if (!isSPF_stat(st) && !isDVM_stat(st)) + { + //TODO: set clear regions for modules + set currRegs = getAllRegionsByLine(regions, st->fileName(), st->lineNumber()); + vector regNames; + for (auto& reg : currRegs) + regNames.push_back(reg->GetName()); + if (regNames.size() == 0) + regNames.push_back("default"); + + for (int i = 0; i < 3; ++i) + findArrayRefs(st->expr(i), st, "", -1, false, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, + false, "NULL", regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, false, + currMessages, countErrors); + } + st = st->lexNext(); + } + } + + //preprocess only block data declaration + for (SgStatement* st = file->firstStatement()->lexNext(); st; st = st->lastNodeOfStmt(), st = st->lexNext()) + { + if (st->variant() == BLOCK_DATA) + { + SgStatement* last = st->lastNodeOfStmt(); + SgStatement* curr = st; + + map> commonBlocks; + getCommonBlocksRef(commonBlocks, st, last); + + set privates; + set deprecatedByIO; + set funcParNames; + + string blockName = "BLOCK DATA"; + if (st->symbol()) + blockName = st->symbol()->identifier(); + + while (curr && curr != last) + { + //TODO: set clear regions for block data + set currRegs = getAllRegionsByLine(regions, curr->fileName(), curr->lineNumber()); + vector regNames; + for (auto& reg : currRegs) + regNames.push_back(reg->GetName()); + if (regNames.size() == 0) + regNames.push_back("default"); + + for (int i = 0; i < 3; ++i) + findArrayRefs(curr->expr(i), curr, "", -1, false, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, + false, blockName, regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, false, + currMessages, countErrors); + curr = curr->lexNext(); + } + } + } + return countErrors; +} diff --git a/sapfor/experts/Sapfor_2017/_src/Distribution/DvmhDirective.cpp b/sapfor/experts/Sapfor_2017/_src/Distribution/DvmhDirective.cpp index 59bf212..8d75eab 100644 --- a/sapfor/experts/Sapfor_2017/_src/Distribution/DvmhDirective.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Distribution/DvmhDirective.cpp @@ -197,15 +197,6 @@ static set fillUsedSymbols(SgStatement *loop) return usedS; } -static SgStatement* getRealStat(const char *file, const int line, const int altLine) -{ - SgStatement* local = SgStatement::getStatementByFileAndLine(file, line); - if (local == NULL) - local = SgStatement::getStatementByFileAndLine(file, altLine); - checkNull(local, convertFileName(__FILE__).c_str(), __LINE__); - return local; -} - static string correctSymbolModuleName(const string& origFull) { auto it = origFull.find("::"); @@ -512,7 +503,7 @@ ParallelDirective::genDirective(File* file, const vector moduleList; findModulesInFile(file, moduleList); - SgStatement* realStat = getRealStat(file->filename(), currLoop->lineNum, currLoop->altLineNum); + SgStatement* realStat = (SgStatement*)currLoop->getRealStat(file->filename()); SgStatement* parentFunc = getFuncStat(realStat); const map> byUseInFunc = moduleRefsByUseInFunction(realStat); const int nested = countPerfectLoopNest(loopG); diff --git a/sapfor/experts/Sapfor_2017/_src/GraphLoop/graph_loops.cpp b/sapfor/experts/Sapfor_2017/_src/GraphLoop/graph_loops.cpp index 3ac61db..aa01680 100644 --- a/sapfor/experts/Sapfor_2017/_src/GraphLoop/graph_loops.cpp +++ b/sapfor/experts/Sapfor_2017/_src/GraphLoop/graph_loops.cpp @@ -908,6 +908,15 @@ void LoopGraph::analyzeParallelDirs() ch->analyzeParallelDirs(); } +void* LoopGraph::getRealStat(const char* file) const +{ + SgStatement* local = SgStatement::getStatementByFileAndLine(file, lineNum); + if (local == NULL) + local = SgStatement::getStatementByFileAndLine(file, altLineNum); + checkNull(local, convertFileName(__FILE__).c_str(), __LINE__); + return local; +} + extern int PASSES_DONE[EMPTY_PASS]; static void printToBuffer(const LoopGraph *currLoop, const int childSize, char buf[512]) { diff --git a/sapfor/experts/Sapfor_2017/_src/GraphLoop/graph_loops.h b/sapfor/experts/Sapfor_2017/_src/GraphLoop/graph_loops.h index ce3939e..887ef29 100644 --- a/sapfor/experts/Sapfor_2017/_src/GraphLoop/graph_loops.h +++ b/sapfor/experts/Sapfor_2017/_src/GraphLoop/graph_loops.h @@ -391,6 +391,8 @@ public: void analyzeParallelDirs(); + void* getRealStat(const char* file) const; + public: int lineNum; int altLineNum; diff --git a/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp b/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp index eb584f0..785f134 100644 --- a/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp +++ b/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp @@ -62,7 +62,6 @@ extern REGIME currRegime; extern std::vector* currMessages; extern int sharedMemoryParallelization; -extern int ignoreIO; extern int parallizeFreeLoops; using std::vector; @@ -956,9 +955,9 @@ static SgExpression* replaceConstatantProcedurePars(SgExpression *dimList, SgSta return dimList; } -static vector> getArraySizes(vector> &sizes, SgSymbol *symb, SgStatement *decl, - const map> &arrayLinksByFuncCalls, - const map> &allFuncInfo) +vector> getArraySizes(vector> &sizes, SgSymbol *symb, SgStatement *decl, + const map> &arrayLinksByFuncCalls, + const map> &allFuncInfo) { SgArrayType *type = isSgArrayType(symb->type()); vector> retVal; @@ -2616,758 +2615,6 @@ int getSizeOfType(SgType *t) return len; } -static bool findOmpThreadPrivDecl(SgStatement* st, map>& ompThreadPrivate, SgSymbol* toFind) -{ - - auto it = ompThreadPrivate.find(st); - if (it == ompThreadPrivate.end()) - { - it = ompThreadPrivate.insert(it, make_pair(st, set())); - - SgStatement* lastN = st->lastNodeOfStmt(); - set dummy; - do - { - st = st->lexNext(); - - auto res = parseOmpInStatement(st, dummy); - for (auto& dir : res) - for (auto& var : dir.threadPrivVars) - it->second.insert(var); - } while (st != lastN && !isSgExecutableStatement(st) && st->variant() != CONTAINS_STMT); - } - - if (it->second.find(toFind->identifier()) != it->second.end()) - return true; - else - return false; -} - -static bool hasAssingOpInDecl(SgSymbol* symb) -{ - vector allDecls; - SgStatement* decl = declaratedInStmt(symb, &allDecls); - - for (auto& elem : allDecls) - { - if (elem->variant() == VAR_DECL_90) - { - SgExpression* list = elem->expr(0); - while (list) - { - if (list->lhs()->variant() == ASSGN_OP) - if (list->lhs()->lhs()->symbol() && OriginalSymbol(list->lhs()->lhs()->symbol()) == symb) - return true; - list = list->rhs(); - } - } - } - - return false; -} - -static set> checkedArraysForWrongLocation; - -static string getNameWithScope(SgStatement* scope, const string& currFunctionName) -{ - if (scope && isSgProgHedrStmt(scope) && scope->symbol()->identifier() != currFunctionName) - return scope->symbol()->identifier(); - else - return currFunctionName; -} - -struct findInfo -{ - findInfo(const string fName, SgExpression* ex, int parN, bool isWrite) : - fName(fName), ex(ex), parN(parN), isWrite(isWrite) - { } - - SgExpression* ex; - string fName; - int parN; - bool isWrite; -}; - -static void findArrayRefs(SgExpression *ex, SgStatement *st, string fName, int parN, bool isWrite, - const map> &commonBlocks, - map, pair> &declaredArrays, - map>> &declaratedArraysSt, - const set &privates, const set &deprecatedByIO, - bool isExecutable, const string &currFunctionName, - const vector &inRegion, - const set &funcParNames, - map>& ompThreadPrivate, - const map& distrStateFromGUI, - const bool saveAllLocals, - map>& currMessages, - int& errorCount) -{ - const string globalFile = current_file->filename(); - const set filesInProj = getAllFilesInProject(); - - if (ex == NULL) - return; - stack queue; - queue.push(findInfo(fName, ex, parN, isWrite)); - - while (!queue.empty()) - { - const findInfo& curQ = queue.top(); - ex = curQ.ex; - fName = curQ.fName; - parN = curQ.parN; - isWrite = curQ.isWrite; - - queue.pop(); - - if (isArrayRef(ex)) - { - SgSymbol* symb = OriginalSymbol(ex->symbol()); - const bool inDataStat = (symb->attributes() & DATA_BIT) != 0 || ((ex->symbol())->attributes() & DATA_BIT); - checkNull(symb->type(), convertFileName(__FILE__).c_str(), __LINE__); - - const int typeSize = getSizeOfType(symb->type()->baseType()); - if (typeSize == 0) - { - //__spf_print(1, "Wrong type size for array %s\n", symb->identifier()); - //printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - - SgStatement* decl = declaratedInStmt(symb); - if (decl->variant() == DVM_VAR_DECL || decl->variant() == HPF_TEMPLATE_STAT) - { - const string tmp(decl->unparse()); - if (tmp.find("!DVM$ TEMPLATE") != string::npos) - { - auto sTemp = symb->identifier(); - tuple uniqKey; - bool found = false; - for (auto& elem : declaredArrays) - { - if (elem.second.first->GetShortName() == sTemp) - { - uniqKey = elem.first; - found = true; - } - } - - if (found) - { - auto itDecl = declaratedArraysSt.find(decl); - if (itDecl == declaratedArraysSt.end()) - itDecl = declaratedArraysSt.insert(itDecl, make_pair(decl, set>())); - itDecl->second.insert(uniqKey); - - return; - } - } - } - - auto uniqKey = getUniqName(commonBlocks, decl, symb); - - SgStatement* scope = symb->scope(); - pair arrayLocation; - - string typePrefix = ""; - while (scope && scope->variant() == STRUCT_DECL) - { - if (typePrefix == "") - typePrefix = scope->symbol()->identifier(); - else - typePrefix += scope->symbol()->identifier() + string("::"); - scope = scope->controlParent(); - } - - if ((ex->symbol() && symb != ex->symbol()) || (scope && scope->variant() == MODULE_STMT)) - { - if (scope) - { - string modName = scope->symbol()->identifier(); - arrayLocation = make_pair(DIST::l_MODULE, (typePrefix == "") ? modName : modName + "::" + typePrefix); - } - else //TODO: find module name with another way - arrayLocation = make_pair(DIST::l_MODULE, "UNREC_MODULE_NAME"); - } - else if (get<1>(uniqKey).find("common_") != string::npos) - arrayLocation = make_pair(DIST::l_COMMON, get<1>(uniqKey).substr(strlen("common_"))); - else if (funcParNames.find(symb->identifier()) != funcParNames.end()) - arrayLocation = make_pair(DIST::l_PARAMETER, getNameWithScope(scope, currFunctionName)); - else - { - if (saveAllLocals || ((symb->attributes() & SAVE_BIT) != 0) || hasAssingOpInDecl(symb)) - arrayLocation = make_pair(DIST::l_LOCAL_SAVE, getNameWithScope(scope, currFunctionName)); - else - arrayLocation = make_pair(DIST::l_LOCAL, getNameWithScope(scope, currFunctionName)); - } - - auto itNew = declaredArrays.find(uniqKey); - if (itNew == declaredArrays.end()) - { - DIST::Array* arrayToAdd = - new DIST::Array(getShortName(uniqKey), symb->identifier(), ((SgArrayType*)(symb->type()))->dimension(), - getUniqArrayId(), decl->fileName(), decl->lineNumber(), arrayLocation, new Symbol(symb), - findOmpThreadPrivDecl(scope, ompThreadPrivate, symb), false, false, - inRegion, typeSize, sharedMemoryParallelization ? DIST::NO_DISTR : DIST::DISTR); - - itNew = declaredArrays.insert(itNew, make_pair(uniqKey, make_pair(arrayToAdd, new DIST::ArrayAccessInfo()))); - - vector> sizes; - map> arrayLinksByFuncCallsNotReady; - map> allFuncInfoNoReady; - auto sizesExpr = getArraySizes(sizes, symb, decl, arrayLinksByFuncCallsNotReady, allFuncInfoNoReady); - arrayToAdd->SetSizes(sizes); - arrayToAdd->SetSizesExpr(sizesExpr); - tableOfUniqNamesByArray[arrayToAdd] = uniqKey; - } - else // check the same location from include! - { - auto prevLocation = itNew->second.first->GetLocation(); - if (prevLocation != arrayLocation) - { - if (checkedArraysForWrongLocation.find(uniqKey) == checkedArraysForWrongLocation.end()) - { - checkedArraysForWrongLocation.insert(uniqKey); - __spf_print(1, "can not change declaration area of array '%s' on line %d\n", symb->identifier(), st->lineNumber()); - - wstring messageE, messageR; - __spf_printToLongBuf(messageE, L"Array '%s' has declaration area conflict, it might be worth applying the Include inlining pass", to_wstring(symb->identifier()).c_str()); - __spf_printToLongBuf(messageR, R184, to_wstring(symb->identifier()).c_str()); - - currMessages[st->fileName()].push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1061)); - } - errorCount++; - } - } - - if ((symb->attributes() & EQUIVALENCE_BIT) != 0) - itNew->second.first->SetEquvalence(true); - - for (auto& reg : inRegion) - itNew->second.first->SetRegionPlace(reg); - - const auto oldVal = itNew->second.first->GetDistributeFlagVal(); - if (oldVal == DIST::DISTR || oldVal == DIST::NO_DISTR) - { - if (itNew->second.first->IsOmpThreadPrivate()) - itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); - else if (privates.find(symb->identifier()) != privates.end()) - { - //check in module - if (itNew->second.first->GetLocation().first == DIST::l_MODULE) - { - for (auto& data : getAttributes(decl, set{ SPF_ANALYSIS_DIR })) - { - set privatesS; - fillPrivatesFromComment(new Statement(data), privatesS); - if (privatesS.find(symb->identifier()) != privatesS.end()) - { - itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); - break; - } - } - - auto prev = decl->lexPrev(); - checkNull(prev, convertFileName(__FILE__).c_str(), __LINE__); - - set privatesS; - fillPrivatesFromComment(new Statement(prev), privatesS); - if (privatesS.find(symb->identifier()) != privatesS.end()) - itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); - } - else - itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); - } - else if (deprecatedByIO.find(symb->identifier()) != deprecatedByIO.end()) - itNew->second.first->SetDistributeFlag(DIST::IO_PRIV); - else if (isSgConstantSymb(symb) || inDataStat) - itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); - else - { - auto it = distrStateFromGUI.find(itNew->second.first->GetIndepUniqName()); - if (it != distrStateFromGUI.end()) - { - if (it->second != oldVal) - { - itNew->second.first->SetDistributeFlag((DIST::distFlag)it->second); - __spf_print(1, "change flag for array from cache '%s': %d -> %d\n", it->first.c_str(), oldVal, it->second); - } - } - else - itNew->second.first->SetDistributeFlag(DIST::DISTR); - } - } - - if (typeSize == 0) // unknown - itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); - - - if (!isExecutable) - itNew->second.first->AddDeclInfo(make_pair(st->fileName(), st->lineNumber()), filesInProj, globalFile, new Symbol(symb)); - - if (isExecutable) - { - if (st->variant() != ALLOCATE_STMT && st->variant() != DEALLOCATE_STMT) - { - itNew->second.second->AddAccessInfo(st->fileName(), make_pair(st->lineNumber(), isWrite ? 1 : 0), fName, parN); - itNew->second.first->AddUsagePlace(st->fileName(), st->lineNumber()); - } - } - - auto itDecl = declaratedArraysSt.find(decl); - if (itDecl == declaratedArraysSt.end()) - itDecl = declaratedArraysSt.insert(itDecl, make_pair(decl, set>())); - itDecl->second.insert(uniqKey); - - if (decl->variant() == DVM_VAR_DECL || decl->variant() == HPF_TEMPLATE_STAT) - { - const string tmp(decl->unparse()); - if (tmp.find("!DVM$ TEMPLATE") != string::npos) - { - itNew->second.first->SetTemplateFlag(true); - //TODO: analyze align mapping - for (int z = 0; z < itNew->second.first->GetDimSize(); ++z) - itNew->second.first->SetMappedDim(z); - } - } - } - - if (ex->variant() == FUNC_CALL) - { - SgFunctionCallExp* funcExp = (SgFunctionCallExp*)ex; - const string fName = funcExp->funName()->identifier(); - bool intr = (isIntrinsicFunctionName(fName.c_str()) == 1); - for (int z = 0; z < funcExp->numberOfArgs(); ++z) - { - //assume all arguments of function as OUT, except for inctrinsics - bool isWriteN = intr ? false : true; - //need to correct W/R usage with GraphCall map later - findArrayRefs(funcExp->arg(z), st, fName, z, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount); - } - } - else - { - bool isWriteN = false; - if (ex->lhs()) - queue.push(findInfo("", ex->lhs(), -1, isWriteN)); - if (ex->rhs()) - queue.push(findInfo("", ex->rhs(), -1, isWriteN)); - //findArrayRefs(ex->lhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount); - //findArrayRefs(ex->rhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount); - } - } -} - -static void findArrayRefInIO(SgExpression *ex, set &deprecatedByIO, SgStatement *st, map> &currMessages) -{ - if (ex) - { - if (ex->variant() == ARRAY_REF) - { - auto symb = ex->symbol(); - if (symb->type()) - { - if (symb->type()->variant() == T_ARRAY) - { - auto found = deprecatedByIO.find(OriginalSymbol(symb)->identifier()); - if (found == deprecatedByIO.end()) - { - deprecatedByIO.insert(found, OriginalSymbol(symb)->identifier()); - - wstring messageE, messageR; - __spf_printToLongBuf(messageE, L"Array '%s' can not be distributed because of DVM's I/O constraints", to_wstring(symb->identifier()).c_str()); - __spf_printToLongBuf(messageR, R68, to_wstring(symb->identifier()).c_str()); - - currMessages[st->fileName()].push_back(Messages(WARR, st->lineNumber(), messageR, messageE, 1037)); - - __spf_print(1, "Array '%s' at line %d can not be distributed because of DVM's I/O constraints\n", symb->identifier(), st->lineNumber()); - } - } - } - } - - findArrayRefInIO(ex->lhs(), deprecatedByIO, st, currMessages); - findArrayRefInIO(ex->rhs(), deprecatedByIO, st, currMessages); - } -} - -static void findReshape(SgStatement *st, set &privates, map> &currMessages) -{ - if (st->variant() == ASSIGN_STAT) - { - SgExpression *exL = st->expr(0); - SgExpression *exR = st->expr(1); - - if (exR->variant() == FUNC_CALL && exL->variant() == ARRAY_REF) - { - if (exR->symbol()->identifier() == string("reshape")) - { - if (privates.find(exL->symbol()->identifier()) == privates.end()) - { - privates.insert(exL->symbol()->identifier()); - - wstring messageE, messageR; - __spf_printToLongBuf(messageE, L"Array '%s' can not be distributed because of RESHAPE", to_wstring(exL->symbol()->identifier()).c_str()); - __spf_printToLongBuf(messageR, R90, to_wstring(exL->symbol()->identifier()).c_str()); - currMessages[st->fileName()].push_back(Messages(NOTE, st->lineNumber(), messageR, messageE, 1047)); - } - } - } - } -} - -static void findConstructorRef(SgStatement* st, set& privates, map>& currMessages) -{ - if (st->variant() == ASSIGN_STAT) - { - SgExpression* exL = st->expr(0); - SgExpression* exR = st->expr(1); - - if (exR->variant() == CONSTRUCTOR_REF && exL->variant() == ARRAY_REF) - { - if (privates.find(exL->symbol()->identifier()) == privates.end()) - { - privates.insert(exL->symbol()->identifier()); - - wstring messageE, messageR; - __spf_printToLongBuf(messageE, L"Array '%s' can not be distributed because of initializer list", to_wstring(exL->symbol()->identifier()).c_str()); - __spf_printToLongBuf(messageR, R164, to_wstring(exL->symbol()->identifier()).c_str()); - currMessages[st->fileName()].push_back(Messages(NOTE, st->lineNumber(), messageR, messageE, 1047)); - } - } - } -} - -static void addPrivates(SgStatement *st, set& privates, map>& reductions, - map>>& reductionsLoc) -{ - //after SPF preprocessing - for (auto& data : getAttributes(st, set{ SPF_ANALYSIS_DIR })) - { - set privatesS; - fillPrivatesFromComment(new Statement(data), privatesS); - fillReductionsFromComment(new Statement(data), reductions); - fillReductionsFromComment(new Statement(data), reductionsLoc); - - for (auto& elem : privatesS) - privates.insert(elem->GetOriginal()->identifier()); - } - - //before SPF preprocessing - if (st->variant() == SPF_ANALYSIS_DIR) - { - set privatesS; - fillPrivatesFromComment(new Statement(st), privatesS); - fillReductionsFromComment(new Statement(st), reductions); - fillReductionsFromComment(new Statement(st), reductionsLoc); - - for (auto& elem : privatesS) - privates.insert(elem->GetOriginal()->identifier()); - } -} - -int getAllDeclaredArrays(SgFile *file, map, pair> &declaredArrays, - map>> &declaratedArraysSt, map> &currMessages, - const vector ®ions, const map& distrStateFromGUI) -{ - int countErrors = 0; - - vector modules; - findModulesInFile(file, modules); - - map> privatesByModule; - for (auto &mod : modules) - { - const string modName = mod->symbol()->identifier(); - privatesByModule[modName] = set(); - auto it = privatesByModule.find(modName); - - for (SgStatement *iter = mod; iter != mod->lastNodeOfStmt(); iter = iter->lexNext()) - { - if (iter->variant() == CONTAINS_STMT) - break; - - //after SPF preprocessing - for (auto &data : getAttributes(iter, set{ SPF_ANALYSIS_DIR })) - fillPrivatesFromComment(new Statement(data), it->second); - - //before SPF preprocessing - if (iter->variant() == SPF_ANALYSIS_DIR) - fillPrivatesFromComment(new Statement(iter), it->second); - } - } - - map> ompThreadPrivate; - - for (int i = 0; i < file->numberOfFunctions(); ++i) - { - bool saveAllLocals = false; - - SgStatement *st = file->functions(i); - SgStatement *lastNode = st->lastNodeOfStmt(); - map> commonBlocks; - const string currFunctionName = st->symbol()->identifier(); - - getCommonBlocksRef(commonBlocks, st, lastNode); - set privates; - set deprecatedByIO; - map> reductions; - map>> reductionsLoc; - set funcParNames; - - if (st->variant() != PROG_HEDR) - { - SgProcHedrStmt *func = (SgProcHedrStmt*)st; - for (int z = 0; z < func->numberOfParameters(); ++z) - funcParNames.insert(func->parameter(z)->identifier()); - - if (func->nameWithContains() != func->name().identifier()) // added contains args - { - SgProcHedrStmt* cp = (SgProcHedrStmt*)func->controlParent(); - checkNull(cp, convertFileName(__FILE__).c_str(), __LINE__); - - for (int z = 0; z < cp->numberOfParameters(); ++z) - funcParNames.insert(cp->parameter(z)->identifier()); - } - } - - for (SgStatement* iter = st; iter != lastNode; iter = iter->lexNext()) - { - if (iter->variant() == CONTAINS_STMT) - break; - - addPrivates(iter, privates, reductions, reductionsLoc); - - if (iter->variant() == USE_STMT) - fillFromModule(iter->symbol(), privatesByModule, privates); - - if (iter->variant() == SAVE_DECL) - if (!iter->expr(0) && !iter->expr(1) && !iter->expr(2)) - saveAllLocals = true; - } - - for (SgStatement* iter = st; iter != lastNode; iter = iter->lexNext()) - { - if (iter->variant() == CONTAINS_STMT) - break; - - findReshape(iter, privates, currMessages); - findConstructorRef(iter, privates, currMessages); - } - - SgStatement* tmpModFind = st; - while (tmpModFind->variant() != GLOBAL) - { - tmpModFind = tmpModFind->controlParent(); - if (tmpModFind->variant() == MODULE_STMT) - fillFromModule(tmpModFind->symbol(), privatesByModule, privates); - } - - SgStatement *currF = st; - SgStatement *contains = isSgProgHedrStmt(currF->controlParent()); - if (contains) - { - for (SgStatement *loc = contains; loc; loc = loc->lexNext()) - { - if (isSgExecutableStatement(loc)) - break; - if (loc->variant() == CONTAINS_STMT) - break; - - if (loc->variant() == USE_STMT) - fillFromModule(loc->symbol(), privatesByModule, privates); - } - } - - for (auto &elem : reductions) - for (auto &setElem : elem.second) - privates.insert(setElem->identifier()); - - for (auto &elem : reductionsLoc) - { - for (auto &setElem : elem.second) - { - privates.insert(get<0>(setElem)->identifier()); - privates.insert(get<1>(setElem)->identifier()); - } - } - - //analyze IO operations - if (!ignoreIO) - { - for (SgStatement* iter = st; iter != lastNode; iter = iter->lexNext()) - { - if (iter->variant() == CONTAINS_STMT) - break; - - SgInputOutputStmt* stIO = isSgInputOutputStmt(iter); - set currRegs = getAllRegionsByLine(regions, iter->fileName(), iter->lineNumber()); - if (stIO && currRegs.size()) // deprecate to distribute arrays only in regions - { - int countOfItems = 0; - for (SgExpression* items = stIO->itemList(); items; items = items->rhs(), ++countOfItems); - - //TODO: need to add more checkers! - if (countOfItems > 1) - { - for (SgExpression* items = stIO->itemList(); items; items = items->rhs()) - findArrayRefInIO(items->lhs(), deprecatedByIO, stIO, currMessages); - } - else if (countOfItems == 1) - { - auto list = stIO->specList(); - bool ok = true; - //exclude FMT='format' - while (list) - { - if (list->lhs() && list->lhs()->variant() == SPEC_PAIR) - { - auto ex = list->lhs(); - if (ex->lhs() && ex->rhs()) - { - if (ex->lhs()->variant() == KEYWORD_VAL) - { - SgKeywordValExp* key = (SgKeywordValExp*)(ex->lhs()); - if (key->value() == string("fmt")) - if (ex->rhs()->variant() == STRING_VAL) - ok = false; - } - } - } - - if (!ok) - break; - list = list->rhs(); - } - - //check A(i,j) for example - auto item = stIO->itemList()->lhs(); - if (item->rhs() || item->lhs()) - ok = false; - - if (!ok) - findArrayRefInIO(item, deprecatedByIO, stIO, currMessages); - } - } - } - } - - while (st != lastNode) - { - if (st->variant() == CONTAINS_STMT) - break; - - if (!isSPF_stat(st) && !isDVM_stat(st)) - { - set currRegs = getAllRegionsByLine(regions, st->fileName(), st->lineNumber()); - vector regNames; - for (auto ® : currRegs) - regNames.push_back(reg->GetName()); - if (regNames.size() == 0) - regNames.push_back("default"); - - if (st->variant() == PROC_STAT) - { - SgCallStmt* funcExp = (SgCallStmt*)st; - const string fName = funcExp->symbol()->identifier(); - for (int z = 0; z < funcExp->numberOfArgs(); ++z) - { - findArrayRefs(funcExp->arg(z), st, fName, z, true, - commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, - isSgExecutableStatement(st) ? true : false, currFunctionName, - regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, - currMessages, countErrors); - } - } - else - { - for (int i = 0; i < 3; ++i) - findArrayRefs(st->expr(i), st, "", -1, (st->variant() == ASSIGN_STAT && i == 0) ? true : false, - commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, - isSgExecutableStatement(st) ? true : false, currFunctionName, - regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, - currMessages, countErrors); - } - } - st = st->lexNext(); - } - } - - //preprocess only module declaration - for (auto &mod : modules) - { - SgStatement *st = mod->lexNext(); - SgStatement *lastNode = mod->lastNodeOfStmt(); - map> commonBlocks; - set privates; - set deprecatedByIO; - set funcParNames; - - fillFromModule(st->symbol(), privatesByModule, privates); - - while (st != lastNode) - { - if (st->variant() == CONTAINS_STMT) - break; - - if (!isSPF_stat(st) && !isDVM_stat(st)) - { - //TODO: set clear regions for modules - set currRegs = getAllRegionsByLine(regions, st->fileName(), st->lineNumber()); - vector regNames; - for (auto& reg : currRegs) - regNames.push_back(reg->GetName()); - if (regNames.size() == 0) - regNames.push_back("default"); - - for (int i = 0; i < 3; ++i) - findArrayRefs(st->expr(i), st, "", -1, false, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, - false, "NULL", regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, false, - currMessages, countErrors); - } - st = st->lexNext(); - } - } - - //preprocess only block data declaration - for (SgStatement* st = file->firstStatement()->lexNext(); st; st = st->lastNodeOfStmt(), st = st->lexNext()) - { - if (st->variant() == BLOCK_DATA) - { - SgStatement* last = st->lastNodeOfStmt(); - SgStatement* curr = st; - - map> commonBlocks; - getCommonBlocksRef(commonBlocks, st, last); - - set privates; - set deprecatedByIO; - set funcParNames; - - string blockName = "BLOCK DATA"; - if (st->symbol()) - blockName = st->symbol()->identifier(); - - while (curr && curr != last) - { - //TODO: set clear regions for block data - set currRegs = getAllRegionsByLine(regions, curr->fileName(), curr->lineNumber()); - vector regNames; - for (auto& reg : currRegs) - regNames.push_back(reg->GetName()); - if (regNames.size() == 0) - regNames.push_back("default"); - - for (int i = 0; i < 3; ++i) - findArrayRefs(curr->expr(i), curr, "", -1, false, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, - false, blockName, regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, false, - currMessages, countErrors); - curr = curr->lexNext(); - } - } - } - return countErrors; -} - void insertSpfAnalysisBeforeParalleLoops(const vector &loops) { for (auto &loop : loops) diff --git a/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.h b/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.h index 70ffa60..5fa5f42 100644 --- a/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.h +++ b/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.h @@ -33,6 +33,13 @@ void loopAnalyzer(SgFile *file, const std::map> &arrayLinksByFuncCalls, const std::map> &defUseByPlace, bool skipDeps, std::vector *loopGraph = NULL); + +void fillFromModule(SgSymbol* s, const std::map>& privatesByModule, std::set& privates); + +std::vector> getArraySizes(std::vector>& sizes, SgSymbol* symb, SgStatement* decl, + const std::map>& arrayLinksByFuncCalls, + const std::map>& allFuncInfo); + void arrayAccessAnalyzer(SgFile *file, std::vector &messagesForFile, const std::map, std::pair> &declaredArrays, REGIME regime); @@ -46,9 +53,6 @@ bool isIntrinsic(const char *funName); std::tuple getUniqName(const std::map &commonBlocks, SgStatement *decl, SgSymbol *symb); std::string getShortName(const std::tuple &uniqKey); -int getAllDeclaredArrays(SgFile *file, std::map, std::pair> &declaredArrays, - std::map>> &declaratedArraysSt, std::map> &currMessages, - const std::vector ®ions, const std::map& distrStateFromGUI); void insertSpfAnalysisBeforeParalleLoops(const std::vector &loops); void recalculateArraySizes(std::set &arraysDone, const std::set &allArrays, const std::map> &arrayLinksByFuncCalls, const std::map>& allFuncInfo); int getSizeOfType(SgType* t); @@ -93,3 +97,8 @@ template bool createRemoteDir(SgStatement *st, const std::map filterUserSpf(const std::vector& toFilter, bool with_omp = true); + +// ArrayAnalysis.cpp +int getAllDeclaredArrays(SgFile *file, std::map, std::pair> &declaredArrays, + std::map>> &declaratedArraysSt, std::map> &currMessages, + const std::vector ®ions, const std::map& distrStateFromGUI); \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp index 5addf9a..9781d75 100644 --- a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp @@ -438,7 +438,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne int global_err = 0; map same_decls; - + for (int i = n - 1; i >= 0; --i) { createNeededException(); diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.cpp b/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.cpp index d71bd0a..9dcd3f3 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.cpp @@ -2726,7 +2726,8 @@ SgStatement* makeDeclaration(SgStatement* curr, const vector& sIn, ve decl->setFileName(place->fileName()); decl->setFileId(place->getFileId()); decl->setProject(place->getProject()); - decl->setlineNumber(place->lineNumber()); + decl->setlineNumber(getNextNegativeLineNumber()); + //decl->setlineNumber(place->lineNumber()); place->insertStmtBefore(*decl, *scope); } diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/version.h b/sapfor/experts/Sapfor_2017/_src/Utils/version.h index 2bdd6e2..0514fe4 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/version.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2368" +#define VERSION_SPF "2372"