2025-06-02 19:08:09 +03:00
|
|
|
#include "leak_detector.h"
|
2024-04-02 17:48:48 +03:00
|
|
|
|
|
|
|
|
#include <cstdio>
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
|
|
|
|
|
#include "dvm.h"
|
|
|
|
|
#include "directive_omp_parser.h"
|
|
|
|
|
#include "directive_parser.h"
|
|
|
|
|
|
2025-06-04 13:08:38 +03:00
|
|
|
#include "SgUtils.h"
|
2024-04-02 17:48:48 +03:00
|
|
|
|
|
|
|
|
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());
|
2024-04-12 16:36:37 +03:00
|
|
|
toAdd->setLocalLineNumber(SPF_OMP_DIR);
|
2024-04-02 17:48:48 +03:00
|
|
|
|
|
|
|
|
//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
|
2024-07-20 13:03:27 +03:00
|
|
|
{
|
|
|
|
|
__spf_print(1, "wrong omp directives placed on line %d\n", st->lineNumber());
|
2024-04-02 17:48:48 +03:00
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
2024-07-20 13:03:27 +03:00
|
|
|
}
|
|
|
|
|
|
2024-04-02 17:48:48 +03:00
|
|
|
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)
|
|
|
|
|
{
|
2024-07-20 13:03:27 +03:00
|
|
|
if (!sections.size())
|
|
|
|
|
{
|
|
|
|
|
__spf_print(1, "wrong omp directives placed on line %d\n", st->lineNumber());
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
}
|
2024-04-02 17:48:48 +03:00
|
|
|
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)
|
2024-07-20 13:03:27 +03:00
|
|
|
{
|
|
|
|
|
__spf_print(1, "wrong omp directives placed\n");
|
2024-04-02 17:48:48 +03:00
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
2024-07-20 13:03:27 +03:00
|
|
|
}
|
2024-04-02 17:48:48 +03:00
|
|
|
else
|
|
|
|
|
parseOmpInStatement(st, getGlobalPrivate(st, globalParallelRegions), true);
|
|
|
|
|
}
|
|
|
|
|
st = st->lexNext();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|