diff --git a/sapfor/experts/Sapfor_2017/CMakeLists.txt b/sapfor/experts/Sapfor_2017/CMakeLists.txt index f3cca8e..7e5220f 100644 --- a/sapfor/experts/Sapfor_2017/CMakeLists.txt +++ b/sapfor/experts/Sapfor_2017/CMakeLists.txt @@ -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 diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/DirectiveAnalyzer.cpp b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_analyzer.cpp similarity index 95% rename from sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/DirectiveAnalyzer.cpp rename to sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_analyzer.cpp index 9a60ef2..afc3da8 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/DirectiveAnalyzer.cpp +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_analyzer.cpp @@ -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; diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/DirectiveAnalyzer.h b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_analyzer.h similarity index 100% rename from sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/DirectiveAnalyzer.h rename to sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_analyzer.h diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_creator_base.cpp b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_creator_base.cpp index 563c44c..b9fa856 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_creator_base.cpp +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_creator_base.cpp @@ -1091,6 +1091,9 @@ static bool tryToResolveUnmatchedDims(const map> &dim printInternalError(convertFileName(__FILE__).c_str(), __LINE__); } + set privates; + +#if __SPF tmpL = loop->parent; while (tmpL) { @@ -1109,11 +1112,9 @@ static bool tryToResolveUnmatchedDims(const map> &dim tmpL = tmpL->parent; } - set 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 diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_omp_parser.cpp b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_omp_parser.cpp new file mode 100644 index 0000000..581886d --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_omp_parser.cpp @@ -0,0 +1,524 @@ +#include "../Utils/leak_detector.h" + +#include +#include +#include +#include + +#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 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 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 list_new; + + auto attributes = getAttributes(st, set{SPF_ANALYSIS_DIR}); + set 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(st, set{SPF_ANALYSIS_DIR}); + map> reduction; + for (auto& attr : attributes) + fillReductionsFromComment(new Statement(attr), reduction); + + map> reductionToAdd; + fillReductionsFromComment(new Statement(toAdd), reductionToAdd); + + vector 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> reductionToAddNew; + for (auto& redPair : reductionToAdd) + { + auto it = reduction.find(redPair.first); + if (it == reduction.end()) + reductionToAddNew[redPair.first] = redPair.second; + else + { + set 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 parseOmpInStatement(SgStatement* st, const set& globalPriv, bool forDo) +{ + vector resultAll; + + const char* lineS = st->comments(); + if (!lineS) + return resultAll; + + string comment(lineS); + convertToLower(comment); + + vector 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(); // 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 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 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 sublex; + splitString(lexem, '(', sublex); + if (sublex.size() == 2 && lexem.back() == ')') + { + splitString(sublex[1].erase(sublex[1].size() - 1), ',', sublex); + + vector list; + set 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 sublex; + splitString(lexem, '(', sublex); + if (sublex.size() == 2 && lexem.back() == ')') + { + splitString(sublex[1].erase(sublex[1].size() - 1), ':', sublex); + + vector vars; + vector 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 res; + if (st != dir.start) + { + set 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 findAllGlobalParallelRegions(SgStatement* stFunc) +{ + vector 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 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 getGlobalPrivate(SgStatement* st, const vector& globalParallelRegions) +{ + set 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& currMessages) +{ + int funcNum = file->numberOfFunctions(); + + for (int i = 0; i < funcNum; ++i) + { + SgStatement* st = file->functions(i); + SgStatement* lastNode = st->lastNodeOfStmt(); + + vector 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(); + } + } +} diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_omp_parser.h b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_omp_parser.h new file mode 100644 index 0000000..e241f38 --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_omp_parser.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include +#include +#include + +#include "../Utils/errors.h" + +struct OmpDir +{ + std::set privVars; + std::set threadPrivVars; + std::map> redVars; + std::set keys; + + SgStatement* start = NULL; + SgStatement* end = NULL; +}; + +void removeOmpDir(SgStatement* st); +std::vector parseOmpInStatement(SgStatement* st, const std::set& globalPriv, bool forDo = false); +void parseOmpDirectives(SgFile* file, std::vector& currMessages); \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_parser.cpp b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_parser.cpp index 029fd3b..d2860c5 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_parser.cpp +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_parser.cpp @@ -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 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 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 list_new; - - auto attributes = getAttributes(st, set{SPF_ANALYSIS_DIR}); - set 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(st, set{SPF_ANALYSIS_DIR}); - map> reduction; - for (auto& attr : attributes) - fillReductionsFromComment(new Statement(attr), reduction); - - map> reductionToAdd; - fillReductionsFromComment(new Statement(st), reductionToAdd); - - vector 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> reductionToAddNew; - for (auto& redPair : reductionToAdd) - { - auto it = reduction.find(redPair.first); - if (it == reduction.end()) - reductionToAddNew[redPair.first] = redPair.second; - else - { - set 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 parseOmpDirs(void* stIn, const set &globalPriv, bool forDo) -{ - SgStatement* st = (SgStatement*)stIn; - vector resultAll; - - const char* lineS = st->comments(); - if (!lineS) - return resultAll; - - string comment(lineS); - convertToLower(comment); - - vector 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(); // 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 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 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 sublex; - splitString(lexem, '(', sublex); - if (sublex.size() == 2 && lexem.back() == ')') - { - splitString(sublex[1].erase(sublex[1].size() - 1), ',', sublex); - - vector list; - set 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 sublex; - splitString(lexem, '(', sublex); - if (sublex.size() == 2 && lexem.back() == ')') - { - splitString(sublex[1].erase(sublex[1].size() - 1), ':', sublex); - - vector vars; - vector 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; -} \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_parser.h b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_parser.h index 8955e96..92e7acd 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_parser.h +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/directive_parser.h @@ -40,14 +40,3 @@ void fillShrinkFromComment(Statement *stIn, std::vector void fillCheckpointFromComment(Statement *stIn, std::map &clauses, std::set &vars, std::set &expt); - -struct OmpDir -{ - std::set privVars; - std::set threadPrivVars; - std::map> redVars; - std::set keys; -}; - -void removeOmpDir(void* stIn); -std::vector parseOmpDirs(void* st, const std::set& globalPriv, bool forDo = false); \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/spf_directive_preproc.cpp b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/spf_directive_preproc.cpp index 0d737eb..aa7f440 100644 --- a/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/spf_directive_preproc.cpp +++ b/sapfor/experts/Sapfor_2017/_src/DirectiveProcessing/spf_directive_preproc.cpp @@ -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, pair> declaredArrays, map>> 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); } } } diff --git a/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp b/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp index 71da168..8807af9 100644 --- a/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp +++ b/sapfor/experts/Sapfor_2017/_src/LoopAnalyzer/loop_analyzer.cpp @@ -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 { 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); diff --git a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp index a5d55e3..e17ee2c 100644 --- a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp @@ -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()) diff --git a/sapfor/experts/Sapfor_2017/_src/Sapfor.h b/sapfor/experts/Sapfor_2017/_src/Sapfor.h index 4a08593..1337941 100644 --- a/sapfor/experts/Sapfor_2017/_src/Sapfor.h +++ b/sapfor/experts/Sapfor_2017/_src/Sapfor.h @@ -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"; diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/PassManager.h b/sapfor/experts/Sapfor_2017/_src/Utils/PassManager.h index b8e6c2e..0e07092 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/PassManager.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/PassManager.h @@ -227,7 +227,7 @@ void InitPassesDependencies(map> &passDepsIn, set 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); diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/utils.cpp b/sapfor/experts/Sapfor_2017/_src/Utils/utils.cpp index b5a3eab..9bc31d2 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/utils.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Utils/utils.cpp @@ -1162,7 +1162,9 @@ template vector& getObjectForFileFromMap(const char *fileName, map& getObjectForFileFromMap(const char *fileName, map>&); template map& getObjectForFileFromMap(const char *fileName, map>&); template map& getObjectForFileFromMap(const char *fileName, map>&); +#if __SPF template map>& getObjectForFileFromMap(const char* fileName, map>>&); +#endif static set mpiFunctions; bool isMpiFunction(const string& func) diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/version.h b/sapfor/experts/Sapfor_2017/_src/Utils/version.h index 6678a59..454143e 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/version.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2301" +#define VERSION_SPF "2303" diff --git a/sapfor/experts/Sapfor_2017/_src/VerificationCode/StructureChecker.cpp b/sapfor/experts/Sapfor_2017/_src/VerificationCode/StructureChecker.cpp index 9e19936..757b9ae 100644 --- a/sapfor/experts/Sapfor_2017/_src/VerificationCode/StructureChecker.cpp +++ b/sapfor/experts/Sapfor_2017/_src/VerificationCode/StructureChecker.cpp @@ -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 &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 &currMessages) if (st->variant() == CONTAINS_STMT) break; - { - set 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 &currMessages) currMessages.push_back(Messages(ERROR, st->lineNumber(), R51, L"This loop does not have END DO format", 1018)); checkOK = false; } - else - { - set globalPriv; - if (globalParallelSection.privVars.size()) - globalPriv = globalParallelSection.privVars; - auto res = parseOmpDirs(st, globalPriv, true); - } } if (st->variant() == FORALL_NODE || st->variant() == FORALL_STAT ||