2 Commits

Author SHA1 Message Date
1522dc7f27 Merge branch 'master' into analyze_loops_with_IR 2024-11-21 21:27:58 +03:00
ALEXks
d6cb4c2a8a fixed remotes, shadows, array analysis 2024-11-21 15:07:16 +03:00
15 changed files with 822 additions and 791 deletions

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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());
}
}

View File

@@ -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);

View File

@@ -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)
{

View 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;
}

View File

@@ -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);

View File

@@ -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])
{

View File

@@ -391,6 +391,8 @@ public:
void analyzeParallelDirs();
void* getRealStat(const char* file) const;
public:
int lineNum;
int altLineNum;

View File

@@ -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*> &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;
}
void insertSpfAnalysisBeforeParalleLoops(const vector<LoopGraph*> &loops)
{
for (auto &loop : loops)

View File

@@ -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*> &regions, 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*> &regions, const std::map<std::string, int>& distrStateFromGUI);

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2368"
#define VERSION_SPF "2372"