fixed and improved OMP parser

This commit is contained in:
ALEXks
2024-04-02 17:48:48 +03:00
parent 1840fb7d45
commit b65437a75c
16 changed files with 587 additions and 405 deletions

View File

@@ -235,8 +235,8 @@ set(DATA_FLOW
set(CREATE_INTER_T _src/CreateInterTree/CreateInterTree.cpp
_src/CreateInterTree/CreateInterTree.h)
set(DIRA _src/DirectiveProcessing/DirectiveAnalyzer.cpp
_src/DirectiveProcessing/DirectiveAnalyzer.h
set(DIRA _src/DirectiveProcessing/directive_analyzer.cpp
_src/DirectiveProcessing/directive_analyzer.h
_src/DirectiveProcessing/directive_creator.cpp
_src/DirectiveProcessing/directive_creator_base.cpp
_src/DirectiveProcessing/directive_creator.h
@@ -244,6 +244,8 @@ set(DIRA _src/DirectiveProcessing/DirectiveAnalyzer.cpp
_src/DirectiveProcessing/directive_creator_nodist.h
_src/DirectiveProcessing/directive_parser.cpp
_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.h
_src/DirectiveProcessing/remote_access.cpp

View File

@@ -17,7 +17,7 @@
#include "../Distribution/DvmhDirective.h"
#include "../GraphLoop/graph_loops.h"
#include "DirectiveAnalyzer.h"
#include "directive_analyzer.h"
#include "../Utils/utils.h"
using std::vector;

View File

@@ -1091,6 +1091,9 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
set<string> privates;
#if __SPF
tmpL = loop->parent;
while (tmpL)
{
@@ -1109,11 +1112,9 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
tmpL = tmpL->parent;
}
set<string> privates;
#if __SPF
tryToFindPrivateInAttributes(loop->loop->GetOriginal(), privates);
#else
#error 'TODO - fill privates for this loop'
#error 'TODO - fill privates for this loop and check all inductive variables'
#endif
//try to resolve from write operations

View File

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

View File

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

View File

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

View File

@@ -40,14 +40,3 @@ void fillShrinkFromComment(Statement *stIn, std::vector<std::pair<fillType, std:
template<typename fillType>
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);

View File

@@ -2121,6 +2121,23 @@ static bool moveSpfParameterForImplicitLoops(SgStatement* st, SgStatement* toAdd
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,
map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays,
map<SgStatement*, set<tuple<int, string, string>>> declaratedArraysSt)
@@ -2163,7 +2180,7 @@ void revertion_spf_dirs(SgFile *file,
toAdd = UniteAttributes(sameAtt);
if (toAdd)
if (!moveSpfParameterForImplicitLoops(st, toAdd))
st->insertStmtBefore(*toAdd, *st->controlParent());
insertBefore(st, toAdd);
}
//check previosly directives SPF_PARALLEL
@@ -2174,7 +2191,7 @@ void revertion_spf_dirs(SgFile *file,
{
if (toAdd)
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());
if (toAdd)
st->insertStmtBefore(*toAdd, *st->controlParent());
insertBefore(st, toAdd);
}
}
}

View File

@@ -16,6 +16,7 @@
#include "loop_analyzer_internal.h"
#include "loop_analyzer.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
using std::vector;
using std::pair;
@@ -2598,7 +2599,7 @@ static bool findOmpThreadPrivDecl(SgStatement* st, map<SgStatement*, set<string>
{
st = st->lexNext();
auto res = parseOmpDirs(st, dummy);
auto res = parseOmpInStatement(st, dummy);
for (auto& dir : res)
for (auto& var : dir.threadPrivVars)
it->second.insert(var);

View File

@@ -46,10 +46,11 @@
#include "DynamicAnalysis/gCov_parser_func.h"
#include "DynamicAnalysis/createParallelRegions.h"
#include "DirectiveProcessing/DirectiveAnalyzer.h"
#include "DirectiveProcessing/directive_analyzer.h"
#include "DirectiveProcessing/directive_creator.h"
#include "DirectiveProcessing/directive_creator_nodist.h"
#include "DirectiveProcessing/insert_directive.h"
#include "DirectiveProcessing/directive_omp_parser.h"
#include "VerificationCode/verifications.h"
#include "Distribution/CreateDistributionDirs.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())
removeOmpDir(st);
}
else if (curr_regime == PARSE_OMP_DIRS)
parseOmpDirectives(file, getObjectForFileFromMap(file_name, SPF_messages));
else if (curr_regime == REMOVE_COMMENTS)
{
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())

View File

@@ -169,6 +169,7 @@ enum passes {
REMOVE_DEAD_CODE_AND_UNPARSE,
FIX_COMMON_BLOCKS,
PARSE_OMP_DIRS,
REMOVE_OMP_DIRS,
REMOVE_OMP_DIRS_TRANSFORM,
REMOVE_COMMENTS,
@@ -351,6 +352,7 @@ static void setPassValues()
passNames[REMOVE_DEAD_CODE_AND_UNPARSE] = "REMOVE_DEAD_CODE_AND_UNPARSE";
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_TRANSFORM] = "REMOVE_OMP_DIRS_TRANSFORM";
passNames[REMOVE_COMMENTS] = "REMOVE_COMMENTS";

View File

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

View File

@@ -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 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>>&);
#if __SPF
template map<SgStatement*, vector<SgStatement*>>& getObjectForFileFromMap(const char* fileName, map<string, map<SgStatement*, vector<SgStatement*>>>&);
#endif
static set<string> mpiFunctions;
bool isMpiFunction(const string& func)

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2301"
#define VERSION_SPF "2303"

View File

@@ -12,7 +12,6 @@
#include "../Utils/utils.h"
#include "../Utils/SgUtils.h"
#include "../Utils/errors.h"
#include "../DirectiveProcessing/directive_parser.h"
using std::vector;
using std::map;
@@ -32,7 +31,6 @@ bool EndDoLoopChecker(SgFile *file, vector<Messages> &currMessages)
SgStatement *st = file->functions(i);
SgStatement *lastNode = st->lastNodeOfStmt();
OmpDir globalParallelSection;
while (st != lastNode)
{
if (st == NULL)
@@ -44,31 +42,6 @@ bool EndDoLoopChecker(SgFile *file, vector<Messages> &currMessages)
if (st->variant() == CONTAINS_STMT)
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)
{
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));
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 ||