Files
SAPFOR/src/Distribution/ArrayAnalysis.cpp
2025-09-11 08:07:14 +03:00

767 lines
33 KiB
C++

#include "Array.h"
#include "errors.h"
#include "utils.h"
#include "graph_calls.h"
#include "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<DIST::Array*, std::tuple<int, string, string>> tableOfUniqNamesByArray;
static set<tuple<int, string, string>> checkedArraysForWrongLocation;
static bool findOmpThreadPrivDecl(SgStatement* st, map<SgStatement*, set<string>>& ompThreadPrivate, SgSymbol* toFind)
{
auto it = ompThreadPrivate.find(st);
if (it == ompThreadPrivate.end())
{
it = ompThreadPrivate.insert(it, make_pair(st, set<string>()));
SgStatement* lastN = st->lastNodeOfStmt();
set<string> 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<SgStatement*> 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<string, vector<SgExpression*>>& commonBlocks,
map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
map<SgStatement*, set<tuple<int, string, string>>>& declaratedArraysSt,
const set<string>& privates, const set<string>& deprecatedByIO,
bool isExecutable, const string& currFunctionName,
const vector<string>& inRegion,
const set<string>& funcParNames,
map<SgStatement*, set<string>>& ompThreadPrivate,
const map<string, int>& distrStateFromGUI,
const bool saveAllLocals,
map<string, vector<Messages>>& currMessages,
int& errorCount)
{
const string globalFile = current_file->filename();
const set<string> filesInProj = getAllFilesInProject();
if (ex == NULL)
return;
stack<findInfo> 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<int, string, string> 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<tuple<int, string, string>>()));
itDecl->second.insert(uniqKey);
return;
}
}
}
auto uniqKey = getUniqName(commonBlocks, decl, symb);
SgStatement* scope = symb->scope();
pair<DIST::arrayLocType, string> 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<pair<int, int>> sizes;
map<DIST::Array*, set<DIST::Array*>> arrayLinksByFuncCallsNotReady;
map<string, vector<FuncInfo*>> 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 (deprecatedByIO.find(symb->identifier()) != deprecatedByIO.end())
itNew->second.first->SetDistributeFlag(DIST::IO_PRIV);
else if (isArrayInModule || privates.find(symb->identifier()) != privates.end())
{
//check in module
if (itNew->second.first->GetLocation().first == DIST::l_MODULE)
{
for (auto& data : getAttributes<SgStatement*, SgStatement*>(decl, set<int>{ SPF_ANALYSIS_DIR }))
{
set<string> 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<string> 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 (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<tuple<int, string, string>>()));
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<string>& deprecatedByIO, SgStatement* st, map<string, vector<Messages>>& 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<string>& privates, map<string, vector<Messages>>& 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<string>& privates, map<string, vector<Messages>>& 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<string>& privates, map<string, set<Symbol*>>& reductions,
map<string, set<tuple<Symbol*, Symbol*, int>>>& reductionsLoc)
{
//after SPF preprocessing
for (auto& data : getAttributes<SgStatement*, SgStatement*>(st, set<int>{ SPF_ANALYSIS_DIR }))
{
set<Symbol*> 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<Symbol*> 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<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
map<SgStatement*, set<tuple<int, string, string>>>& declaratedArraysSt, map<string, vector<Messages>>& currMessages,
const vector<ParallelRegion*>& regions, const map<string, int>& distrStateFromGUI)
{
int countErrors = 0;
vector<SgStatement*> modules;
findModulesInFile(file, modules);
map<string, set<string>> privatesByModule;
for (auto& mod : modules)
{
const string modName = mod->symbol()->identifier();
privatesByModule[modName] = set<string>();
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<SgStatement*, SgStatement*>(iter, set<int>{ 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<SgStatement*, set<string>> ompThreadPrivate;
for (int i = 0; i < file->numberOfFunctions(); ++i)
{
bool saveAllLocals = false;
SgStatement* st = file->functions(i);
SgStatement* lastNode = st->lastNodeOfStmt();
map<string, vector<SgExpression*>> commonBlocks;
const string currFunctionName = st->symbol()->identifier();
getCommonBlocksRef(commonBlocks, st, lastNode);
set<string> privates;
set<string> deprecatedByIO;
map<string, set<Symbol*>> reductions;
map<string, set<tuple<Symbol*, Symbol*, int>>> reductionsLoc;
set<string> 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<ParallelRegion*> 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<ParallelRegion*> currRegs = getAllRegionsByLine(regions, st->fileName(), st->lineNumber());
vector<string> 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<string, vector<SgExpression*>> commonBlocks;
set<string> privates;
set<string> deprecatedByIO;
set<string> 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<ParallelRegion*> currRegs = getAllRegionsByLine(regions, st->fileName(), st->lineNumber());
vector<string> 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<string, vector<SgExpression*>> commonBlocks;
getCommonBlocksRef(commonBlocks, st, last);
set<string> privates;
set<string> deprecatedByIO;
set<string> funcParNames;
string blockName = "BLOCK DATA";
if (st->symbol())
blockName = st->symbol()->identifier();
while (curr && curr != last)
{
//TODO: set clear regions for block data
set<ParallelRegion*> currRegs = getAllRegionsByLine(regions, curr->fileName(), curr->lineNumber());
vector<string> 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;
}