Merge branch 'master' into analyze_loops_with_IR
This commit is contained in:
@@ -259,6 +259,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
|
||||
|
||||
@@ -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<string, FuncInfo*>& funcMap,
|
||||
}
|
||||
}
|
||||
|
||||
ArrayRefExp* createRemoteLink(const DIST::Array* forArray)
|
||||
ArrayRefExp* createRemoteLink(const LoopGraph* currLoop, const DIST::Array* forArray)
|
||||
{
|
||||
SgFile* file = current_file;
|
||||
|
||||
const set<string> allFiles = getAllFilesInProject();
|
||||
SgStatement* realStat = (SgStatement*)currLoop->getRealStat(file->filename());
|
||||
const map<string, set<SgSymbol*>> byUseInFunc = moduleRefsByUseInFunction(realStat);
|
||||
SgStatement* parentFunc = getFuncStat(realStat);
|
||||
const pair<int, int> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ void addRemoteLink(const LoopGraph* loop, const std::map<std::string, FuncInfo*>
|
||||
const std::set<std::string>& remotesInParallel, std::set<ArrayRefExp*>& addedRemotes, const std::vector<std::string>& mapToLoop,
|
||||
std::vector<Messages>& messages, const int line, bool bindToLoopDistribution = true);
|
||||
|
||||
ArrayRefExp* createRemoteLink(const DIST::Array* forArray);
|
||||
ArrayRefExp* createRemoteLink(const LoopGraph* currLoop, const DIST::Array* forArray);
|
||||
|
||||
std::vector<RemoteRequest>
|
||||
checkArrayRefInLoopForRemoteStatus(bool ifUnknownArrayAssignFound,
|
||||
|
||||
@@ -86,7 +86,7 @@ static void createRemoteInParallel(const pair<LoopGraph*, const ParallelDirectiv
|
||||
mapToLoop.push_back("");
|
||||
|
||||
//TODO: find all array refs
|
||||
addRemoteLink(under_dvm_dir.first, funcMap, createRemoteLink(usedArr), uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, -1, false);
|
||||
addRemoteLink(under_dvm_dir.first, funcMap, createRemoteLink(under_dvm_dir.first, usedArr), uniqRemotes, remotesInParallel, addedRemotes, mapToLoop, messages, -1, false);
|
||||
__spf_print(DEB, "CRIP: %d, AFTER MAIN CHECK for arrray '%s'\n", __LINE__, usedArr->GetShortName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ static void replaceShadowByRemote(SgExpression *specInDir, SgStatement *stat,
|
||||
|
||||
void devourShadowByRemote(void *file_, const map<string, FuncInfo*>& funcMap, const vector<LoopGraph*>& loops,
|
||||
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls)
|
||||
{
|
||||
{
|
||||
SgFile* file = static_cast<SgFile*>(file_);
|
||||
map<int, LoopGraph*> loopByLine;
|
||||
createMapLoopGraph(loops, loopByLine);
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace Distribution
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void TemplateLink::AddRule(const int dimNum, int dimTempl, const pair<int, int> &rule, Array *templateArray_)
|
||||
void TemplateLink::AddRule(const int dimNum, int dimTempl, const pair<int, int>& rule, Array* templateArray_)
|
||||
{
|
||||
linkWithTemplate[dimNum] = dimTempl;
|
||||
alignRuleWithTemplate[dimNum] = rule;
|
||||
@@ -132,7 +132,7 @@ namespace Distribution
|
||||
const vector<pair<int, int>>& Array::GetSizes()
|
||||
{
|
||||
if (templateDimsOrder.size() == 0)
|
||||
return sizes;
|
||||
return sizes;
|
||||
else
|
||||
{
|
||||
if (orderedSizes.size() == 0)
|
||||
@@ -141,7 +141,7 @@ namespace Distribution
|
||||
}
|
||||
}
|
||||
|
||||
const vector<pair<pair<Expression*, pair<int, int>>, pair<Expression*, pair<int, int>>>>&
|
||||
const vector<pair<pair<Expression*, pair<int, int>>, pair<Expression*, pair<int, int>>>>&
|
||||
Array::GetSizesExpr()
|
||||
{
|
||||
if (templateDimsOrder.size() == 0)
|
||||
@@ -154,7 +154,7 @@ namespace Distribution
|
||||
}
|
||||
}
|
||||
|
||||
void printArrayInfo(const string &file, const map<tuple<int, string, string>, pair<Array*, ArrayAccessInfo*>> &declaredArrays)
|
||||
void printArrayInfo(const string& file, const map<tuple<int, string, string>, pair<Array*, ArrayAccessInfo*>>& 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<tuple<int, string, string>, pair<Array*, ArrayAccessInfo*>> &declaredArrays,
|
||||
const map<string, FuncInfo*> &allFuncs)
|
||||
void fixTypeOfArrayInfoWithCallGraph(map<tuple<int, string, string>, pair<Array*, ArrayAccessInfo*>>& declaredArrays,
|
||||
const map<string, FuncInfo*>& allFuncs)
|
||||
{
|
||||
for (auto& elem : declaredArrays)
|
||||
{
|
||||
|
||||
766
sapfor/experts/Sapfor_2017/_src/Distribution/ArrayAnalysis.cpp
Normal file
766
sapfor/experts/Sapfor_2017/_src/Distribution/ArrayAnalysis.cpp
Normal file
@@ -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<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 (privates.find(symb->identifier()) != privates.end() || isarrayInModule)
|
||||
{
|
||||
//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 (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<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;
|
||||
}
|
||||
@@ -197,15 +197,6 @@ static set<string> 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<pair<DIST::Array*, cons
|
||||
vector<SgStatement*> 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<string, set<SgSymbol*>> byUseInFunc = moduleRefsByUseInFunction(realStat);
|
||||
const int nested = countPerfectLoopNest(loopG);
|
||||
|
||||
@@ -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])
|
||||
{
|
||||
|
||||
@@ -391,6 +391,8 @@ public:
|
||||
|
||||
void analyzeParallelDirs();
|
||||
|
||||
void* getRealStat(const char* file) const;
|
||||
|
||||
public:
|
||||
int lineNum;
|
||||
int altLineNum;
|
||||
|
||||
@@ -62,7 +62,6 @@ extern REGIME currRegime;
|
||||
extern std::vector<Messages>* 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<pair<Expression*, Expression*>> getArraySizes(vector<pair<int, int>> &sizes, SgSymbol *symb, SgStatement *decl,
|
||||
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls,
|
||||
const map<string, vector<FuncInfo*>> &allFuncInfo)
|
||||
vector<pair<Expression*, Expression*>> getArraySizes(vector<pair<int, int>> &sizes, SgSymbol *symb, SgStatement *decl,
|
||||
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls,
|
||||
const map<string, vector<FuncInfo*>> &allFuncInfo)
|
||||
{
|
||||
SgArrayType *type = isSgArrayType(symb->type());
|
||||
vector<pair<Expression*, Expression*>> retVal;
|
||||
@@ -2616,758 +2615,6 @@ int getSizeOfType(SgType *t)
|
||||
return len;
|
||||
}
|
||||
|
||||
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 set<tuple<int, string, string>> 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<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();
|
||||
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<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 (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<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*> ®ions, 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 ® : 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;
|
||||
}
|
||||
|
||||
void insertSpfAnalysisBeforeParalleLoops(const vector<LoopGraph*> &loops)
|
||||
{
|
||||
for (auto &loop : loops)
|
||||
|
||||
@@ -33,6 +33,13 @@ void loopAnalyzer(SgFile *file,
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls,
|
||||
const std::map<SgStatement*, std::vector<DefUseList>> &defUseByPlace,
|
||||
bool skipDeps, std::vector<LoopGraph*> *loopGraph = NULL);
|
||||
|
||||
void fillFromModule(SgSymbol* s, const std::map<std::string, std::set<std::string>>& privatesByModule, std::set<std::string>& privates);
|
||||
|
||||
std::vector<std::pair<Expression*, Expression*>> getArraySizes(std::vector<std::pair<int, int>>& sizes, SgSymbol* symb, SgStatement* decl,
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
|
||||
const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
|
||||
|
||||
void arrayAccessAnalyzer(SgFile *file, std::vector<Messages> &messagesForFile,
|
||||
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays,
|
||||
REGIME regime);
|
||||
@@ -46,9 +53,6 @@ bool isIntrinsic(const char *funName);
|
||||
std::tuple<int, std::string, std::string> getUniqName(const std::map<std::string, SgStatement*> &commonBlocks, SgStatement *decl, SgSymbol *symb);
|
||||
std::string getShortName(const std::tuple<int, std::string, std::string> &uniqKey);
|
||||
|
||||
int getAllDeclaredArrays(SgFile *file, std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays,
|
||||
std::map<SgStatement*, std::set<std::tuple<int, std::string, std::string>>> &declaratedArraysSt, std::map<std::string, std::vector<Messages>> &currMessages,
|
||||
const std::vector<ParallelRegion*> ®ions, const std::map<std::string, int>& distrStateFromGUI);
|
||||
void insertSpfAnalysisBeforeParalleLoops(const std::vector<LoopGraph*> &loops);
|
||||
void recalculateArraySizes(std::set<DIST::Array*> &arraysDone, const std::set<DIST::Array*> &allArrays, const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
|
||||
int getSizeOfType(SgType* t);
|
||||
@@ -93,3 +97,8 @@ template<int NUM> bool createRemoteDir(SgStatement *st, const std::map<std::stri
|
||||
void groupActualAndRemote(SgFile* file, bool revert = false);
|
||||
|
||||
std::vector<SgStatement*> filterUserSpf(const std::vector<SgStatement*>& toFilter, bool with_omp = true);
|
||||
|
||||
// ArrayAnalysis.cpp
|
||||
int getAllDeclaredArrays(SgFile *file, std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays,
|
||||
std::map<SgStatement*, std::set<std::tuple<int, std::string, std::string>>> &declaratedArraysSt, std::map<std::string, std::vector<Messages>> &currMessages,
|
||||
const std::vector<ParallelRegion*> ®ions, const std::map<std::string, int>& distrStateFromGUI);
|
||||
@@ -439,7 +439,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
int global_err = 0;
|
||||
|
||||
map<string, int> same_decls;
|
||||
|
||||
|
||||
for (int i = n - 1; i >= 0; --i)
|
||||
{
|
||||
createNeededException();
|
||||
|
||||
@@ -2726,7 +2726,8 @@ SgStatement* makeDeclaration(SgStatement* curr, const vector<SgSymbol*>& 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);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_SPF "2368"
|
||||
#define VERSION_SPF "2372"
|
||||
|
||||
Reference in New Issue
Block a user