fixed and improved OMP parser
This commit is contained in:
@@ -235,8 +235,8 @@ set(DATA_FLOW
|
|||||||
set(CREATE_INTER_T _src/CreateInterTree/CreateInterTree.cpp
|
set(CREATE_INTER_T _src/CreateInterTree/CreateInterTree.cpp
|
||||||
_src/CreateInterTree/CreateInterTree.h)
|
_src/CreateInterTree/CreateInterTree.h)
|
||||||
|
|
||||||
set(DIRA _src/DirectiveProcessing/DirectiveAnalyzer.cpp
|
set(DIRA _src/DirectiveProcessing/directive_analyzer.cpp
|
||||||
_src/DirectiveProcessing/DirectiveAnalyzer.h
|
_src/DirectiveProcessing/directive_analyzer.h
|
||||||
_src/DirectiveProcessing/directive_creator.cpp
|
_src/DirectiveProcessing/directive_creator.cpp
|
||||||
_src/DirectiveProcessing/directive_creator_base.cpp
|
_src/DirectiveProcessing/directive_creator_base.cpp
|
||||||
_src/DirectiveProcessing/directive_creator.h
|
_src/DirectiveProcessing/directive_creator.h
|
||||||
@@ -244,6 +244,8 @@ set(DIRA _src/DirectiveProcessing/DirectiveAnalyzer.cpp
|
|||||||
_src/DirectiveProcessing/directive_creator_nodist.h
|
_src/DirectiveProcessing/directive_creator_nodist.h
|
||||||
_src/DirectiveProcessing/directive_parser.cpp
|
_src/DirectiveProcessing/directive_parser.cpp
|
||||||
_src/DirectiveProcessing/directive_parser.h
|
_src/DirectiveProcessing/directive_parser.h
|
||||||
|
_src/DirectiveProcessing/directive_omp_parser.cpp
|
||||||
|
_src/DirectiveProcessing/directive_omp_parser.h
|
||||||
_src/DirectiveProcessing/insert_directive.cpp
|
_src/DirectiveProcessing/insert_directive.cpp
|
||||||
_src/DirectiveProcessing/insert_directive.h
|
_src/DirectiveProcessing/insert_directive.h
|
||||||
_src/DirectiveProcessing/remote_access.cpp
|
_src/DirectiveProcessing/remote_access.cpp
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include "../Distribution/DvmhDirective.h"
|
#include "../Distribution/DvmhDirective.h"
|
||||||
#include "../GraphLoop/graph_loops.h"
|
#include "../GraphLoop/graph_loops.h"
|
||||||
#include "DirectiveAnalyzer.h"
|
#include "directive_analyzer.h"
|
||||||
#include "../Utils/utils.h"
|
#include "../Utils/utils.h"
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
@@ -1091,6 +1091,9 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
|
|||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set<string> privates;
|
||||||
|
|
||||||
|
#if __SPF
|
||||||
tmpL = loop->parent;
|
tmpL = loop->parent;
|
||||||
while (tmpL)
|
while (tmpL)
|
||||||
{
|
{
|
||||||
@@ -1109,11 +1112,9 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
|
|||||||
tmpL = tmpL->parent;
|
tmpL = tmpL->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
set<string> privates;
|
|
||||||
#if __SPF
|
|
||||||
tryToFindPrivateInAttributes(loop->loop->GetOriginal(), privates);
|
tryToFindPrivateInAttributes(loop->loop->GetOriginal(), privates);
|
||||||
#else
|
#else
|
||||||
#error 'TODO - fill privates for this loop'
|
#error 'TODO - fill privates for this loop and check all inductive variables'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//try to resolve from write operations
|
//try to resolve from write operations
|
||||||
|
|||||||
@@ -0,0 +1,524 @@
|
|||||||
|
#include "../Utils/leak_detector.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "dvm.h"
|
||||||
|
#include "directive_omp_parser.h"
|
||||||
|
#include "directive_parser.h"
|
||||||
|
|
||||||
|
#include "../Utils/SgUtils.h"
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
using std::map;
|
||||||
|
using std::set;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
|
||||||
|
void removeOmpDir(SgStatement* st)
|
||||||
|
{
|
||||||
|
char* lineS = st->comments();
|
||||||
|
if (!lineS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vector<string> split;
|
||||||
|
splitString(lineS, '\n', split);
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
for (auto& elem : split)
|
||||||
|
{
|
||||||
|
string line = elem;
|
||||||
|
convertToLower(line);
|
||||||
|
if (line.substr(0, 5) == "!$omp")
|
||||||
|
lineS[idx + 1] = '_';
|
||||||
|
else if (line.substr(0, 3) == "!$ ")
|
||||||
|
lineS[idx + 1] = '_';
|
||||||
|
idx += line.size() + 1; // with '\n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void addToAttribute(SgStatement* st, int var, vector<SgExpression*> list)
|
||||||
|
{
|
||||||
|
if (list.size())
|
||||||
|
{
|
||||||
|
SgExprListExp* ex = new SgExprListExp();
|
||||||
|
ex->setLhs(new SgExpression(var, makeExprList(list), NULL));
|
||||||
|
SgStatement* toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, ex, NULL, NULL);
|
||||||
|
toAdd->setlineNumber(st->lineNumber());
|
||||||
|
toAdd->setLocalLineNumber(888);
|
||||||
|
|
||||||
|
//filter
|
||||||
|
if (var == ACC_PRIVATE_OP)
|
||||||
|
{
|
||||||
|
vector<SgExpression*> list_new;
|
||||||
|
|
||||||
|
auto attributes = getAttributes<SgStatement*, SgStatement*>(st, set<int>{SPF_ANALYSIS_DIR});
|
||||||
|
set<string> privates;
|
||||||
|
for (auto& attr : attributes)
|
||||||
|
fillPrivatesFromComment(new Statement(attr), privates);
|
||||||
|
|
||||||
|
if (privates.size())
|
||||||
|
{
|
||||||
|
for (auto& elem : list)
|
||||||
|
if (privates.find(elem->unparse()) == privates.end())
|
||||||
|
list_new.push_back(elem);
|
||||||
|
list = list_new;
|
||||||
|
|
||||||
|
if (!list.size())
|
||||||
|
{
|
||||||
|
__spf_print(1, "-- skip privates on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (var == REDUCTION_OP)
|
||||||
|
{
|
||||||
|
auto attributes = getAttributes<SgStatement*, SgStatement*>(st, set<int>{SPF_ANALYSIS_DIR});
|
||||||
|
map<string, set<string>> reduction;
|
||||||
|
for (auto& attr : attributes)
|
||||||
|
fillReductionsFromComment(new Statement(attr), reduction);
|
||||||
|
|
||||||
|
map<string, set<string>> reductionToAdd;
|
||||||
|
fillReductionsFromComment(new Statement(toAdd), reductionToAdd);
|
||||||
|
|
||||||
|
vector<SgExpression*> list_new;
|
||||||
|
if (reduction.size())
|
||||||
|
{
|
||||||
|
if (reduction == reductionToAdd)
|
||||||
|
{
|
||||||
|
__spf_print(1, "-- skip reduction on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<string, set<string>> reductionToAddNew;
|
||||||
|
for (auto& redPair : reductionToAdd)
|
||||||
|
{
|
||||||
|
auto it = reduction.find(redPair.first);
|
||||||
|
if (it == reduction.end())
|
||||||
|
reductionToAddNew[redPair.first] = redPair.second;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set<string> newVar;
|
||||||
|
for (auto& var : redPair.second)
|
||||||
|
{
|
||||||
|
auto itVar = it->second.find(var);
|
||||||
|
if (itVar == it->second.end())
|
||||||
|
reductionToAddNew[redPair.first].insert(var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reductionToAddNew.size())
|
||||||
|
{
|
||||||
|
__spf_print(1, "-- skip reduction on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reductionToAddNew != reductionToAdd)
|
||||||
|
{
|
||||||
|
list.clear();
|
||||||
|
for (auto& redPair : reductionToAddNew)
|
||||||
|
for (auto& var : redPair.second)
|
||||||
|
list.push_back(new SgExpression(ARRAY_OP,
|
||||||
|
new SgKeywordValExp(redPair.first.c_str()),
|
||||||
|
new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st)))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ex = new SgExprListExp();
|
||||||
|
ex->setLhs(new SgExpression(var, makeExprList(list), NULL));
|
||||||
|
toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, ex, NULL, NULL);
|
||||||
|
|
||||||
|
st->addAttribute(SPF_ANALYSIS_DIR, toAdd, sizeof(SgStatement));
|
||||||
|
|
||||||
|
if (var == ACC_PRIVATE_OP)
|
||||||
|
__spf_print(1, "-- set private attribute to line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
||||||
|
else if (var == REDUCTION_OP)
|
||||||
|
__spf_print(1, "-- set reduction attribute to line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_write_in_do(SgStatement* st, const string& var)
|
||||||
|
{
|
||||||
|
checkNull(st, convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
|
if (st->variant() != FOR_NODE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||||
|
for (SgStatement* op = st->lexNext(); st != lastNode; st = st->lexNext())
|
||||||
|
{
|
||||||
|
if (st->variant() == ASSIGN_STAT)
|
||||||
|
{
|
||||||
|
SgExpression* ex = st->expr(0);
|
||||||
|
if (ex->variant() == ARRAY_REF || ex->variant() == VAR_REF)
|
||||||
|
if (var == ex->symbol()->identifier())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (st->variant() == FOR_NODE)
|
||||||
|
{
|
||||||
|
if (var == isSgForStmt(st)->doName()->identifier())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<OmpDir> parseOmpInStatement(SgStatement* st, const set<string>& globalPriv, bool forDo)
|
||||||
|
{
|
||||||
|
vector<OmpDir> resultAll;
|
||||||
|
|
||||||
|
const char* lineS = st->comments();
|
||||||
|
if (!lineS)
|
||||||
|
return resultAll;
|
||||||
|
|
||||||
|
string comment(lineS);
|
||||||
|
convertToLower(comment);
|
||||||
|
|
||||||
|
vector<string> split;
|
||||||
|
splitString(comment, '\n', split);
|
||||||
|
|
||||||
|
for (int z = split.size() - 1; z >= 0; z--)
|
||||||
|
{
|
||||||
|
string line = split[z];
|
||||||
|
|
||||||
|
if (line.substr(0, 6) == "!$omp&")
|
||||||
|
{
|
||||||
|
if (z - 1 < 0)
|
||||||
|
break;
|
||||||
|
split[z - 1] += line.substr(6);
|
||||||
|
split[z] = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& line : split)
|
||||||
|
{
|
||||||
|
if (line.substr(0, 5) == "!$omp")
|
||||||
|
{
|
||||||
|
OmpDir result;
|
||||||
|
|
||||||
|
string line1 = "";
|
||||||
|
int space = 0;
|
||||||
|
int brake = 0;
|
||||||
|
for (int z = 0; z < line.size(); ++z)
|
||||||
|
{
|
||||||
|
if (brake < 0)
|
||||||
|
return vector<OmpDir>(); // error
|
||||||
|
|
||||||
|
if (brake == 0)
|
||||||
|
{
|
||||||
|
if (line[z] == ' ')
|
||||||
|
space++;
|
||||||
|
else
|
||||||
|
space = 0;
|
||||||
|
if ((line[z] == ' ' && space <= 1) || line[z] != ' ')
|
||||||
|
line1 += line[z];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (line[z] != ' ')
|
||||||
|
line1 += line[z];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line[z] == '(')
|
||||||
|
{
|
||||||
|
while (line1.size() > 2 && line1[line1.size() - 2] == ' ')
|
||||||
|
line1 = line1.erase(line1.size() - 2, 1);
|
||||||
|
brake++;
|
||||||
|
space = 0;
|
||||||
|
}
|
||||||
|
else if (line[z] == ')')
|
||||||
|
brake--;
|
||||||
|
}
|
||||||
|
vector<string> lexems;
|
||||||
|
splitString(line1, ' ', lexems);
|
||||||
|
bool doLexem = false;
|
||||||
|
bool end = false;
|
||||||
|
bool parallel = false;
|
||||||
|
bool privat = false;
|
||||||
|
|
||||||
|
for (auto& lexem : lexems)
|
||||||
|
{
|
||||||
|
if (lexem == "do")
|
||||||
|
{
|
||||||
|
doLexem = true;
|
||||||
|
result.keys.insert(lexem);
|
||||||
|
}
|
||||||
|
if (lexem == "end")
|
||||||
|
{
|
||||||
|
end = true;
|
||||||
|
result.keys.insert(lexem);
|
||||||
|
}
|
||||||
|
if (lexem == "parallel")
|
||||||
|
{
|
||||||
|
parallel = true;
|
||||||
|
result.keys.insert(lexem);
|
||||||
|
}
|
||||||
|
if (lexem == "private")
|
||||||
|
{
|
||||||
|
privat = true;
|
||||||
|
result.keys.insert(lexem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (privat == false)
|
||||||
|
{
|
||||||
|
if (forDo && doLexem)
|
||||||
|
{
|
||||||
|
vector<SgExpression*> list;
|
||||||
|
for (auto& var : globalPriv)
|
||||||
|
if (is_write_in_do(st, var))
|
||||||
|
list.push_back(new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st))));
|
||||||
|
|
||||||
|
if (list.size())
|
||||||
|
addToAttribute(st, ACC_PRIVATE_OP, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& lexem : lexems)
|
||||||
|
{
|
||||||
|
bool priv = lexem.substr(0, strlen("private(")) == "private(";
|
||||||
|
bool threadpriv = lexem.substr(0, strlen("threadprivate(")) == "threadprivate(";
|
||||||
|
bool red = lexem.substr(0, strlen("reduction(")) == "reduction(";
|
||||||
|
if (priv || threadpriv)
|
||||||
|
{
|
||||||
|
vector<string> sublex;
|
||||||
|
splitString(lexem, '(', sublex);
|
||||||
|
if (sublex.size() == 2 && lexem.back() == ')')
|
||||||
|
{
|
||||||
|
splitString(sublex[1].erase(sublex[1].size() - 1), ',', sublex);
|
||||||
|
|
||||||
|
vector<SgExpression*> list;
|
||||||
|
set<string> uniqList;
|
||||||
|
for (auto& varG : globalPriv)
|
||||||
|
uniqList.insert(varG);
|
||||||
|
|
||||||
|
for (auto& var : sublex)
|
||||||
|
uniqList.insert(var);
|
||||||
|
|
||||||
|
for (auto& var : uniqList)
|
||||||
|
{
|
||||||
|
if (priv)
|
||||||
|
{
|
||||||
|
result.privVars.insert(var);
|
||||||
|
list.push_back(new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result.threadPrivVars.insert(var);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forDo && doLexem && priv)
|
||||||
|
addToAttribute(st, ACC_PRIVATE_OP, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (red)
|
||||||
|
{
|
||||||
|
vector<string> sublex;
|
||||||
|
splitString(lexem, '(', sublex);
|
||||||
|
if (sublex.size() == 2 && lexem.back() == ')')
|
||||||
|
{
|
||||||
|
splitString(sublex[1].erase(sublex[1].size() - 1), ':', sublex);
|
||||||
|
|
||||||
|
vector<string> vars;
|
||||||
|
vector<SgExpression*> list;
|
||||||
|
splitString(sublex[1], ',', vars);
|
||||||
|
string op = "";
|
||||||
|
|
||||||
|
if (sublex[0] == "+")
|
||||||
|
op = "sum";
|
||||||
|
else if (sublex[0] == "*")
|
||||||
|
op = "prod";
|
||||||
|
else if (sublex[0] == "max")
|
||||||
|
op = "max";
|
||||||
|
else if (sublex[0] == "min")
|
||||||
|
op = "min";
|
||||||
|
else if (sublex[0] == ".or." || sublex[0] == "or")
|
||||||
|
op = "or";
|
||||||
|
else if (sublex[0] == ".and." || sublex[0] == "and")
|
||||||
|
op = "and";
|
||||||
|
else if (sublex[0] == ".eqv." || sublex[0] == "eqv")
|
||||||
|
op = "eqv";
|
||||||
|
else if (sublex[0] == ".neqv." || sublex[0] == "neqv")
|
||||||
|
op = "neqv";
|
||||||
|
|
||||||
|
if (op != "")
|
||||||
|
{
|
||||||
|
for (auto& var : vars)
|
||||||
|
{
|
||||||
|
result.redVars[sublex[0]].insert(var);
|
||||||
|
list.push_back(new SgExpression(ARRAY_OP, new SgKeywordValExp(op.c_str()), new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st)))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forDo && doLexem && op != "")
|
||||||
|
addToAttribute(st, REDUCTION_OP, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resultAll.push_back(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: need to use IR and RD for checking
|
||||||
|
static void filterPrivates(OmpDir& dir)
|
||||||
|
{
|
||||||
|
if (dir.privVars.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto st = dir.start; st != dir.end; st = st->lexNext())
|
||||||
|
{
|
||||||
|
vector<OmpDir> res;
|
||||||
|
if (st != dir.start)
|
||||||
|
{
|
||||||
|
set<string> dummy;
|
||||||
|
res = parseOmpInStatement(st, dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasParallelDo = false;
|
||||||
|
for (auto& dir : res)
|
||||||
|
{
|
||||||
|
if (dir.keys.find("parallel") != dir.keys.end() ||
|
||||||
|
dir.keys.find("do") != dir.keys.end())
|
||||||
|
{
|
||||||
|
hasParallelDo = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.size() == 0 || !hasParallelDo)
|
||||||
|
{
|
||||||
|
if (st->variant() == ASSIGN_STAT)
|
||||||
|
{
|
||||||
|
if (st->expr(0))
|
||||||
|
{
|
||||||
|
string ref = st->expr(0)->symbol()->identifier();
|
||||||
|
dir.privVars.erase(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<OmpDir> findAllGlobalParallelRegions(SgStatement* stFunc)
|
||||||
|
{
|
||||||
|
vector<OmpDir> sections;
|
||||||
|
|
||||||
|
SgStatement* lastNode = stFunc->lastNodeOfStmt();
|
||||||
|
for (auto st = stFunc; st != lastNode; st = st->lexNext())
|
||||||
|
{
|
||||||
|
if (st == NULL)
|
||||||
|
{
|
||||||
|
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->variant() == CONTAINS_STMT)
|
||||||
|
break;
|
||||||
|
|
||||||
|
set<string> dummy;
|
||||||
|
auto res = parseOmpInStatement(st, dummy);
|
||||||
|
|
||||||
|
for (auto& dir : res)
|
||||||
|
{
|
||||||
|
auto end = dir.keys.end();
|
||||||
|
if (dir.keys.find("parallel") != end
|
||||||
|
&& dir.keys.find("do") == end
|
||||||
|
&& dir.keys.find("end") == end)
|
||||||
|
{
|
||||||
|
if (sections.size() && sections.back().end == NULL) // has open parallel region
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
sections.push_back(dir);
|
||||||
|
sections.back().start = st;
|
||||||
|
}
|
||||||
|
else if (dir.keys.find("parallel") != end
|
||||||
|
&& dir.keys.find("do") == end
|
||||||
|
&& dir.keys.find("end") != end)
|
||||||
|
{
|
||||||
|
sections.back().end = st;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& dir : sections)
|
||||||
|
filterPrivates(dir);
|
||||||
|
|
||||||
|
return sections;
|
||||||
|
}
|
||||||
|
|
||||||
|
static set<string> getGlobalPrivate(SgStatement* st, const vector<OmpDir>& globalParallelRegions)
|
||||||
|
{
|
||||||
|
set<string> globalPrivates;
|
||||||
|
const int line = st->lineNumber();
|
||||||
|
if (line > 0)
|
||||||
|
{
|
||||||
|
for (auto& reg : globalParallelRegions)
|
||||||
|
{
|
||||||
|
if (reg.start->lineNumber() <= line && line < reg.end->lineNumber())
|
||||||
|
{
|
||||||
|
if (reg.privVars.size())
|
||||||
|
return reg.privVars;
|
||||||
|
else
|
||||||
|
return globalPrivates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& reg : globalParallelRegions)
|
||||||
|
{
|
||||||
|
for (auto stF = reg.start; stF != reg.end; stF = stF->lexNext())
|
||||||
|
{
|
||||||
|
if (st == stF)
|
||||||
|
{
|
||||||
|
if (reg.privVars.size())
|
||||||
|
return reg.privVars;
|
||||||
|
else
|
||||||
|
return globalPrivates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return globalPrivates;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseOmpDirectives(SgFile* file, vector<Messages>& currMessages)
|
||||||
|
{
|
||||||
|
int funcNum = file->numberOfFunctions();
|
||||||
|
|
||||||
|
for (int i = 0; i < funcNum; ++i)
|
||||||
|
{
|
||||||
|
SgStatement* st = file->functions(i);
|
||||||
|
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||||
|
|
||||||
|
vector<OmpDir> globalParallelRegions = findAllGlobalParallelRegions(st);
|
||||||
|
|
||||||
|
while (st != lastNode)
|
||||||
|
{
|
||||||
|
if (st == NULL)
|
||||||
|
{
|
||||||
|
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->variant() == CONTAINS_STMT)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (st->variant() == FOR_NODE)
|
||||||
|
{
|
||||||
|
SgForStmt* currSt = (SgForStmt*)st;
|
||||||
|
if (currSt->isEnddoLoop() == 0)
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
else
|
||||||
|
parseOmpInStatement(st, getGlobalPrivate(st, globalParallelRegions), true);
|
||||||
|
}
|
||||||
|
st = st->lexNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../Utils/errors.h"
|
||||||
|
|
||||||
|
struct OmpDir
|
||||||
|
{
|
||||||
|
std::set<std::string> privVars;
|
||||||
|
std::set<std::string> threadPrivVars;
|
||||||
|
std::map<std::string, std::set<std::string>> redVars;
|
||||||
|
std::set<std::string> keys;
|
||||||
|
|
||||||
|
SgStatement* start = NULL;
|
||||||
|
SgStatement* end = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
void removeOmpDir(SgStatement* st);
|
||||||
|
std::vector<OmpDir> parseOmpInStatement(SgStatement* st, const std::set<std::string>& globalPriv, bool forDo = false);
|
||||||
|
void parseOmpDirectives(SgFile* file, std::vector<Messages>& currMessages);
|
||||||
@@ -594,350 +594,3 @@ void fillInfoFromDirectives(const LoopGraph *loopInfo, ParallelDirective *direct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeOmpDir(void* stIn)
|
|
||||||
{
|
|
||||||
SgStatement* st = (SgStatement*)stIn;
|
|
||||||
|
|
||||||
char* lineS = st->comments();
|
|
||||||
if (!lineS)
|
|
||||||
return;
|
|
||||||
|
|
||||||
vector<string> split;
|
|
||||||
splitString(lineS, '\n', split);
|
|
||||||
|
|
||||||
int idx = 0;
|
|
||||||
for (auto& elem : split)
|
|
||||||
{
|
|
||||||
string line = elem;
|
|
||||||
convertToLower(line);
|
|
||||||
if (line.substr(0, 5) == "!$omp")
|
|
||||||
lineS[idx + 1] = '_';
|
|
||||||
else if (line.substr(0, 3) == "!$ ")
|
|
||||||
lineS[idx + 1] = '_';
|
|
||||||
idx += line.size() + 1; // with '\n'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void addToAttribute(SgStatement* st, int var, vector<SgExpression*> list)
|
|
||||||
{
|
|
||||||
if (list.size())
|
|
||||||
{
|
|
||||||
SgExprListExp* ex = new SgExprListExp();
|
|
||||||
ex->setLhs(new SgExpression(var, makeExprList(list), NULL));
|
|
||||||
SgStatement* toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, ex, NULL, NULL);
|
|
||||||
toAdd->setlineNumber(st->lineNumber());
|
|
||||||
toAdd->setLocalLineNumber(888);
|
|
||||||
|
|
||||||
//filter
|
|
||||||
if (var == ACC_PRIVATE_OP)
|
|
||||||
{
|
|
||||||
vector<SgExpression*> list_new;
|
|
||||||
|
|
||||||
auto attributes = getAttributes<SgStatement*, SgStatement*>(st, set<int>{SPF_ANALYSIS_DIR});
|
|
||||||
set<string> privates;
|
|
||||||
for (auto& attr : attributes)
|
|
||||||
fillPrivatesFromComment(new Statement(attr), privates);
|
|
||||||
|
|
||||||
if (privates.size())
|
|
||||||
{
|
|
||||||
for (auto& elem : list)
|
|
||||||
if (privates.find(elem->unparse()) == privates.end())
|
|
||||||
list_new.push_back(elem);
|
|
||||||
list = list_new;
|
|
||||||
|
|
||||||
if (!list.size())
|
|
||||||
{
|
|
||||||
__spf_print(1, "-- skip privates on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (var == REDUCTION_OP)
|
|
||||||
{
|
|
||||||
auto attributes = getAttributes<SgStatement*, SgStatement*>(st, set<int>{SPF_ANALYSIS_DIR});
|
|
||||||
map<string, set<string>> reduction;
|
|
||||||
for (auto& attr : attributes)
|
|
||||||
fillReductionsFromComment(new Statement(attr), reduction);
|
|
||||||
|
|
||||||
map<string, set<string>> reductionToAdd;
|
|
||||||
fillReductionsFromComment(new Statement(st), reductionToAdd);
|
|
||||||
|
|
||||||
vector<SgExpression*> list_new;
|
|
||||||
if (reduction.size())
|
|
||||||
{
|
|
||||||
if (reduction == reductionToAdd)
|
|
||||||
{
|
|
||||||
__spf_print(1, "-- skip reduction on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
map<string, set<string>> reductionToAddNew;
|
|
||||||
for (auto& redPair : reductionToAdd)
|
|
||||||
{
|
|
||||||
auto it = reduction.find(redPair.first);
|
|
||||||
if (it == reduction.end())
|
|
||||||
reductionToAddNew[redPair.first] = redPair.second;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set<string> newVar;
|
|
||||||
for (auto& var : redPair.second)
|
|
||||||
{
|
|
||||||
auto itVar = it->second.find(var);
|
|
||||||
if (itVar == it->second.end())
|
|
||||||
reductionToAddNew[redPair.first].insert(var);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reductionToAddNew.size())
|
|
||||||
{
|
|
||||||
__spf_print(1, "-- skip reduction on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reductionToAddNew != reductionToAdd)
|
|
||||||
{
|
|
||||||
list.clear();
|
|
||||||
for (auto& redPair : reductionToAddNew)
|
|
||||||
for (auto& var : redPair.second)
|
|
||||||
list.push_back(new SgExpression(ARRAY_OP,
|
|
||||||
new SgKeywordValExp(redPair.first.c_str()),
|
|
||||||
new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st)))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ex = new SgExprListExp();
|
|
||||||
ex->setLhs(new SgExpression(var, makeExprList(list), NULL));
|
|
||||||
toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, ex, NULL, NULL);
|
|
||||||
|
|
||||||
st->addAttribute(SPF_ANALYSIS_DIR, toAdd, sizeof(SgStatement));
|
|
||||||
|
|
||||||
if (var == ACC_PRIVATE_OP)
|
|
||||||
__spf_print(1, "-- set private attribute to line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
|
||||||
else if (var == REDUCTION_OP)
|
|
||||||
__spf_print(1, "-- set reduction attribute to line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_private_in_do(SgStatement* st, const string& var)
|
|
||||||
{
|
|
||||||
checkNull(st, convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
|
|
||||||
if (st->variant() != FOR_NODE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SgStatement* lastNode = st->lastNodeOfStmt();
|
|
||||||
for (SgStatement* op = st->lexNext(); st != lastNode; st = st->lexNext())
|
|
||||||
{
|
|
||||||
if (st->variant() == ASSIGN_STAT)
|
|
||||||
{
|
|
||||||
SgExpression* ex = st->expr(0);
|
|
||||||
if (ex->variant() == ARRAY_REF || ex->variant() == VAR_REF)
|
|
||||||
if (var == ex->symbol()->identifier())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<OmpDir> parseOmpDirs(void* stIn, const set<string> &globalPriv, bool forDo)
|
|
||||||
{
|
|
||||||
SgStatement* st = (SgStatement*)stIn;
|
|
||||||
vector<OmpDir> resultAll;
|
|
||||||
|
|
||||||
const char* lineS = st->comments();
|
|
||||||
if (!lineS)
|
|
||||||
return resultAll;
|
|
||||||
|
|
||||||
string comment(lineS);
|
|
||||||
convertToLower(comment);
|
|
||||||
|
|
||||||
vector<string> split;
|
|
||||||
splitString(comment, '\n', split);
|
|
||||||
|
|
||||||
for (int z = split.size() - 1; z >= 0; z--)
|
|
||||||
{
|
|
||||||
string line = split[z];
|
|
||||||
|
|
||||||
if (line.substr(0, 6) == "!$omp&")
|
|
||||||
{
|
|
||||||
if (z - 1 < 0)
|
|
||||||
break;
|
|
||||||
split[z - 1] += line.substr(6);
|
|
||||||
split[z] = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& line : split)
|
|
||||||
{
|
|
||||||
if (line.substr(0, 5) == "!$omp")
|
|
||||||
{
|
|
||||||
OmpDir result;
|
|
||||||
|
|
||||||
string line1 = "";
|
|
||||||
int space = 0;
|
|
||||||
int brake = 0;
|
|
||||||
for (int z = 0; z < line.size(); ++z)
|
|
||||||
{
|
|
||||||
if (brake < 0)
|
|
||||||
return vector<OmpDir>(); // error
|
|
||||||
|
|
||||||
if (brake == 0)
|
|
||||||
{
|
|
||||||
if (line[z] == ' ')
|
|
||||||
space++;
|
|
||||||
else
|
|
||||||
space = 0;
|
|
||||||
if ((line[z] == ' ' && space <= 1) || line[z] != ' ')
|
|
||||||
line1 += line[z];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (line[z] != ' ')
|
|
||||||
line1 += line[z];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line[z] == '(')
|
|
||||||
{
|
|
||||||
while (line1.size() > 2 && line1[line1.size() - 2] == ' ')
|
|
||||||
line1 = line1.erase(line1.size() - 2, 1);
|
|
||||||
brake++;
|
|
||||||
space = 0;
|
|
||||||
}
|
|
||||||
else if (line[z] == ')')
|
|
||||||
brake--;
|
|
||||||
}
|
|
||||||
vector<string> lexems;
|
|
||||||
splitString(line1, ' ', lexems);
|
|
||||||
bool doLexem = false;
|
|
||||||
bool end = false;
|
|
||||||
bool parallel = false;
|
|
||||||
bool privat = false;
|
|
||||||
|
|
||||||
for (auto& lexem : lexems)
|
|
||||||
{
|
|
||||||
if (lexem == "do")
|
|
||||||
{
|
|
||||||
doLexem = true;
|
|
||||||
result.keys.insert(lexem);
|
|
||||||
}
|
|
||||||
if (lexem == "end")
|
|
||||||
{
|
|
||||||
end = true;
|
|
||||||
result.keys.insert(lexem);
|
|
||||||
}
|
|
||||||
if (lexem == "parallel")
|
|
||||||
{
|
|
||||||
parallel = true;
|
|
||||||
result.keys.insert(lexem);
|
|
||||||
}
|
|
||||||
if (lexem == "private")
|
|
||||||
{
|
|
||||||
privat = true;
|
|
||||||
result.keys.insert(lexem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (privat == false)
|
|
||||||
{
|
|
||||||
if (forDo && doLexem)
|
|
||||||
{
|
|
||||||
vector<SgExpression*> list;
|
|
||||||
for (auto& var : globalPriv)
|
|
||||||
if (is_private_in_do(st, var))
|
|
||||||
list.push_back(new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st))));
|
|
||||||
|
|
||||||
if (list.size())
|
|
||||||
addToAttribute(st, ACC_PRIVATE_OP, list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& lexem : lexems)
|
|
||||||
{
|
|
||||||
bool priv = lexem.substr(0, strlen("private(")) == "private(";
|
|
||||||
bool threadpriv = lexem.substr(0, strlen("threadprivate(")) == "threadprivate(";
|
|
||||||
bool red = lexem.substr(0, strlen("reduction(")) == "reduction(";
|
|
||||||
if (priv || threadpriv)
|
|
||||||
{
|
|
||||||
vector<string> sublex;
|
|
||||||
splitString(lexem, '(', sublex);
|
|
||||||
if (sublex.size() == 2 && lexem.back() == ')')
|
|
||||||
{
|
|
||||||
splitString(sublex[1].erase(sublex[1].size() - 1), ',', sublex);
|
|
||||||
|
|
||||||
vector<SgExpression*> list;
|
|
||||||
set<string> uniqList;
|
|
||||||
for (auto& varG : globalPriv)
|
|
||||||
uniqList.insert(varG);
|
|
||||||
|
|
||||||
for (auto& var : sublex)
|
|
||||||
uniqList.insert(var);
|
|
||||||
|
|
||||||
for (auto& var : uniqList)
|
|
||||||
{
|
|
||||||
if (priv)
|
|
||||||
{
|
|
||||||
result.privVars.insert(var);
|
|
||||||
list.push_back(new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st))));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result.threadPrivVars.insert(var);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (forDo && doLexem && priv)
|
|
||||||
addToAttribute(st, ACC_PRIVATE_OP, list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (red)
|
|
||||||
{
|
|
||||||
vector<string> sublex;
|
|
||||||
splitString(lexem, '(', sublex);
|
|
||||||
if (sublex.size() == 2 && lexem.back() == ')')
|
|
||||||
{
|
|
||||||
splitString(sublex[1].erase(sublex[1].size() - 1), ':', sublex);
|
|
||||||
|
|
||||||
vector<string> vars;
|
|
||||||
vector<SgExpression*> list;
|
|
||||||
splitString(sublex[1], ',', vars);
|
|
||||||
string op = "";
|
|
||||||
|
|
||||||
if (sublex[0] == "+")
|
|
||||||
op = "sum";
|
|
||||||
else if (sublex[0] == "*")
|
|
||||||
op = "prod";
|
|
||||||
else if (sublex[0] == "max")
|
|
||||||
op = "max";
|
|
||||||
else if (sublex[0] == "min")
|
|
||||||
op = "min";
|
|
||||||
else if (sublex[0] == ".or." || sublex[0] == "or")
|
|
||||||
op = "or";
|
|
||||||
else if (sublex[0] == ".and." || sublex[0] == "and")
|
|
||||||
op = "and";
|
|
||||||
else if (sublex[0] == ".eqv." || sublex[0] == "eqv")
|
|
||||||
op = "eqv";
|
|
||||||
else if (sublex[0] == ".neqv." || sublex[0] == "neqv")
|
|
||||||
op = "neqv";
|
|
||||||
|
|
||||||
if (op != "")
|
|
||||||
{
|
|
||||||
for (auto& var : vars)
|
|
||||||
{
|
|
||||||
result.redVars[sublex[0]].insert(var);
|
|
||||||
list.push_back(new SgExpression(ARRAY_OP, new SgKeywordValExp(op.c_str()), new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st)))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (forDo && doLexem && op != "")
|
|
||||||
addToAttribute(st, REDUCTION_OP, list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resultAll.push_back(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultAll;
|
|
||||||
}
|
|
||||||
@@ -40,14 +40,3 @@ void fillShrinkFromComment(Statement *stIn, std::vector<std::pair<fillType, std:
|
|||||||
|
|
||||||
template<typename fillType>
|
template<typename fillType>
|
||||||
void fillCheckpointFromComment(Statement *stIn, std::map<int, Expression*> &clauses, std::set<fillType> &vars, std::set<fillType> &expt);
|
void fillCheckpointFromComment(Statement *stIn, std::map<int, Expression*> &clauses, std::set<fillType> &vars, std::set<fillType> &expt);
|
||||||
|
|
||||||
struct OmpDir
|
|
||||||
{
|
|
||||||
std::set<std::string> privVars;
|
|
||||||
std::set<std::string> threadPrivVars;
|
|
||||||
std::map<std::string, std::set<std::string>> redVars;
|
|
||||||
std::set<std::string> keys;
|
|
||||||
};
|
|
||||||
|
|
||||||
void removeOmpDir(void* stIn);
|
|
||||||
std::vector<OmpDir> parseOmpDirs(void* st, const std::set<std::string>& globalPriv, bool forDo = false);
|
|
||||||
@@ -2121,6 +2121,23 @@ static bool moveSpfParameterForImplicitLoops(SgStatement* st, SgStatement* toAdd
|
|||||||
return moveNext;
|
return moveNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void insertBefore(SgStatement* st, SgStatement* toAdd)
|
||||||
|
{
|
||||||
|
if (toAdd == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
st->insertStmtBefore(*toAdd, *st->controlParent());
|
||||||
|
if (st->variant() == FOR_NODE)
|
||||||
|
{
|
||||||
|
auto com = st->comments();
|
||||||
|
if (com)
|
||||||
|
{
|
||||||
|
st->lexPrev()->addComment(com);
|
||||||
|
st->delComments();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void revertion_spf_dirs(SgFile *file,
|
void revertion_spf_dirs(SgFile *file,
|
||||||
map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays,
|
map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays,
|
||||||
map<SgStatement*, set<tuple<int, string, string>>> declaratedArraysSt)
|
map<SgStatement*, set<tuple<int, string, string>>> declaratedArraysSt)
|
||||||
@@ -2163,7 +2180,7 @@ void revertion_spf_dirs(SgFile *file,
|
|||||||
toAdd = UniteAttributes(sameAtt);
|
toAdd = UniteAttributes(sameAtt);
|
||||||
if (toAdd)
|
if (toAdd)
|
||||||
if (!moveSpfParameterForImplicitLoops(st, toAdd))
|
if (!moveSpfParameterForImplicitLoops(st, toAdd))
|
||||||
st->insertStmtBefore(*toAdd, *st->controlParent());
|
insertBefore(st, toAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
//check previosly directives SPF_PARALLEL
|
//check previosly directives SPF_PARALLEL
|
||||||
@@ -2174,7 +2191,7 @@ void revertion_spf_dirs(SgFile *file,
|
|||||||
{
|
{
|
||||||
if (toAdd)
|
if (toAdd)
|
||||||
toAdd = UniteAttributes(sameAtt);
|
toAdd = UniteAttributes(sameAtt);
|
||||||
st->insertStmtBefore(*toAdd, *st->controlParent());
|
insertBefore(st, toAdd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2188,7 +2205,7 @@ void revertion_spf_dirs(SgFile *file,
|
|||||||
SgStatement *toAdd = &(data->copy());
|
SgStatement *toAdd = &(data->copy());
|
||||||
|
|
||||||
if (toAdd)
|
if (toAdd)
|
||||||
st->insertStmtBefore(*toAdd, *st->controlParent());
|
insertBefore(st, toAdd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "loop_analyzer_internal.h"
|
#include "loop_analyzer_internal.h"
|
||||||
#include "loop_analyzer.h"
|
#include "loop_analyzer.h"
|
||||||
|
#include "../DirectiveProcessing/directive_omp_parser.h"
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::pair;
|
using std::pair;
|
||||||
@@ -2598,7 +2599,7 @@ static bool findOmpThreadPrivDecl(SgStatement* st, map<SgStatement*, set<string>
|
|||||||
{
|
{
|
||||||
st = st->lexNext();
|
st = st->lexNext();
|
||||||
|
|
||||||
auto res = parseOmpDirs(st, dummy);
|
auto res = parseOmpInStatement(st, dummy);
|
||||||
for (auto& dir : res)
|
for (auto& dir : res)
|
||||||
for (auto& var : dir.threadPrivVars)
|
for (auto& var : dir.threadPrivVars)
|
||||||
it->second.insert(var);
|
it->second.insert(var);
|
||||||
|
|||||||
@@ -46,10 +46,11 @@
|
|||||||
#include "DynamicAnalysis/gCov_parser_func.h"
|
#include "DynamicAnalysis/gCov_parser_func.h"
|
||||||
#include "DynamicAnalysis/createParallelRegions.h"
|
#include "DynamicAnalysis/createParallelRegions.h"
|
||||||
|
|
||||||
#include "DirectiveProcessing/DirectiveAnalyzer.h"
|
#include "DirectiveProcessing/directive_analyzer.h"
|
||||||
#include "DirectiveProcessing/directive_creator.h"
|
#include "DirectiveProcessing/directive_creator.h"
|
||||||
#include "DirectiveProcessing/directive_creator_nodist.h"
|
#include "DirectiveProcessing/directive_creator_nodist.h"
|
||||||
#include "DirectiveProcessing/insert_directive.h"
|
#include "DirectiveProcessing/insert_directive.h"
|
||||||
|
#include "DirectiveProcessing/directive_omp_parser.h"
|
||||||
#include "VerificationCode/verifications.h"
|
#include "VerificationCode/verifications.h"
|
||||||
#include "Distribution/CreateDistributionDirs.h"
|
#include "Distribution/CreateDistributionDirs.h"
|
||||||
#include "PrivateAnalyzer/private_analyzer.h"
|
#include "PrivateAnalyzer/private_analyzer.h"
|
||||||
@@ -1007,6 +1008,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
|
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
|
||||||
removeOmpDir(st);
|
removeOmpDir(st);
|
||||||
}
|
}
|
||||||
|
else if (curr_regime == PARSE_OMP_DIRS)
|
||||||
|
parseOmpDirectives(file, getObjectForFileFromMap(file_name, SPF_messages));
|
||||||
else if (curr_regime == REMOVE_COMMENTS)
|
else if (curr_regime == REMOVE_COMMENTS)
|
||||||
{
|
{
|
||||||
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
|
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ enum passes {
|
|||||||
REMOVE_DEAD_CODE_AND_UNPARSE,
|
REMOVE_DEAD_CODE_AND_UNPARSE,
|
||||||
|
|
||||||
FIX_COMMON_BLOCKS,
|
FIX_COMMON_BLOCKS,
|
||||||
|
PARSE_OMP_DIRS,
|
||||||
REMOVE_OMP_DIRS,
|
REMOVE_OMP_DIRS,
|
||||||
REMOVE_OMP_DIRS_TRANSFORM,
|
REMOVE_OMP_DIRS_TRANSFORM,
|
||||||
REMOVE_COMMENTS,
|
REMOVE_COMMENTS,
|
||||||
@@ -351,6 +352,7 @@ static void setPassValues()
|
|||||||
passNames[REMOVE_DEAD_CODE_AND_UNPARSE] = "REMOVE_DEAD_CODE_AND_UNPARSE";
|
passNames[REMOVE_DEAD_CODE_AND_UNPARSE] = "REMOVE_DEAD_CODE_AND_UNPARSE";
|
||||||
|
|
||||||
passNames[FIX_COMMON_BLOCKS] = "FIX_COMMON_BLOCKS";
|
passNames[FIX_COMMON_BLOCKS] = "FIX_COMMON_BLOCKS";
|
||||||
|
passNames[PARSE_OMP_DIRS] = "PARSE_OMP_DIRS";
|
||||||
passNames[REMOVE_OMP_DIRS] = "REMOVE_OMP_DIRS";
|
passNames[REMOVE_OMP_DIRS] = "REMOVE_OMP_DIRS";
|
||||||
passNames[REMOVE_OMP_DIRS_TRANSFORM] = "REMOVE_OMP_DIRS_TRANSFORM";
|
passNames[REMOVE_OMP_DIRS_TRANSFORM] = "REMOVE_OMP_DIRS_TRANSFORM";
|
||||||
passNames[REMOVE_COMMENTS] = "REMOVE_COMMENTS";
|
passNames[REMOVE_COMMENTS] = "REMOVE_COMMENTS";
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
|
|||||||
|
|
||||||
list({ VERIFY_ENDDO, VERIFY_INCLUDE, PREPROC_SPF, PREPROC_ALLOCATES, GET_ALL_ARRAY_DECL, GCOV_PARSER }) <= list({ CALL_GRAPH, MACRO_EXPANSION, DEF_USE_STAGE1 });
|
list({ VERIFY_ENDDO, VERIFY_INCLUDE, PREPROC_SPF, PREPROC_ALLOCATES, GET_ALL_ARRAY_DECL, GCOV_PARSER }) <= list({ CALL_GRAPH, MACRO_EXPANSION, DEF_USE_STAGE1 });
|
||||||
|
|
||||||
list({ VERIFY_ENDDO, VERIFY_INCLUDE, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ GET_ALL_ARRAY_DECL, FILL_COMMON_BLOCKS }) <= Pass(PREPROC_SPF);
|
list({ VERIFY_ENDDO, VERIFY_INCLUDE, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ GET_ALL_ARRAY_DECL, FILL_COMMON_BLOCKS, PARSE_OMP_DIRS }) <= Pass(PREPROC_SPF);
|
||||||
|
|
||||||
Pass(CHECK_PAR_REG_DIR) <= Pass(FILL_PARALLEL_REG_IR);
|
Pass(CHECK_PAR_REG_DIR) <= Pass(FILL_PARALLEL_REG_IR);
|
||||||
|
|
||||||
|
|||||||
@@ -1162,7 +1162,9 @@ template vector<LoopGraph*>& getObjectForFileFromMap(const char *fileName, map<s
|
|||||||
template vector<FuncInfo*>& getObjectForFileFromMap(const char *fileName, map<string, vector<FuncInfo*>>&);
|
template vector<FuncInfo*>& getObjectForFileFromMap(const char *fileName, map<string, vector<FuncInfo*>>&);
|
||||||
template map<int, Gcov_info>& getObjectForFileFromMap(const char *fileName, map<string, map<int, Gcov_info>>&);
|
template map<int, Gcov_info>& getObjectForFileFromMap(const char *fileName, map<string, map<int, Gcov_info>>&);
|
||||||
template map<int, double>& getObjectForFileFromMap(const char *fileName, map<string, map<int, double>>&);
|
template map<int, double>& getObjectForFileFromMap(const char *fileName, map<string, map<int, double>>&);
|
||||||
|
#if __SPF
|
||||||
template map<SgStatement*, vector<SgStatement*>>& getObjectForFileFromMap(const char* fileName, map<string, map<SgStatement*, vector<SgStatement*>>>&);
|
template map<SgStatement*, vector<SgStatement*>>& getObjectForFileFromMap(const char* fileName, map<string, map<SgStatement*, vector<SgStatement*>>>&);
|
||||||
|
#endif
|
||||||
|
|
||||||
static set<string> mpiFunctions;
|
static set<string> mpiFunctions;
|
||||||
bool isMpiFunction(const string& func)
|
bool isMpiFunction(const string& func)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION_SPF "2301"
|
#define VERSION_SPF "2303"
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include "../Utils/utils.h"
|
#include "../Utils/utils.h"
|
||||||
#include "../Utils/SgUtils.h"
|
#include "../Utils/SgUtils.h"
|
||||||
#include "../Utils/errors.h"
|
#include "../Utils/errors.h"
|
||||||
#include "../DirectiveProcessing/directive_parser.h"
|
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::map;
|
using std::map;
|
||||||
@@ -32,7 +31,6 @@ bool EndDoLoopChecker(SgFile *file, vector<Messages> &currMessages)
|
|||||||
SgStatement *st = file->functions(i);
|
SgStatement *st = file->functions(i);
|
||||||
SgStatement *lastNode = st->lastNodeOfStmt();
|
SgStatement *lastNode = st->lastNodeOfStmt();
|
||||||
|
|
||||||
OmpDir globalParallelSection;
|
|
||||||
while (st != lastNode)
|
while (st != lastNode)
|
||||||
{
|
{
|
||||||
if (st == NULL)
|
if (st == NULL)
|
||||||
@@ -44,31 +42,6 @@ bool EndDoLoopChecker(SgFile *file, vector<Messages> &currMessages)
|
|||||||
if (st->variant() == CONTAINS_STMT)
|
if (st->variant() == CONTAINS_STMT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
{
|
|
||||||
set<string> globalPriv;
|
|
||||||
auto res = parseOmpDirs(st, globalPriv);
|
|
||||||
|
|
||||||
for (auto& dir : res)
|
|
||||||
{
|
|
||||||
auto end = dir.keys.end();
|
|
||||||
if (dir.keys.find("parallel") != end
|
|
||||||
&& dir.keys.find("do") == end
|
|
||||||
&& dir.privVars.size()
|
|
||||||
&& dir.keys.find("end") == end)
|
|
||||||
{
|
|
||||||
if (globalParallelSection.keys.size())
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
globalParallelSection = dir;
|
|
||||||
}
|
|
||||||
else if (dir.keys.find("parallel") != end
|
|
||||||
&& dir.keys.find("do") == end
|
|
||||||
&& dir.keys.find("end") != end)
|
|
||||||
{
|
|
||||||
globalParallelSection = OmpDir();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st->variant() == FOR_NODE)
|
if (st->variant() == FOR_NODE)
|
||||||
{
|
{
|
||||||
SgForStmt *currSt = (SgForStmt*)st;
|
SgForStmt *currSt = (SgForStmt*)st;
|
||||||
@@ -78,13 +51,6 @@ bool EndDoLoopChecker(SgFile *file, vector<Messages> &currMessages)
|
|||||||
currMessages.push_back(Messages(ERROR, st->lineNumber(), R51, L"This loop does not have END DO format", 1018));
|
currMessages.push_back(Messages(ERROR, st->lineNumber(), R51, L"This loop does not have END DO format", 1018));
|
||||||
checkOK = false;
|
checkOK = false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
set<string> globalPriv;
|
|
||||||
if (globalParallelSection.privVars.size())
|
|
||||||
globalPriv = globalParallelSection.privVars;
|
|
||||||
auto res = parseOmpDirs(st, globalPriv, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->variant() == FORALL_NODE || st->variant() == FORALL_STAT ||
|
if (st->variant() == FORALL_NODE || st->variant() == FORALL_STAT ||
|
||||||
|
|||||||
Reference in New Issue
Block a user