Compare commits
10 Commits
0197fd3a4b
...
172eedfef1
| Author | SHA1 | Date | |
|---|---|---|---|
| 172eedfef1 | |||
|
|
62e4c5cdfe | ||
|
|
69cba903ee | ||
|
|
2fa0eb3e42 | ||
|
|
87a4413472 | ||
|
|
f88e1f570c | ||
|
|
0b6a915753 | ||
|
|
4a13250d1c | ||
|
|
b0d4a1cac5 | ||
|
|
00ca5fbfdf |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -74,3 +74,5 @@ sapfor/experts/Sapfor_2017/Sapc++/Sapc++/x64/
|
|||||||
sapfor/experts/Sapfor_2017/Sapc++/x64/
|
sapfor/experts/Sapfor_2017/Sapc++/x64/
|
||||||
|
|
||||||
/build
|
/build
|
||||||
|
|
||||||
|
sapfor/experts/Sapfor_2017/out/
|
||||||
|
|||||||
@@ -1613,3 +1613,118 @@ vector<IR_Block*> buildIR(SgStatement* function, const FuncInfo* func, const vec
|
|||||||
|
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dfs(SAPFOR::BasicBlock* block, vector<int>& visit, vector<pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>>& startAndEnd, SAPFOR::BasicBlock* prev) {
|
||||||
|
if (visit[block->getNumber()] == 2) {
|
||||||
|
cout << "error";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visit[block->getNumber()] == 1) {
|
||||||
|
visit[block->getNumber()] = 2;
|
||||||
|
startAndEnd.push_back(make_pair(prev, block));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visit[block->getNumber()] = 1;
|
||||||
|
for (auto i : block->getNext()) {
|
||||||
|
dfs(i, visit, startAndEnd, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printBlock(SAPFOR::BasicBlock* block) {
|
||||||
|
cout << "block - " << block->getNumber() << endl;
|
||||||
|
cout << "next -";
|
||||||
|
for (auto i : block->getNext())
|
||||||
|
{
|
||||||
|
cout << " " << i->getNumber();
|
||||||
|
}
|
||||||
|
cout << endl << "prev -";
|
||||||
|
for (auto i : block->getPrev())
|
||||||
|
{
|
||||||
|
cout << " " << i->getNumber();
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
for (auto i : block->getInstructions())
|
||||||
|
{
|
||||||
|
cout << i->getNumber() << " " << i->getInstruction()->dump() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void testIR(map<FuncInfo*, vector<SAPFOR::BasicBlock*>> fullIR) {
|
||||||
|
for (auto& i : fullIR)
|
||||||
|
{
|
||||||
|
for (auto j : i.second)
|
||||||
|
printBlock(j);
|
||||||
|
|
||||||
|
vector<int> visited(i.second.size(), 0);
|
||||||
|
vector<pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>> startAndEnd;
|
||||||
|
dfs(i.second[0], visited, startAndEnd, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
vector<LoopGraph*> loops;
|
||||||
|
for (auto j : startAndEnd)
|
||||||
|
{
|
||||||
|
auto instruction = j.second->getInstructions()[0]->getInstruction();
|
||||||
|
if (instruction->getOperator()->variant() == FOR_NODE) {
|
||||||
|
SgForStmt* stmt = isSgForStmt(instruction->getOperator());
|
||||||
|
|
||||||
|
auto tmpLoop = new LoopGraph();
|
||||||
|
tmpLoop->isFor = true;
|
||||||
|
tmpLoop->lineNum = instruction->getOperator()->lineNumber();
|
||||||
|
|
||||||
|
cout << "for" << endl << stmt->sunparse() << endl;
|
||||||
|
cout << "loop start line " << tmpLoop->lineNum << endl << endl;
|
||||||
|
|
||||||
|
loops.push_back(tmpLoop);
|
||||||
|
} else if (instruction->getOperator()->variant() == WHILE_NODE) {
|
||||||
|
SgWhileStmt* stmt = isSgWhileStmt(instruction->getOperator());
|
||||||
|
|
||||||
|
auto tmpLoop = new LoopGraph();
|
||||||
|
tmpLoop->lineNum = instruction->getOperator()->lineNumber();
|
||||||
|
|
||||||
|
if (stmt->conditional() == NULL)
|
||||||
|
{
|
||||||
|
//infinit loop
|
||||||
|
cout << "infinit loop " << endl << stmt->sunparse() << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//while
|
||||||
|
cout << "while " << endl << stmt->sunparse();
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "loop start line " << tmpLoop->lineNum << endl << endl;
|
||||||
|
|
||||||
|
loops.push_back(tmpLoop);
|
||||||
|
} else if (instruction->getOperator()->variant() == LOOP_NODE) {
|
||||||
|
cout << "not known loop" << endl << instruction->getOperator()->sunparse() << endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cout << "goto loop - " << instruction->getOperator()->sunparse() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*for (auto j : i.second) {
|
||||||
|
cout << j->getNumber() << endl << "in" << endl;
|
||||||
|
for (auto k : j->getRD_In()) {
|
||||||
|
cout << k.first->getMemTypeStr() << " - ";
|
||||||
|
for (auto h : k.second) {
|
||||||
|
cout << h << " ";
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
cout << "out" << endl;
|
||||||
|
for (auto k : j->getRD_Out()) {
|
||||||
|
cout << k.first->getMemTypeStr() << " - ";
|
||||||
|
for (auto h : k.second) {
|
||||||
|
cout << h << " ";
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -130,7 +130,7 @@ namespace SAPFOR
|
|||||||
{
|
{
|
||||||
if (arg == NULL)
|
if (arg == NULL)
|
||||||
return "";
|
return "";
|
||||||
return arg->getValue();
|
return arg->getValue();
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ namespace SAPFOR
|
|||||||
{
|
{
|
||||||
std::string res = "";
|
std::string res = "";
|
||||||
|
|
||||||
std::string resultVal = getArgValue(result);
|
std::string resultVal = getArgValue(result);
|
||||||
std::string arg1Val = getArgValue(arg1);
|
std::string arg1Val = getArgValue(arg1);
|
||||||
std::string arg2Val = getArgValue(arg2);
|
std::string arg2Val = getArgValue(arg2);
|
||||||
|
|
||||||
@@ -312,4 +312,6 @@ std::vector<SAPFOR::IR_Block*> buildIR(SgStatement* function, const FuncInfo* fu
|
|||||||
SAPFOR::Instruction* getInstructionByNumber(const std::vector<SAPFOR::IR_Block*>& blocks, int num);
|
SAPFOR::Instruction* getInstructionByNumber(const std::vector<SAPFOR::IR_Block*>& blocks, int num);
|
||||||
std::pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*> getInstructionAndBlockByNumber(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph, int num);
|
std::pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*> getInstructionAndBlockByNumber(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph, int num);
|
||||||
std::pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*> getInstructionAndBlockByStatement(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt);
|
std::pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*> getInstructionAndBlockByStatement(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt);
|
||||||
int getParamIndex(SAPFOR::Argument* func_param, int max_index);
|
int getParamIndex(SAPFOR::Argument* func_param, int max_index);
|
||||||
|
|
||||||
|
void testIR(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>> fullIR);
|
||||||
@@ -68,7 +68,7 @@ void createParallelDirectivesNoDist(const map<LoopGraph*, map<DIST::Array*, Arra
|
|||||||
__spf_print(PRINT_DIR_RESULT, " has conflict\n");
|
__spf_print(PRINT_DIR_RESULT, " has conflict\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!currLoop->hasLimitsToParallel() &&
|
if (!currLoop->hasLimitsToParallel() &&
|
||||||
(currLoop->lineNum > 0 || (currLoop->lineNum < 0 && currLoop->altLineNum > 0)))
|
(currLoop->lineNum > 0 || (currLoop->lineNum < 0 && currLoop->altLineNum > 0)))
|
||||||
{
|
{
|
||||||
ParallelDirective* parDir = new ParallelDirective();
|
ParallelDirective* parDir = new ParallelDirective();
|
||||||
|
|||||||
@@ -158,10 +158,10 @@ namespace Distribution
|
|||||||
Array(const STRING &name, const STRING &shortName, const int dimSize, const unsigned id,
|
Array(const STRING &name, const STRING &shortName, const int dimSize, const unsigned id,
|
||||||
const STRING &declFile, const int declLine, const PAIR<arrayLocation, STRING> &locationPos,
|
const STRING &declFile, const int declLine, const PAIR<arrayLocation, STRING> &locationPos,
|
||||||
Symbol *declSymbol, bool inOmpThreadPriv, bool privateInLoop, bool inEquivalence,
|
Symbol *declSymbol, bool inOmpThreadPriv, bool privateInLoop, bool inEquivalence,
|
||||||
const VECTOR<STRING> ®ions, const int typeSize) :
|
const VECTOR<STRING> ®ions, const int typeSize, const distFlag flag = DISTR) :
|
||||||
|
|
||||||
name(name), dimSize(dimSize), id(id), shortName(shortName),
|
name(name), dimSize(dimSize), id(id), shortName(shortName),
|
||||||
isTemplFlag(false), isNonDistribute(DISTR), isLoopArrayFlag(false),
|
isTemplFlag(false), isNonDistribute(flag), isLoopArrayFlag(false),
|
||||||
locationPos(locationPos), declSymbol(declSymbol), typeSize(typeSize),
|
locationPos(locationPos), declSymbol(declSymbol), typeSize(typeSize),
|
||||||
ompThreadPrivate(inOmpThreadPriv), privateInLoop(privateInLoop), inEquivalence(inEquivalence)
|
ompThreadPrivate(inOmpThreadPriv), privateInLoop(privateInLoop), inEquivalence(inEquivalence)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -960,10 +960,12 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
|
|||||||
st = copy->lexNext();
|
st = copy->lexNext();
|
||||||
while (st != last)
|
while (st != last)
|
||||||
{
|
{
|
||||||
if (st->variant() == VAR_DECL
|
const int var = st->variant();
|
||||||
|| st->variant() == VAR_DECL_90
|
if (var == VAR_DECL
|
||||||
|| st->variant() == DIM_STAT
|
|| var == VAR_DECL_90
|
||||||
|| st->variant() == INTENT_STMT)
|
|| var == DIM_STAT
|
||||||
|
|| var == INTENT_STMT
|
||||||
|
|| var == EXTERN_STAT)
|
||||||
{
|
{
|
||||||
bool empty = filterFromList(st, idents);
|
bool empty = filterFromList(st, idents);
|
||||||
if (empty)
|
if (empty)
|
||||||
|
|||||||
@@ -12,13 +12,14 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
#include "dvm.h"
|
#include "dvm.h"
|
||||||
#include "../GraphLoop/graph_loops_func.h"
|
|
||||||
#include "graph_calls_func.h"
|
#include "graph_calls_func.h"
|
||||||
|
|
||||||
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
#include "../GraphLoop/graph_loops_func.h"
|
||||||
#include "../DirectiveProcessing/directive_parser.h"
|
#include "../DirectiveProcessing/directive_parser.h"
|
||||||
#include "../Utils/SgUtils.h"
|
#include "../Utils/SgUtils.h"
|
||||||
#include "../ParallelizationRegions/ParRegions_func.h"
|
#include "../ParallelizationRegions/ParRegions_func.h"
|
||||||
#include "../DynamicAnalysis/gCov_parser_func.h"
|
#include "../DynamicAnalysis/gCov_parser_func.h"
|
||||||
#include "acc_analyzer.h"
|
|
||||||
#include "../ExpressionTransform/expr_transform.h"
|
#include "../ExpressionTransform/expr_transform.h"
|
||||||
#include "../LoopAnalyzer/loop_analyzer.h"
|
#include "../LoopAnalyzer/loop_analyzer.h"
|
||||||
#include "../VerificationCode/verifications.h"
|
#include "../VerificationCode/verifications.h"
|
||||||
@@ -203,8 +204,16 @@ static void fillFuncParams(FuncInfo *currInfo, const map<string, vector<SgExpres
|
|||||||
currParams.init(numOfParams);
|
currParams.init(numOfParams);
|
||||||
|
|
||||||
if (numOfParams > 0)
|
if (numOfParams > 0)
|
||||||
|
{
|
||||||
for (int i = 0; i < numOfParams; ++i)
|
for (int i = 0; i < numOfParams; ++i)
|
||||||
fillParam(i, procHeader->parameter(i), currParams, commonBlocks, false);
|
fillParam(i, procHeader->parameter(i), currParams, commonBlocks, false);
|
||||||
|
|
||||||
|
for (int i = 0; i < procHeader->numberOfParameters(); ++i)
|
||||||
|
{
|
||||||
|
currInfo->funcParams.identificators.push_back((procHeader->parameter(i))->identifier());
|
||||||
|
currInfo->isParamUsedAsIndex.push_back(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fillFuncParams(FuncInfo *currInfo, const map<string, vector<SgExpression*>> &commonBlocks, SgStatement *entryHeader)
|
static void fillFuncParams(FuncInfo *currInfo, const map<string, vector<SgExpression*>> &commonBlocks, SgStatement *entryHeader)
|
||||||
@@ -341,38 +350,35 @@ static void processActualParams(SgExpression *parList, const map<string, vector<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void findFuncCalls(SgStatement *parent, SgExpression *curr, vector<FuncInfo*> &entryProcs, const int line,
|
static void findFuncCalls(SgStatement *parent, SgExpression *curr, FuncInfo* procInfo, const int line,
|
||||||
const map<string, vector<SgExpression*>> &commonBlocks, const set<string> ¯oNames,
|
const map<string, vector<SgExpression*>> &commonBlocks, const set<string> ¯oNames,
|
||||||
const vector<SgStatement*> &containsFunctions, const string &prefix)
|
const vector<SgStatement*> &containsFunctions, const string &prefix)
|
||||||
{
|
{
|
||||||
if (curr->variant() == FUNC_CALL && macroNames.find(curr->symbol()->identifier()) == macroNames.end())
|
if (curr->variant() == FUNC_CALL && macroNames.find(curr->symbol()->identifier()) == macroNames.end())
|
||||||
{
|
{
|
||||||
for (auto &proc : entryProcs)
|
vector<string> nameOfCallFunc;
|
||||||
{
|
nameOfCallFunc.push_back(curr->symbol()->identifier());
|
||||||
vector<string> nameOfCallFunc;
|
nameOfCallFunc.push_back(OriginalSymbol(curr->symbol())->identifier());
|
||||||
nameOfCallFunc.push_back(curr->symbol()->identifier());
|
|
||||||
nameOfCallFunc.push_back(OriginalSymbol(curr->symbol())->identifier());
|
|
||||||
|
|
||||||
for (auto& elem : nameOfCallFunc)
|
for (auto& elem : nameOfCallFunc)
|
||||||
correctNameIfContains(NULL, curr, elem, containsFunctions, prefix);
|
correctNameIfContains(NULL, curr, elem, containsFunctions, prefix);
|
||||||
|
|
||||||
proc->callsFrom.insert(nameOfCallFunc.begin(), nameOfCallFunc.end());
|
procInfo->callsFrom.insert(nameOfCallFunc.begin(), nameOfCallFunc.end());
|
||||||
|
|
||||||
FuncInfoCallFrom newCall;
|
FuncInfoCallFrom newCall;
|
||||||
newCall.detailCallsFrom = make_pair(nameOfCallFunc[1], line); // original name of call
|
newCall.detailCallsFrom = make_pair(nameOfCallFunc[1], line); // original name of call
|
||||||
newCall.pointerDetailCallsFrom = make_pair(curr, FUNC_CALL);
|
newCall.pointerDetailCallsFrom = make_pair(curr, FUNC_CALL);
|
||||||
newCall.parentForPointer = parent;
|
newCall.parentForPointer = parent;
|
||||||
newCall.actualParams = FuncParam();
|
newCall.actualParams = FuncParam();
|
||||||
|
|
||||||
processActualParams(curr->lhs(), commonBlocks, newCall.actualParams, proc->externalCalls);
|
processActualParams(curr->lhs(), commonBlocks, newCall.actualParams, procInfo->externalCalls);
|
||||||
proc->callsFromDetailed.push_back(newCall);
|
procInfo->callsFromDetailed.push_back(newCall);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curr->lhs())
|
if (curr->lhs())
|
||||||
findFuncCalls(parent, curr->lhs(), entryProcs, line, commonBlocks, macroNames, containsFunctions, prefix);
|
findFuncCalls(parent, curr->lhs(), procInfo, line, commonBlocks, macroNames, containsFunctions, prefix);
|
||||||
if (curr->rhs())
|
if (curr->rhs())
|
||||||
findFuncCalls(parent, curr->rhs(), entryProcs, line, commonBlocks, macroNames, containsFunctions, prefix);
|
findFuncCalls(parent, curr->rhs(), procInfo, line, commonBlocks, macroNames, containsFunctions, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void findReplaceSymbolByExpression(SgExpression *parentEx, SgExpression *findIn, int pos,
|
static void findReplaceSymbolByExpression(SgExpression *parentEx, SgExpression *findIn, int pos,
|
||||||
@@ -730,13 +736,13 @@ static void fillIn(FuncInfo *currF, SgExpression *ex, const map<string, int> &pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fillOut(FuncInfo* currF, const string& symb, const map<string, int>& parNames)
|
static void fillType(FuncInfo* currF, const string& symb, const map<string, int>& parNames, const int type)
|
||||||
{
|
{
|
||||||
if (symb != "")
|
if (symb != "")
|
||||||
{
|
{
|
||||||
auto it = parNames.find(symb);
|
auto it = parNames.find(symb);
|
||||||
if (it != parNames.end())
|
if (it != parNames.end())
|
||||||
currF->funcParams.inout_types[it->second] |= OUT_BIT;
|
currF->funcParams.inout_types[it->second] |= type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,7 +751,7 @@ static void checkSpecList(SgExpression* pair, FuncInfo* currF, const map<string,
|
|||||||
auto valExp = isSgKeywordValExp(pair->lhs());
|
auto valExp = isSgKeywordValExp(pair->lhs());
|
||||||
if (valExp->value() == string("unit"))
|
if (valExp->value() == string("unit"))
|
||||||
if (pair->rhs() && pair->rhs()->symbol())
|
if (pair->rhs() && pair->rhs()->symbol())
|
||||||
fillOut(currF, pair->rhs()->symbol()->identifier(), parNames);
|
fillType(currF, pair->rhs()->symbol()->identifier(), parNames, INOUT_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkSpecList(SgExpression *spec, FuncInfo* currF, const map<string, int>& parNames)
|
static void checkSpecList(SgExpression *spec, FuncInfo* currF, const map<string, int>& parNames)
|
||||||
@@ -763,7 +769,7 @@ static void checkSpecList(SgExpression *spec, FuncInfo* currF, const map<string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
|
static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, const set<SgStatement*>& activeOps)
|
||||||
{
|
{
|
||||||
if (currF->funcParams.countOfPars == 0)
|
if (currF->funcParams.countOfPars == 0)
|
||||||
return;
|
return;
|
||||||
@@ -786,6 +792,12 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
|
|||||||
if (isSgExecutableStatement(st) == NULL || st->lineNumber() <= 0)
|
if (isSgExecutableStatement(st) == NULL || st->lineNumber() <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (activeOps.size() && activeOps.find(st) == activeOps.end())
|
||||||
|
{
|
||||||
|
st = st->lastNodeOfStmt();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (st->variant() == ASSIGN_STAT)
|
if (st->variant() == ASSIGN_STAT)
|
||||||
{
|
{
|
||||||
SgExpression *left = st->expr(0);
|
SgExpression *left = st->expr(0);
|
||||||
@@ -802,7 +814,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
|
|||||||
if (left->lhs()->symbol())
|
if (left->lhs()->symbol())
|
||||||
symb = left->lhs()->symbol()->identifier();
|
symb = left->lhs()->symbol()->identifier();
|
||||||
}
|
}
|
||||||
fillOut(currF, symb, parNames);
|
fillType(currF, symb, parNames, OUT_BIT);
|
||||||
} // TODO: need to extend
|
} // TODO: need to extend
|
||||||
else if (st->variant() == READ_STAT)
|
else if (st->variant() == READ_STAT)
|
||||||
{
|
{
|
||||||
@@ -818,7 +830,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
|
|||||||
string symb = "";
|
string symb = "";
|
||||||
if (item->symbol())
|
if (item->symbol())
|
||||||
symb = item->symbol()->identifier();
|
symb = item->symbol()->identifier();
|
||||||
fillOut(currF, symb, parNames);
|
fillType(currF, symb, parNames, OUT_BIT);
|
||||||
}
|
}
|
||||||
else if (item->variant() == IOACCESS)
|
else if (item->variant() == IOACCESS)
|
||||||
{
|
{
|
||||||
@@ -839,7 +851,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
|
|||||||
string symb = "";
|
string symb = "";
|
||||||
if (item->symbol())
|
if (item->symbol())
|
||||||
symb = item->symbol()->identifier();
|
symb = item->symbol()->identifier();
|
||||||
fillOut(currF, symb, parNames);
|
fillType(currF, symb, parNames, OUT_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -875,7 +887,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
|
|||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
if (types[z] == OUT_BIT || types[z] == INOUT_BIT)
|
if (types[z] == OUT_BIT || types[z] == INOUT_BIT)
|
||||||
fillOut(currF, arg->symbol()->identifier(), parNames);
|
fillType(currF, arg->symbol()->identifier(), parNames, OUT_BIT);
|
||||||
if (types[z] == IN_BIT || types[z] == INOUT_BIT)
|
if (types[z] == IN_BIT || types[z] == INOUT_BIT)
|
||||||
fillIn(currF, arg, parNames);
|
fillIn(currF, arg, parNames);
|
||||||
}
|
}
|
||||||
@@ -894,12 +906,12 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: check common block and module use
|
//TODO: check common block and module use
|
||||||
static void fillFunctionPureStatus(SgStatement *header, FuncInfo *currInfo, vector<Messages> &messagesForFile)
|
static void fillFunctionPureStatus(SgStatement *header, FuncInfo *currInfo, vector<Messages> &messagesForFile, const set<SgStatement*>& activeOps)
|
||||||
{
|
{
|
||||||
if (!currInfo->isMain)
|
if (!currInfo->isMain)
|
||||||
{
|
{
|
||||||
set<int> lines;
|
set<int> lines;
|
||||||
bool hasIntent = hasThisIds(header, lines, { INTENT_STMT });
|
bool hasIntent = hasThisIds(header, lines, { INTENT_STMT }, &activeOps);
|
||||||
bool declaratedAsPure = (header->symbol()->attributes() & PURE_BIT);
|
bool declaratedAsPure = (header->symbol()->attributes() & PURE_BIT);
|
||||||
|
|
||||||
if (declaratedAsPure && !hasIntent && ((SgProgHedrStmt*)header)->numberOfParameters())
|
if (declaratedAsPure && !hasIntent && ((SgProgHedrStmt*)header)->numberOfParameters())
|
||||||
@@ -913,7 +925,9 @@ static void fillFunctionPureStatus(SgStatement *header, FuncInfo *currInfo, vect
|
|||||||
lines.clear();
|
lines.clear();
|
||||||
bool has = hasThisIds(header, lines, { DATA_DECL, SAVE_DECL, USE_STMT,
|
bool has = hasThisIds(header, lines, { DATA_DECL, SAVE_DECL, USE_STMT,
|
||||||
WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT,
|
WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT,
|
||||||
PRINT_STAT, STOP_STAT, PAUSE_NODE });
|
PRINT_STAT, STOP_STAT, PAUSE_NODE },
|
||||||
|
&activeOps);
|
||||||
|
|
||||||
if (!has || declaratedAsPure)
|
if (!has || declaratedAsPure)
|
||||||
currInfo->isPure = true;
|
currInfo->isPure = true;
|
||||||
else
|
else
|
||||||
@@ -947,284 +961,380 @@ static void fillCommons(FuncInfo *currInfo, const map<string, vector<SgExpressio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo, vector<LoopGraph*> &loops, vector<Messages> &messagesForFile, bool dontFillFuncParam)
|
static FuncInfo* createNewFuction(const string& funcName, SgStatement *st, SgStatement* entry,
|
||||||
|
vector<Messages>& messagesForFile,
|
||||||
|
const map<string, vector<SgExpression*>>& commonBlocks,
|
||||||
|
const set<SgStatement*>& activeOps)
|
||||||
|
{
|
||||||
|
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||||
|
|
||||||
|
FuncInfo* currInfo = new FuncInfo(funcName, make_pair(entry->lineNumber(), lastNode->lineNumber()), new Statement(entry));
|
||||||
|
hasThisIds(st, currInfo->linesOfIO, { WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT, PRINT_STAT }, &activeOps);
|
||||||
|
hasThisIds(st, currInfo->linesOfStop, { STOP_STAT, PAUSE_NODE }, &activeOps);
|
||||||
|
currInfo->isMain = (st->variant() == PROG_HEDR);
|
||||||
|
fillCommons(currInfo, commonBlocks);
|
||||||
|
fillFunctionPureStatus(st, currInfo, messagesForFile, activeOps);
|
||||||
|
|
||||||
|
if (st->variant() != PROG_HEDR)
|
||||||
|
{
|
||||||
|
SgProgHedrStmt* procFuncHedr = ((SgProgHedrStmt*)st);
|
||||||
|
|
||||||
|
if (st == entry)
|
||||||
|
fillFuncParams(currInfo, commonBlocks, procFuncHedr);
|
||||||
|
else
|
||||||
|
fillFuncParams(currInfo, commonBlocks, entry);
|
||||||
|
fillInOut(currInfo, st, lastNode, activeOps);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSPF_NoInline(new Statement(st->lexNext())))
|
||||||
|
{
|
||||||
|
__spf_print(1, "set NOINLINE attribute for function '%s'\n", funcName.c_str());
|
||||||
|
currInfo->doNotInline = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
currInfo->funcParams.completeParams();
|
||||||
|
|
||||||
|
return currInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FuncInfo* analyzeFunction(const string& funcName, const string& containsPrefix,
|
||||||
|
SgStatement *function, SgStatement* entry, map<string, vector<FuncInfo*>>& allFuncInfo,
|
||||||
|
const map<int, LoopGraph*>& mapLoopGraph, vector<Messages>& messagesForFile,
|
||||||
|
vector<SgStatement*>& containsFunctions,
|
||||||
|
const set<SgStatement*>& activeOps)
|
||||||
|
{
|
||||||
|
SgStatement* st = function;
|
||||||
|
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||||
|
|
||||||
|
const string fileName = function->fileName();
|
||||||
|
auto it = allFuncInfo.find(fileName);
|
||||||
|
if (it == allFuncInfo.end())
|
||||||
|
it = allFuncInfo.insert(it, make_pair(fileName, vector<FuncInfo*>()));
|
||||||
|
|
||||||
|
map<string, vector<SgExpression*>> commonBlocks;
|
||||||
|
getCommonBlocksRef(commonBlocks, function, lastNode);
|
||||||
|
|
||||||
|
if (function->controlParent()->variant() == GLOBAL)
|
||||||
|
containsFunctions.clear();
|
||||||
|
|
||||||
|
findContainsFunctions(function, containsFunctions);
|
||||||
|
auto procInfo = createNewFuction(funcName, function, entry, messagesForFile, commonBlocks, activeOps);
|
||||||
|
it->second.push_back(procInfo);
|
||||||
|
|
||||||
|
vector<SgStatement*> macroStats;
|
||||||
|
set<string> macroNames;
|
||||||
|
|
||||||
|
while (st != lastNode)
|
||||||
|
{
|
||||||
|
if (st->variant() == CONTAINS_STMT)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (st->variant() == INTERFACE_STMT)
|
||||||
|
{
|
||||||
|
st = st->lexNext();
|
||||||
|
while (st && !(st->controlParent()->variant() == INTERFACE_STMT && st->variant() == CONTROL_END))
|
||||||
|
{
|
||||||
|
if (st->variant() == PROC_HEDR || st->variant() == FUNC_HEDR)
|
||||||
|
{
|
||||||
|
procInfo->interfaceBlocks[st->symbol()->identifier()] = NULL;
|
||||||
|
st = st->lastNodeOfStmt();
|
||||||
|
}
|
||||||
|
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 (!isSgExecutableStatement(st))
|
||||||
|
{
|
||||||
|
if (st->variant() == STMTFN_STAT)
|
||||||
|
{
|
||||||
|
macroStats.push_back(st);
|
||||||
|
macroNames.insert(st->expr(0)->symbol()->identifier());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
st = st->lexNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
st = function;
|
||||||
|
const string file = st->fileName();
|
||||||
|
|
||||||
|
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 (!__gcov_doesThisLineExecuted(st->fileName(), st->lineNumber()) ||
|
||||||
|
st->variant() == ENTRY_STAT)
|
||||||
|
{
|
||||||
|
st = st->lexNext();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeOps.size())
|
||||||
|
{
|
||||||
|
if (st->fileName() == file &&
|
||||||
|
isSgExecutableStatement(st) &&
|
||||||
|
activeOps.find(st) == activeOps.end())
|
||||||
|
{
|
||||||
|
st = st->lastNodeOfStmt();
|
||||||
|
st = st->lexNext();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for external calls
|
||||||
|
if (st->variant() == EXTERN_STAT)
|
||||||
|
for (SgExpression* ex = st->expr(0); ex; ex = ex->rhs())
|
||||||
|
if (ex->lhs()->symbol())
|
||||||
|
procInfo->externalCalls.insert(ex->lhs()->symbol()->identifier());
|
||||||
|
|
||||||
|
const string prefix = containsPrefix == "" ? string(function->symbol()->identifier()) + "." : containsPrefix;
|
||||||
|
//printf("var %d, line %d, file %s\n", st->variant(), st->lineNumber(), st->fileName());
|
||||||
|
if (st->variant() == PROC_STAT)
|
||||||
|
{
|
||||||
|
vector<string> pureNameOfCallFunc;
|
||||||
|
pureNameOfCallFunc.push_back(removeString("call ", st->symbol()->identifier()));
|
||||||
|
pureNameOfCallFunc.push_back(removeString("call ", OriginalSymbol(st->symbol())->identifier()));
|
||||||
|
|
||||||
|
for (auto& elem : pureNameOfCallFunc)
|
||||||
|
correctNameIfContains(st, NULL, elem, containsFunctions, prefix);
|
||||||
|
|
||||||
|
if (hasRecCall(procInfo, pureNameOfCallFunc))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
procInfo->callsFrom.insert(pureNameOfCallFunc.begin(), pureNameOfCallFunc.end());
|
||||||
|
|
||||||
|
FuncInfoCallFrom newCall;
|
||||||
|
newCall.detailCallsFrom = make_pair(pureNameOfCallFunc[1], st->lineNumber()); // original name of call
|
||||||
|
newCall.pointerDetailCallsFrom = make_pair(st, PROC_STAT);
|
||||||
|
newCall.parentForPointer = st;
|
||||||
|
newCall.actualParams = FuncParam();
|
||||||
|
|
||||||
|
processActualParams(st->expr(0), commonBlocks, newCall.actualParams, procInfo->externalCalls);
|
||||||
|
procInfo->callsFromDetailed.push_back(newCall);
|
||||||
|
|
||||||
|
// Add func call which we've just found
|
||||||
|
NestedFuncCall funcCall(pureNameOfCallFunc[1]);
|
||||||
|
procInfo->funcsCalledFromThis.push_back(funcCall);
|
||||||
|
|
||||||
|
// search for using pars of cur func in pars of called
|
||||||
|
throughParams(st->expr(0), *procInfo, containsFunctions, prefix);
|
||||||
|
|
||||||
|
//find external calls
|
||||||
|
for (SgExpression* par = st->expr(0); par != NULL; par = par->rhs())
|
||||||
|
{
|
||||||
|
SgExpression* curr = par->lhs();
|
||||||
|
if (curr)
|
||||||
|
{
|
||||||
|
if (curr->variant() == VAR_REF)
|
||||||
|
{
|
||||||
|
auto s = curr->symbol();
|
||||||
|
if (procInfo->externalCalls.find(s->identifier()) != procInfo->externalCalls.end() ||
|
||||||
|
(s->attributes() & EXTERNAL_BIT))
|
||||||
|
{
|
||||||
|
vector<string> nameOfCallFunc;
|
||||||
|
nameOfCallFunc.push_back(s->identifier());
|
||||||
|
nameOfCallFunc.push_back(OriginalSymbol(s)->identifier());
|
||||||
|
|
||||||
|
for (auto& elem : nameOfCallFunc)
|
||||||
|
correctNameIfContains(NULL, curr, elem, containsFunctions, prefix);
|
||||||
|
|
||||||
|
procInfo->callsFrom.insert(nameOfCallFunc.begin(), nameOfCallFunc.end());
|
||||||
|
|
||||||
|
FuncInfoCallFrom newCall;
|
||||||
|
newCall.detailCallsFrom = make_pair(nameOfCallFunc[1], st->lineNumber()); // original name of call
|
||||||
|
newCall.pointerDetailCallsFrom = make_pair(curr, VAR_REF);
|
||||||
|
newCall.parentForPointer = st;
|
||||||
|
newCall.actualParams = FuncParam();
|
||||||
|
|
||||||
|
procInfo->callsFromDetailed.push_back(newCall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
if (st->expr(i))
|
||||||
|
findParamUsedInFuncCalls(st->expr(i), *procInfo, containsFunctions, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
if (st->expr(i))
|
||||||
|
findFuncCalls(st, st->expr(i), procInfo, st->lineNumber(), commonBlocks, macroNames, containsFunctions, prefix);
|
||||||
|
|
||||||
|
if (isSgExecutableStatement(st))
|
||||||
|
{
|
||||||
|
if (procInfo->isParamUsedAsIndex.size())
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
findArrayRef(st->expr(i), *procInfo, st->variant() == ASSIGN_STAT && i == 0);
|
||||||
|
|
||||||
|
if (st->variant() == FOR_NODE)
|
||||||
|
{
|
||||||
|
auto itL = mapLoopGraph.find(st->lineNumber());
|
||||||
|
if (itL != mapLoopGraph.end())
|
||||||
|
procInfo->loopsInFunc.push_back(itL->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
st = st->lexNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
return procInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static set<SgStatement*> fillActiveOperators(const vector<SAPFOR::BasicBlock*>& blocks)
|
||||||
|
{
|
||||||
|
if (blocks.size() == 0)
|
||||||
|
return set<SgStatement*>();
|
||||||
|
|
||||||
|
set<SgStatement*> active;
|
||||||
|
set<SAPFOR::BasicBlock*> activeBlocks;
|
||||||
|
|
||||||
|
activeBlocks.insert(blocks[0]);
|
||||||
|
bool added = true;
|
||||||
|
while (added)
|
||||||
|
{
|
||||||
|
added = false;
|
||||||
|
for (auto& block : activeBlocks)
|
||||||
|
{
|
||||||
|
for (auto& next : block->getNext())
|
||||||
|
{
|
||||||
|
if (activeBlocks.find(next) == activeBlocks.end())
|
||||||
|
{
|
||||||
|
activeBlocks.insert(next);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& block : activeBlocks)
|
||||||
|
{
|
||||||
|
for (auto& instr : block->getInstructions())
|
||||||
|
{
|
||||||
|
auto op = instr->getInstruction()->getOperator();
|
||||||
|
if (op)
|
||||||
|
active.insert(op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if fullIR not empty -> call this function from CALL_GRAPH2
|
||||||
|
void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo, const vector<LoopGraph*> &loops, vector<Messages> &messagesForFile,
|
||||||
|
map<FuncInfo*, vector<SAPFOR::BasicBlock*>> &fullIR)
|
||||||
{
|
{
|
||||||
map<int, LoopGraph*> mapLoopGraph;
|
map<int, LoopGraph*> mapLoopGraph;
|
||||||
createMapLoopGraph(loops, mapLoopGraph);
|
createMapLoopGraph(loops, mapLoopGraph);
|
||||||
|
|
||||||
|
map<SgStatement*, FuncInfo*> tmpInfoInIR;
|
||||||
|
for (auto& elem : fullIR)
|
||||||
|
{
|
||||||
|
SgStatement* func = elem.first->funcPointer->GetOriginal();
|
||||||
|
if (tmpInfoInIR.count(func) != 0)
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
|
tmpInfoInIR[func] = elem.first;
|
||||||
|
}
|
||||||
|
|
||||||
int funcNum = file->numberOfFunctions();
|
int funcNum = file->numberOfFunctions();
|
||||||
__spf_print(DEBUG, "functions num in file = %d\n", funcNum);
|
__spf_print(DEBUG, "functions num in file = %d\n", funcNum);
|
||||||
vector<SgStatement*> containsFunctions;
|
vector<SgStatement*> containsFunctions;
|
||||||
|
|
||||||
|
vector<SgStatement*> functions;
|
||||||
for (int i = 0; i < funcNum; ++i)
|
for (int i = 0; i < funcNum; ++i)
|
||||||
{
|
{
|
||||||
SgStatement *st = file->functions(i);
|
auto func = file->functions(i);
|
||||||
string containsPrefix = "";
|
functions.push_back(func);
|
||||||
|
|
||||||
SgStatement *st_cp = st->controlParent();
|
//find entry points
|
||||||
|
for (auto st = func->lexNext(); st != func->lastNodeOfStmt(); st = st->lexNext())
|
||||||
|
{
|
||||||
|
if (st->variant() == ENTRY_STAT)
|
||||||
|
functions.push_back(st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FuncInfo* lastNonEntry = NULL;
|
||||||
|
for (auto& function : functions)
|
||||||
|
{
|
||||||
|
bool isEntry = (function->variant() == ENTRY_STAT);
|
||||||
|
|
||||||
|
const int line = function->lineNumber();
|
||||||
|
const char* file = function->fileName();
|
||||||
|
|
||||||
|
string containsPrefix = "";
|
||||||
|
SgStatement* st_cp = isEntry ? function->controlParent()->controlParent() : function->controlParent();
|
||||||
if (st_cp->variant() == PROC_HEDR || st_cp->variant() == PROG_HEDR || st_cp->variant() == FUNC_HEDR)
|
if (st_cp->variant() == PROC_HEDR || st_cp->variant() == PROG_HEDR || st_cp->variant() == FUNC_HEDR)
|
||||||
containsPrefix = st_cp->symbol()->identifier() + string(".");
|
containsPrefix = st_cp->symbol()->identifier() + string(".");
|
||||||
else if (st_cp->variant() == INTERFACE_STMT)
|
else if (st_cp->variant() == INTERFACE_STMT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
string currFunc = "";
|
string funcName = "";
|
||||||
if (st->variant() == PROG_HEDR)
|
if (function->variant() == PROG_HEDR)
|
||||||
{
|
{
|
||||||
SgProgHedrStmt *progH = (SgProgHedrStmt*)st;
|
SgProgHedrStmt* progH = (SgProgHedrStmt*)function;
|
||||||
currFunc = progH->nameWithContains();
|
funcName = progH->nameWithContains();
|
||||||
__spf_print(DEBUG, "*** Program <%s> started at line %d / %s\n", progH->symbol()->identifier(), st->lineNumber(), st->fileName());
|
__spf_print(DEBUG, "*** Program <%s> started at line %d / %s\n", progH->symbol()->identifier(), line, file);
|
||||||
}
|
}
|
||||||
else if (st->variant() == PROC_HEDR)
|
else if (function->variant() == PROC_HEDR)
|
||||||
{
|
{
|
||||||
SgProcHedrStmt *procH = (SgProcHedrStmt*)st;
|
SgProcHedrStmt* procH = (SgProcHedrStmt*)function;
|
||||||
currFunc = procH->nameWithContains();
|
funcName = procH->nameWithContains();
|
||||||
__spf_print(DEBUG, "*** Function <%s> started at line %d / %s\n", procH->symbol()->identifier(), st->lineNumber(), st->fileName());
|
__spf_print(DEBUG, "*** Function <%s> started at line %d / %s\n", procH->symbol()->identifier(), line, file);
|
||||||
}
|
}
|
||||||
else if (st->variant() == FUNC_HEDR)
|
else if (function->variant() == FUNC_HEDR)
|
||||||
{
|
{
|
||||||
SgFuncHedrStmt *funcH = (SgFuncHedrStmt*)st;
|
SgFuncHedrStmt* funcH = (SgFuncHedrStmt*)function;
|
||||||
currFunc = funcH->nameWithContains();
|
funcName = funcH->nameWithContains();
|
||||||
__spf_print(DEBUG, "*** Function <%s> started at line %d / %s\n", funcH->symbol()->identifier(), st->lineNumber(), st->fileName());
|
__spf_print(DEBUG, "*** Function <%s> started at line %d / %s\n", funcH->symbol()->identifier(), line, file);
|
||||||
|
}
|
||||||
|
else if (function->variant() == ENTRY_STAT)
|
||||||
|
{
|
||||||
|
funcName = function->symbol()->identifier();
|
||||||
|
__spf_print(DEBUG, "*** Entry function <%s> started at line %d / %s\n", funcName.c_str(), line, file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
SgStatement *lastNode = st->lastNodeOfStmt();
|
set<SgStatement*> activeOps;
|
||||||
|
if (fullIR.size())
|
||||||
const string fileName = st->fileName();
|
|
||||||
auto it = allFuncInfo.find(fileName);
|
|
||||||
if (it == allFuncInfo.end())
|
|
||||||
it = allFuncInfo.insert(it, make_pair(fileName, vector<FuncInfo*>()));
|
|
||||||
|
|
||||||
map<string, vector<SgExpression*>> commonBlocks;
|
|
||||||
getCommonBlocksRef(commonBlocks, st, lastNode);
|
|
||||||
|
|
||||||
if (st->controlParent()->variant() == GLOBAL)
|
|
||||||
containsFunctions.clear();
|
|
||||||
|
|
||||||
findContainsFunctions(st, containsFunctions);
|
|
||||||
|
|
||||||
FuncInfo *currInfo = new FuncInfo(currFunc, make_pair(st->lineNumber(), lastNode->lineNumber()), new Statement(st));
|
|
||||||
hasThisIds(st, currInfo->linesOfIO, { WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT, PRINT_STAT });
|
|
||||||
hasThisIds(st, currInfo->linesOfStop, { STOP_STAT, PAUSE_NODE });
|
|
||||||
currInfo->isMain = (st->variant() == PROG_HEDR);
|
|
||||||
fillCommons(currInfo, commonBlocks);
|
|
||||||
fillFunctionPureStatus(st, currInfo, messagesForFile);
|
|
||||||
|
|
||||||
if (st->variant() != PROG_HEDR)
|
|
||||||
{
|
{
|
||||||
SgProgHedrStmt *procFuncHedr = ((SgProgHedrStmt*)st);
|
if (tmpInfoInIR.count(function) == 0)
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
fillFuncParams(currInfo, commonBlocks, procFuncHedr);
|
activeOps = fillActiveOperators(fullIR[tmpInfoInIR[function]]);
|
||||||
|
activeOps.insert(function);
|
||||||
// Fill in names of function parameters
|
if (isEntry)
|
||||||
for (int i = 0; i < procFuncHedr->numberOfParameters(); ++i)
|
activeOps.insert(function->controlParent());
|
||||||
{
|
|
||||||
currInfo->funcParams.identificators.push_back((procFuncHedr->parameter(i))->identifier());
|
|
||||||
currInfo->isParamUsedAsIndex.push_back(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
fillInOut(currInfo, st, st->lastNodeOfStmt());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSPF_NoInline(new Statement(st->lexNext())))
|
auto procInfo = analyzeFunction(funcName, containsPrefix, isEntry ? function->controlParent() : function, function, allFuncInfo, mapLoopGraph, messagesForFile, containsFunctions, activeOps);
|
||||||
|
|
||||||
|
if (isEntry)
|
||||||
{
|
{
|
||||||
__spf_print(1, "set NOINLINE attribute for function '%s'\n", currFunc.c_str());
|
if (!lastNonEntry)
|
||||||
currInfo->doNotInline = true;
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
}
|
lastNonEntry->entry.push_back(procInfo);
|
||||||
|
|
||||||
it->second.push_back(currInfo);
|
|
||||||
|
|
||||||
vector<FuncInfo*> entryProcs;
|
|
||||||
entryProcs.push_back(currInfo);
|
|
||||||
|
|
||||||
vector<SgStatement*> macroStats;
|
|
||||||
set<string> macroNames;
|
|
||||||
while (st != lastNode)
|
|
||||||
{
|
|
||||||
if (st->variant() == CONTAINS_STMT)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (st->variant() == INTERFACE_STMT)
|
|
||||||
{
|
|
||||||
st = st->lexNext();
|
|
||||||
while (st && !(st->controlParent()->variant() == INTERFACE_STMT && st->variant() == CONTROL_END))
|
|
||||||
{
|
|
||||||
if (st->variant() == PROC_HEDR || st->variant() == FUNC_HEDR)
|
|
||||||
{
|
|
||||||
currInfo->interfaceBlocks[st->symbol()->identifier()] = NULL;
|
|
||||||
st = st->lastNodeOfStmt();
|
|
||||||
}
|
|
||||||
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 (!isSgExecutableStatement(st))
|
|
||||||
{
|
|
||||||
if (st->variant() == STMTFN_STAT)
|
|
||||||
{
|
|
||||||
macroStats.push_back(st);
|
|
||||||
macroNames.insert(st->expr(0)->symbol()->identifier());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
st = st->lexNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
SgStatement* origStart = NULL;
|
|
||||||
origStart = st = file->functions(i);
|
|
||||||
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 (!__gcov_doesThisLineExecuted(st->fileName(), st->lineNumber()))
|
|
||||||
{
|
|
||||||
st = st->lexNext();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for external calls
|
|
||||||
if (st->variant() == EXTERN_STAT)
|
|
||||||
for (SgExpression* ex = st->expr(0); ex; ex = ex->rhs())
|
|
||||||
if (ex->lhs()->symbol())
|
|
||||||
currInfo->externalCalls.insert(ex->lhs()->symbol()->identifier());
|
|
||||||
|
|
||||||
const string prefix = containsPrefix == "" ? currFunc + "." : containsPrefix;
|
|
||||||
//printf("var %d, line %d, file %s\n", st->variant(), st->lineNumber(), st->fileName());
|
|
||||||
if (st->variant() == PROC_STAT)
|
|
||||||
{
|
|
||||||
vector<string> pureNameOfCallFunc;
|
|
||||||
pureNameOfCallFunc.push_back(removeString("call ", st->symbol()->identifier()));
|
|
||||||
pureNameOfCallFunc.push_back(removeString("call ", OriginalSymbol(st->symbol())->identifier()));
|
|
||||||
|
|
||||||
for (auto& elem : pureNameOfCallFunc)
|
|
||||||
correctNameIfContains(st, NULL, elem, containsFunctions, prefix);
|
|
||||||
|
|
||||||
for (auto &proc : entryProcs)
|
|
||||||
{
|
|
||||||
if (hasRecCall(proc, pureNameOfCallFunc))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
proc->callsFrom.insert(pureNameOfCallFunc.begin(), pureNameOfCallFunc.end());
|
|
||||||
|
|
||||||
FuncInfoCallFrom newCall;
|
|
||||||
newCall.detailCallsFrom = make_pair(pureNameOfCallFunc[1], st->lineNumber()); // original name of call
|
|
||||||
newCall.pointerDetailCallsFrom = make_pair(st, PROC_STAT);
|
|
||||||
newCall.parentForPointer = st;
|
|
||||||
newCall.actualParams = FuncParam();
|
|
||||||
|
|
||||||
processActualParams(st->expr(0), commonBlocks, newCall.actualParams, proc->externalCalls);
|
|
||||||
proc->callsFromDetailed.push_back(newCall);
|
|
||||||
|
|
||||||
// Add func call which we've just found
|
|
||||||
NestedFuncCall funcCall(pureNameOfCallFunc[1]);
|
|
||||||
proc->funcsCalledFromThis.push_back(funcCall);
|
|
||||||
|
|
||||||
// search for using pars of cur func in pars of called
|
|
||||||
throughParams(st->expr(0), *proc, containsFunctions, prefix);
|
|
||||||
|
|
||||||
//find external calls
|
|
||||||
for (SgExpression* par = st->expr(0); par != NULL; par = par->rhs())
|
|
||||||
{
|
|
||||||
SgExpression* curr = par->lhs();
|
|
||||||
if (curr)
|
|
||||||
{
|
|
||||||
if (curr->variant() == VAR_REF)
|
|
||||||
{
|
|
||||||
auto s = curr->symbol();
|
|
||||||
if (currInfo->externalCalls.find(s->identifier()) != currInfo->externalCalls.end() ||
|
|
||||||
(s->attributes() & EXTERNAL_BIT))
|
|
||||||
{
|
|
||||||
vector<string> nameOfCallFunc;
|
|
||||||
nameOfCallFunc.push_back(s->identifier());
|
|
||||||
nameOfCallFunc.push_back(OriginalSymbol(s)->identifier());
|
|
||||||
|
|
||||||
for (auto& elem : nameOfCallFunc)
|
|
||||||
correctNameIfContains(NULL, curr, elem, containsFunctions, prefix);
|
|
||||||
|
|
||||||
proc->callsFrom.insert(nameOfCallFunc.begin(), nameOfCallFunc.end());
|
|
||||||
|
|
||||||
FuncInfoCallFrom newCall;
|
|
||||||
newCall.detailCallsFrom = make_pair(nameOfCallFunc[1], st->lineNumber()); // original name of call
|
|
||||||
newCall.pointerDetailCallsFrom = make_pair(curr, VAR_REF);
|
|
||||||
newCall.parentForPointer = st;
|
|
||||||
newCall.actualParams = FuncParam();
|
|
||||||
|
|
||||||
proc->callsFromDetailed.push_back(newCall);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (auto &proc : entryProcs)
|
|
||||||
for (int i = 0; i < 3; ++i)
|
|
||||||
if (st->expr(i))
|
|
||||||
findParamUsedInFuncCalls(st->expr(i), *proc, containsFunctions, prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
|
||||||
if (st->expr(i))
|
|
||||||
findFuncCalls(st, st->expr(i), entryProcs, st->lineNumber(), commonBlocks, macroNames, containsFunctions, prefix);
|
|
||||||
|
|
||||||
if (st->variant() == ENTRY_STAT)
|
|
||||||
{
|
|
||||||
string entryName = st->symbol()->identifier();
|
|
||||||
FuncInfo *entryInfo = new FuncInfo(entryName, make_pair(st->lineNumber(), lastNode->lineNumber()), new Statement(st));
|
|
||||||
hasThisIds(st, entryInfo->linesOfIO, { WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT, PRINT_STAT });
|
|
||||||
hasThisIds(st, entryInfo->linesOfStop, { STOP_STAT, PAUSE_NODE });
|
|
||||||
fillCommons(entryInfo, commonBlocks);
|
|
||||||
fillFunctionPureStatus(st, entryInfo, messagesForFile);
|
|
||||||
|
|
||||||
fillFuncParams(entryInfo, commonBlocks, st);
|
|
||||||
|
|
||||||
if (isSPF_NoInline(new Statement(st->lexNext())))
|
|
||||||
{
|
|
||||||
__spf_print(1, "set NOINLINE attribute for function '%s'\n", entryName.c_str());
|
|
||||||
entryInfo->doNotInline = true;
|
|
||||||
}
|
|
||||||
it->second.push_back(entryInfo);
|
|
||||||
entryProcs.push_back(entryInfo);
|
|
||||||
|
|
||||||
fillInOut(entryInfo, origStart, origStart->lastNodeOfStmt());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSgExecutableStatement(st))
|
|
||||||
{
|
|
||||||
for (auto &proc : entryProcs)
|
|
||||||
if (proc->isParamUsedAsIndex.size())
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
findArrayRef(st->expr(i), *proc, st->variant() == ASSIGN_STAT && i == 0);
|
|
||||||
|
|
||||||
if (st->variant() == FOR_NODE)
|
|
||||||
{
|
|
||||||
auto itL = mapLoopGraph.find(st->lineNumber());
|
|
||||||
if (itL != mapLoopGraph.end())
|
|
||||||
{
|
|
||||||
for (auto &proc : entryProcs)
|
|
||||||
proc->loopsInFunc.push_back(itL->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
st = st->lexNext();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
lastNonEntry = procInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
//fill INTERFACE block from modules
|
//fill INTERFACE block from modules
|
||||||
@@ -1275,6 +1385,30 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto it = allFuncInfo.find(file->filename());
|
||||||
|
if (it == allFuncInfo.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fullIR.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vector<FuncInfo*> toRemove;
|
||||||
|
for (auto& func : it->second)
|
||||||
|
{
|
||||||
|
SgStatement* pointer = func->funcPointer->GetOriginal();
|
||||||
|
if (tmpInfoInIR.find(pointer) != tmpInfoInIR.end())
|
||||||
|
{
|
||||||
|
auto key = tmpInfoInIR[pointer];
|
||||||
|
toRemove.push_back(key);
|
||||||
|
|
||||||
|
fullIR[func] = fullIR[key];
|
||||||
|
fullIR.erase(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& func : toRemove)
|
||||||
|
delete func;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findLoopVarInParameter(SgExpression *ex, const string &loopSymb)
|
static bool findLoopVarInParameter(SgExpression *ex, const string &loopSymb)
|
||||||
|
|||||||
@@ -37,10 +37,17 @@ struct FuncParam
|
|||||||
parametersT.resize(numPar);
|
parametersT.resize(numPar);
|
||||||
inout_types.resize(numPar);
|
inout_types.resize(numPar);
|
||||||
std::fill(parametersT.begin(), parametersT.end(), NONE_T);
|
std::fill(parametersT.begin(), parametersT.end(), NONE_T);
|
||||||
std::fill(inout_types.begin(), inout_types.end(), IN_BIT);
|
std::fill(inout_types.begin(), inout_types.end(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void completeParams()
|
||||||
|
{
|
||||||
|
for (int z = 0; z < countOfPars; ++z)
|
||||||
|
if (inout_types[z] == 0)
|
||||||
|
inout_types[z] = IN_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
bool isArgIn(const int num) const
|
bool isArgIn(const int num) const
|
||||||
{
|
{
|
||||||
if (num >= countOfPars)
|
if (num >= countOfPars)
|
||||||
@@ -142,6 +149,8 @@ struct FuncInfo
|
|||||||
std::map<std::string, FuncInfo*> interfaceBlocks;
|
std::map<std::string, FuncInfo*> interfaceBlocks;
|
||||||
std::map<std::string, FuncInfo*> interfaceSynonims;
|
std::map<std::string, FuncInfo*> interfaceSynonims;
|
||||||
|
|
||||||
|
std::vector<FuncInfo*> entry; // all entry points
|
||||||
|
|
||||||
std::set<std::string> externalCalls;
|
std::set<std::string> externalCalls;
|
||||||
|
|
||||||
bool isPure; // does this func or funcs called from this have common block[s] and have no side effects
|
bool isPure; // does this func or funcs called from this have common block[s] and have no side effects
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ namespace Distribution
|
|||||||
}
|
}
|
||||||
namespace DIST = Distribution;
|
namespace DIST = Distribution;
|
||||||
|
|
||||||
|
namespace SAPFOR
|
||||||
|
{
|
||||||
|
class BasicBlock;
|
||||||
|
}
|
||||||
|
|
||||||
int CreateCallGraphViz(const char *fileName, const std::map<std::string, std::vector<FuncInfo*>> &funcByFile, std::map<std::string, CallV> &V, std::vector<std::string> &E);
|
int CreateCallGraphViz(const char *fileName, const std::map<std::string, std::vector<FuncInfo*>> &funcByFile, std::map<std::string, CallV> &V, std::vector<std::string> &E);
|
||||||
int CreateFuncInfo(const char *fileName, const std::map<std::string, std::vector<FuncInfo*>> &funcByFile);
|
int CreateFuncInfo(const char *fileName, const std::map<std::string, std::vector<FuncInfo*>> &funcByFile);
|
||||||
std::string removeString(const std::string &toRemove, const std::string &inStr);
|
std::string removeString(const std::string &toRemove, const std::string &inStr);
|
||||||
@@ -32,7 +37,7 @@ void updateFuncInfo(const std::map<std::string, std::vector<FuncInfo*>> &allFunc
|
|||||||
void excludeArraysFromDistribution(const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays, std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::vector<ParallelRegion*> parallelRegions, std::map<std::string, std::vector<Messages>>& SPF_messages, std::map<std::tuple<int, std::string, std::string>, DIST::Array*>& createdArrays, int mpiProgram = 0);
|
void excludeArraysFromDistribution(const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays, std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::vector<ParallelRegion*> parallelRegions, std::map<std::string, std::vector<Messages>>& SPF_messages, std::map<std::tuple<int, std::string, std::string>, DIST::Array*>& createdArrays, int mpiProgram = 0);
|
||||||
|
|
||||||
#if __SPF
|
#if __SPF
|
||||||
void functionAnalyzer(SgFile *file, std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, std::vector<LoopGraph*> &loops, std::vector<Messages> &messagesForFile, bool dontFillFuncParam = false);
|
void functionAnalyzer(SgFile *file, std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, const std::vector<LoopGraph*> &loops, std::vector<Messages> &messagesForFile, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR);
|
||||||
int CheckFunctionsToInline(SgProject *proj, const std::map<std::string, int> &files, const char *fileName,
|
int CheckFunctionsToInline(SgProject *proj, const std::map<std::string, int> &files, const char *fileName,
|
||||||
std::map<std::string, std::vector<FuncInfo*>> &funcByFile, const std::map<std::string, std::vector<LoopGraph*>> &loopGraph,
|
std::map<std::string, std::vector<FuncInfo*>> &funcByFile, const std::map<std::string, std::vector<LoopGraph*>> &loopGraph,
|
||||||
std::map<std::string, std::vector<Messages>> &allMessages, bool needToAddErrors,
|
std::map<std::string, std::vector<Messages>> &allMessages, bool needToAddErrors,
|
||||||
|
|||||||
@@ -318,24 +318,32 @@ bool checkRegionEntries(SgStatement *begin,
|
|||||||
return noError;
|
return noError;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasThisIds(SgStatement *start, set<int> &lines, const set<int> &IDs)
|
bool hasThisIds(SgStatement *start, set<int> &lines, const set<int> &IDs, const std::set<SgStatement*>* activeOps)
|
||||||
{
|
{
|
||||||
bool has = false;
|
bool has = false;
|
||||||
SgStatement *end = start->lastNodeOfStmt();
|
SgStatement *end = start->lastNodeOfStmt();
|
||||||
SgStatement *curr = start;
|
SgStatement *curr = start;
|
||||||
|
|
||||||
while (curr != end)
|
for ( ; curr != end; curr = curr->lexNext())
|
||||||
{
|
{
|
||||||
const int var = curr->variant();
|
const int var = curr->variant();
|
||||||
if (var == CONTAINS_STMT || var == ENTRY_STAT)
|
if (var == CONTAINS_STMT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (var == ENTRY_STAT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (activeOps && activeOps->size() && activeOps->find(curr) == activeOps->end())
|
||||||
|
{
|
||||||
|
curr = curr->lastNodeOfStmt();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (IDs.find(var) != IDs.end())
|
if (IDs.find(var) != IDs.end())
|
||||||
{
|
{
|
||||||
has = true;
|
has = true;
|
||||||
lines.insert(curr->lineNumber());
|
lines.insert(curr->lineNumber());
|
||||||
}
|
}
|
||||||
curr = curr->lexNext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return has;
|
return has;
|
||||||
@@ -564,6 +572,43 @@ static bool isLoopStat(SgStatement* st)
|
|||||||
return (var == FOR_NODE || var == WHILE_NODE);
|
return (var == FOR_NODE || var == WHILE_NODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hasSubstringRef(SgExpression* ex)
|
||||||
|
{
|
||||||
|
bool res = false;
|
||||||
|
if (ex)
|
||||||
|
{
|
||||||
|
if (ex->variant() == ARRAY_OP)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (ex->variant() == ARRAY_REF && !isArrayRef(ex))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (ex->lhs())
|
||||||
|
res |= hasSubstringRef(ex->lhs());
|
||||||
|
if (ex->rhs())
|
||||||
|
res |= hasSubstringRef(ex->rhs());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool hasSubstringRef(SgStatement* loop)
|
||||||
|
{
|
||||||
|
for (SgStatement* st = loop->lexNext(); st != loop->lastNodeOfStmt(); st = st->lexNext())
|
||||||
|
{
|
||||||
|
if (isSgExecutableStatement(st) && !isDVM_stat(st) && !isSPF_stat(st))
|
||||||
|
{
|
||||||
|
for (int z = 0; z < 3; ++z)
|
||||||
|
{
|
||||||
|
bool res = hasSubstringRef(st->expr(z));
|
||||||
|
if (res)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void loopGraphAnalyzer(SgFile *file, vector<LoopGraph*> &loopGraph, const vector<SpfInterval*> &intervalTree, vector<Messages> &messages, int mpiProgram)
|
void loopGraphAnalyzer(SgFile *file, vector<LoopGraph*> &loopGraph, const vector<SpfInterval*> &intervalTree, vector<Messages> &messages, int mpiProgram)
|
||||||
{
|
{
|
||||||
map<int, SpfInterval*> mapIntervals;
|
map<int, SpfInterval*> mapIntervals;
|
||||||
@@ -653,6 +698,7 @@ void loopGraphAnalyzer(SgFile *file, vector<LoopGraph*> &loopGraph, const vector
|
|||||||
newLoop->hasDvmIntervals = hasThisIds(st, tmpLines, { DVM_INTERVAL_DIR, DVM_ENDINTERVAL_DIR, DVM_EXIT_INTERVAL_DIR });
|
newLoop->hasDvmIntervals = hasThisIds(st, tmpLines, { DVM_INTERVAL_DIR, DVM_ENDINTERVAL_DIR, DVM_EXIT_INTERVAL_DIR });
|
||||||
newLoop->isFor = isSgForStmt(st) ? true : false;
|
newLoop->isFor = isSgForStmt(st) ? true : false;
|
||||||
newLoop->inCanonicalFrom = isSgForStmt(st) ? true : false;
|
newLoop->inCanonicalFrom = isSgForStmt(st) ? true : false;
|
||||||
|
newLoop->hasSubstringRefs = hasSubstringRef(st);
|
||||||
|
|
||||||
if (isSgForStmt(st))
|
if (isSgForStmt(st))
|
||||||
newLoop->hasNonRectangularBounds = hasNonRect(((SgForStmt*)st), parentLoops, messages);
|
newLoop->hasNonRectangularBounds = hasNonRect(((SgForStmt*)st), parentLoops, messages);
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ public:
|
|||||||
isFor = false;
|
isFor = false;
|
||||||
inCanonicalFrom = false;
|
inCanonicalFrom = false;
|
||||||
hasAccessToSubArray = false;
|
hasAccessToSubArray = false;
|
||||||
|
hasSubstringRefs = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~LoopGraph()
|
~LoopGraph()
|
||||||
@@ -112,7 +113,7 @@ public:
|
|||||||
{
|
{
|
||||||
return hasUnknownArrayDep || hasUnknownScalarDep || hasGoto || hasPrints || (hasConflicts.size() != 0) || hasStops || hasNonPureProcedures ||
|
return hasUnknownArrayDep || hasUnknownScalarDep || hasGoto || hasPrints || (hasConflicts.size() != 0) || hasStops || hasNonPureProcedures ||
|
||||||
hasUnknownArrayAssigns || hasNonRectangularBounds || hasIndirectAccess || hasWritesToNonDistribute || hasDifferentAlignRules || hasDvmIntervals ||
|
hasUnknownArrayAssigns || hasNonRectangularBounds || hasIndirectAccess || hasWritesToNonDistribute || hasDifferentAlignRules || hasDvmIntervals ||
|
||||||
!isFor || lastprivateScalars.size() || hasAccessToSubArray;
|
!isFor || lastprivateScalars.size() || hasAccessToSubArray || hasSubstringRefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasLimitsToSplit() const
|
bool hasLimitsToSplit() const
|
||||||
@@ -440,12 +441,15 @@ public:
|
|||||||
bool hasNonPureProcedures;
|
bool hasNonPureProcedures;
|
||||||
|
|
||||||
bool hasDvmIntervals;
|
bool hasDvmIntervals;
|
||||||
|
// make sense only for NODIST regime
|
||||||
|
bool hasAccessToSubArray;
|
||||||
|
|
||||||
|
bool hasSubstringRefs;
|
||||||
|
|
||||||
bool isFor;
|
bool isFor;
|
||||||
|
|
||||||
bool inCanonicalFrom;
|
bool inCanonicalFrom;
|
||||||
// make sense only for NODIST regime
|
|
||||||
bool hasAccessToSubArray;
|
|
||||||
|
|
||||||
std::vector<LoopGraph*> children;
|
std::vector<LoopGraph*> children;
|
||||||
std::vector<LoopGraph*> funcChildren;
|
std::vector<LoopGraph*> funcChildren;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ void findAllRefsToLables(SgStatement *st, std::map<int, std::vector<int>> &label
|
|||||||
std::map<LoopGraph*, ParallelDirective*> findAllDirectives(SgFile *file, const std::vector<LoopGraph*> &loops, const uint64_t regId);
|
std::map<LoopGraph*, ParallelDirective*> findAllDirectives(SgFile *file, const std::vector<LoopGraph*> &loops, const uint64_t regId);
|
||||||
std::vector<std::tuple<DIST::Array*, std::vector<long>, std::pair<std::string, int>>> findAllSingleRemotes(SgFile *file, const uint64_t regId, std::vector<ParallelRegion*> ®ions);
|
std::vector<std::tuple<DIST::Array*, std::vector<long>, std::pair<std::string, int>>> findAllSingleRemotes(SgFile *file, const uint64_t regId, std::vector<ParallelRegion*> ®ions);
|
||||||
std::map<DIST::Array*, std::vector<long>> fillRemoteInParallel(Statement *st);
|
std::map<DIST::Array*, std::vector<long>> fillRemoteInParallel(Statement *st);
|
||||||
bool hasThisIds(SgStatement *loop, std::set<int> &lines, const std::set<int> &IDs);
|
bool hasThisIds(SgStatement *loop, std::set<int> &lines, const std::set<int> &IDs, const std::set<SgStatement*>* activeOps = NULL);
|
||||||
bool checkRegionEntries(SgStatement *begin, SgStatement *end, const std::map<std::string, FuncInfo*> &funcMap, const std::vector<ParallelRegion*> ¶llelRegions, std::map<std::string, std::vector<Messages>> &SPF_messages);
|
bool checkRegionEntries(SgStatement *begin, SgStatement *end, const std::map<std::string, FuncInfo*> &funcMap, const std::vector<ParallelRegion*> ¶llelRegions, std::map<std::string, std::vector<Messages>> &SPF_messages);
|
||||||
bool recSymbolFind(SgExpression *ex, const std::string &symb, const int var);
|
bool recSymbolFind(SgExpression *ex, const std::string &symb, const int var);
|
||||||
void completeFillOfArrayUsageBetweenProc(const std::map<std::string, std::vector<LoopGraph*>>& loopGraph, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
|
void completeFillOfArrayUsageBetweenProc(const std::map<std::string, std::vector<LoopGraph*>>& loopGraph, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
|
||||||
|
|||||||
@@ -2774,9 +2774,9 @@ static void findArrayRefs(SgExpression *ex, SgStatement *st, string fName, int p
|
|||||||
{
|
{
|
||||||
DIST::Array* arrayToAdd =
|
DIST::Array* arrayToAdd =
|
||||||
new DIST::Array(getShortName(uniqKey), symb->identifier(), ((SgArrayType*)(symb->type()))->dimension(),
|
new DIST::Array(getShortName(uniqKey), symb->identifier(), ((SgArrayType*)(symb->type()))->dimension(),
|
||||||
getUniqArrayId(), decl->fileName(), decl->lineNumber(), arrayLocation, new Symbol(symb),
|
getUniqArrayId(), decl->fileName(), decl->lineNumber(), arrayLocation, new Symbol(symb),
|
||||||
findOmpThreadPrivDecl(scope, ompThreadPrivate, symb), false, false,
|
findOmpThreadPrivDecl(scope, ompThreadPrivate, symb), false, false,
|
||||||
inRegion, typeSize);
|
inRegion, typeSize, mpiProgram ? DIST::NO_DISTR : DIST::DISTR);
|
||||||
|
|
||||||
itNew = declaredArrays.insert(itNew, make_pair(uniqKey, make_pair(arrayToAdd, new DIST::ArrayAccessInfo())));
|
itNew = declaredArrays.insert(itNew, make_pair(uniqKey, make_pair(arrayToAdd, new DIST::ArrayAccessInfo())));
|
||||||
|
|
||||||
|
|||||||
@@ -497,7 +497,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
{
|
{
|
||||||
auto it = allFuncInfo.find(file_name);
|
auto it = allFuncInfo.find(file_name);
|
||||||
if (it == allFuncInfo.end())
|
if (it == allFuncInfo.end())
|
||||||
functionAnalyzer(file, allFuncInfo, getObjectForFileFromMap(file_name, loopGraph), getObjectForFileFromMap(file_name, SPF_messages));
|
functionAnalyzer(file, allFuncInfo, getObjectForFileFromMap(file_name, loopGraph), getObjectForFileFromMap(file_name, SPF_messages), fullIR);
|
||||||
}
|
}
|
||||||
else if (curr_regime == CALL_GRAPH2)
|
else if (curr_regime == CALL_GRAPH2)
|
||||||
{
|
{
|
||||||
@@ -905,7 +905,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
if (it == allFuncInfo_IR.end())
|
if (it == allFuncInfo_IR.end())
|
||||||
{
|
{
|
||||||
vector<LoopGraph*> tmp;
|
vector<LoopGraph*> tmp;
|
||||||
functionAnalyzer(file, allFuncInfo_IR, tmp, getObjectForFileFromMap(file_name, SPF_messages), true);
|
map<FuncInfo*, vector<SAPFOR::BasicBlock*>> tmp1;
|
||||||
|
|
||||||
|
functionAnalyzer(file, allFuncInfo_IR, tmp, getObjectForFileFromMap(file_name, SPF_messages), tmp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (curr_regime == ADD_TEMPL_TO_USE_ONLY)
|
else if (curr_regime == ADD_TEMPL_TO_USE_ONLY)
|
||||||
@@ -1034,26 +1036,10 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
if(func->funcPointer->variant() != ENTRY_STAT)
|
if(func->funcPointer->variant() != ENTRY_STAT)
|
||||||
countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
|
countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
|
||||||
}
|
}
|
||||||
|
else if (curr_regime == EXPLORE_IR_LOOPS)
|
||||||
|
testIR(fullIR);
|
||||||
else if (curr_regime == TEST_PASS)
|
else if (curr_regime == TEST_PASS)
|
||||||
{
|
{
|
||||||
/*int funcNum = file->numberOfFunctions();
|
|
||||||
for (int z = 0; z < funcNum; ++z)
|
|
||||||
{
|
|
||||||
SgStatement* f = file->functions(z);
|
|
||||||
for (auto st = f->lexNext(); st != f->lastNodeOfStmt(); st = st->lexNext())
|
|
||||||
{
|
|
||||||
if (st->variant() == CONTAINS_STMT)
|
|
||||||
break;
|
|
||||||
if (isSgExecutableStatement(st))
|
|
||||||
break;
|
|
||||||
|
|
||||||
string key = st->unparse();
|
|
||||||
if (same_decls.find(key) == same_decls.end())
|
|
||||||
same_decls[key] = 1;
|
|
||||||
else
|
|
||||||
same_decls[key]++;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
//test pass
|
//test pass
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1293,30 +1279,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
|
|
||||||
removeDistrStateFromDeadFunctions(allFuncInfo, declaredArrays);
|
removeDistrStateFromDeadFunctions(allFuncInfo, declaredArrays);
|
||||||
propagateArrayFlags(arrayLinksByFuncCalls, declaredArrays, SPF_messages);
|
propagateArrayFlags(arrayLinksByFuncCalls, declaredArrays, SPF_messages);
|
||||||
|
|
||||||
//replaced FuncInfo fullIR
|
|
||||||
map<FuncInfo*, vector<SAPFOR::BasicBlock*>> fullIR_new;
|
|
||||||
if (allFuncInfo_IR.size() != allFuncInfo.size())
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
|
|
||||||
for (auto& byFile : allFuncInfo_IR)
|
|
||||||
{
|
|
||||||
auto itByFileReal = allFuncInfo.find(byFile.first);
|
|
||||||
if (itByFileReal == allFuncInfo.end())
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
|
|
||||||
for (auto& func : byFile.second)
|
|
||||||
{
|
|
||||||
if (func->isInterface)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto itOld = fullIR.find(func);
|
|
||||||
if (itOld == fullIR.end())
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
fullIR_new[itOld->first] = itOld->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fullIR_new = fullIR;
|
|
||||||
}
|
}
|
||||||
else if (curr_regime == CALL_GRAPH2)
|
else if (curr_regime == CALL_GRAPH2)
|
||||||
{
|
{
|
||||||
@@ -1955,7 +1917,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
else if (curr_regime == FIX_COMMON_BLOCKS)
|
else if (curr_regime == FIX_COMMON_BLOCKS)
|
||||||
fixCommonBlocks(allFuncInfo, commonBlocks, &project);
|
fixCommonBlocks(allFuncInfo, commonBlocks, &project);
|
||||||
else if (curr_regime == SELECT_ARRAY_DIM_CONF) {
|
else if (curr_regime == SELECT_ARRAY_DIM_CONF) {
|
||||||
SelectArrayConfForParallelization(&project, allFuncInfo, loopGraph, SPF_messages, arrayLinksByFuncCalls);
|
;// SelectArrayConfForParallelization(&project, allFuncInfo, loopGraph, SPF_messages, arrayLinksByFuncCalls);
|
||||||
}
|
}
|
||||||
else if (curr_regime == GET_MIN_MAX_BLOCK_DIST)
|
else if (curr_regime == GET_MIN_MAX_BLOCK_DIST)
|
||||||
{
|
{
|
||||||
@@ -2472,7 +2434,7 @@ int main(int argc, char **argv)
|
|||||||
int numVar = 0;
|
int numVar = 0;
|
||||||
|
|
||||||
out_free_form = 0; // F90 style out
|
out_free_form = 0; // F90 style out
|
||||||
out_upper_case = 1;
|
out_upper_case = 0;
|
||||||
out_line_unlimit = 0;
|
out_line_unlimit = 0;
|
||||||
|
|
||||||
bool printText = false;
|
bool printText = false;
|
||||||
@@ -2605,8 +2567,10 @@ int main(int argc, char **argv)
|
|||||||
pppaAnalyzer(argc - i, argv + i);
|
pppaAnalyzer(argc - i, argv + i);
|
||||||
else if (string(curr_arg) == "-fdvm")
|
else if (string(curr_arg) == "-fdvm")
|
||||||
convertFiles(argc - i, argv + i);
|
convertFiles(argc - i, argv + i);
|
||||||
else if (string(curr_arg) == "-mpi")
|
else if (string(curr_arg) == "-mpi") {
|
||||||
mpiProgram = 1;
|
mpiProgram = 1;
|
||||||
|
ignoreArrayDistributeState = true;
|
||||||
|
}
|
||||||
else if (string(curr_arg) == "-client")
|
else if (string(curr_arg) == "-client")
|
||||||
{
|
{
|
||||||
runAsClient = true;
|
runAsClient = true;
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ enum passes {
|
|||||||
INSERT_NO_DISTR_FLAGS_FROM_GUI,
|
INSERT_NO_DISTR_FLAGS_FROM_GUI,
|
||||||
|
|
||||||
SET_IMPLICIT_NONE,
|
SET_IMPLICIT_NONE,
|
||||||
|
EXPLORE_IR_LOOPS,
|
||||||
|
|
||||||
TEST_PASS,
|
TEST_PASS,
|
||||||
EMPTY_PASS
|
EMPTY_PASS
|
||||||
@@ -360,6 +361,7 @@ static void setPassValues()
|
|||||||
passNames[CONVERT_TO_C] = "CONVERT_TO_C";
|
passNames[CONVERT_TO_C] = "CONVERT_TO_C";
|
||||||
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
|
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
|
||||||
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
|
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
|
||||||
|
passNames[EXPLORE_IR_LOOPS] = "EXPLORE_IR_LOOPS";
|
||||||
|
|
||||||
passNames[TEST_PASS] = "TEST_PASS";
|
passNames[TEST_PASS] = "TEST_PASS";
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -369,8 +369,11 @@ map<SgStatement*, set<string>> fillFromIntent(SgStatement* header)
|
|||||||
return intentS;
|
return intentS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void insertIntents(vector<string> identificators, SgStatement* header, map <string, SgSymbol*> parSym, int intentVariant, int intentBit)
|
static void insertIntents(set<string>& identificators, SgStatement* header, const map<string, SgSymbol*>& parSym, int intentVariant, int intentBit)
|
||||||
{
|
{
|
||||||
|
if (identificators.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (header->variant() == ENTRY_STAT)
|
if (header->variant() == ENTRY_STAT)
|
||||||
while (isSgProgHedrStmt(header) == NULL)
|
while (isSgProgHedrStmt(header) == NULL)
|
||||||
header = header->controlParent();
|
header = header->controlParent();
|
||||||
@@ -388,67 +391,58 @@ static void insertIntents(vector<string> identificators, SgStatement* header, ma
|
|||||||
if (stmt->variant() != ENTRY_STAT)
|
if (stmt->variant() != ENTRY_STAT)
|
||||||
lastDecl = stmt;
|
lastDecl = stmt;
|
||||||
|
|
||||||
if (stmt->variant() == VAR_DECL_90)
|
if (stmt->variant() == VAR_DECL_90)
|
||||||
{
|
{
|
||||||
SgVarDeclStmt* s = (SgVarDeclStmt*)stmt;
|
SgVarDeclStmt* s = (SgVarDeclStmt*)stmt;
|
||||||
for (int i = 0; i < s->numberOfAttributes(); i++)
|
for (int i = 0; i < s->numberOfAttributes(); i++)
|
||||||
{
|
{
|
||||||
if (s->attribute(i)->variant() == intentVariant)
|
if (s->attribute(i)->variant() == intentVariant)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < s->numberOfVars(); i++)
|
for (int i = 0; i < s->numberOfVars(); i++)
|
||||||
{
|
{
|
||||||
for (auto it = identificators.begin(); it != identificators.end(); it++)
|
auto sname = s->var(i)->symbol()->identifier();
|
||||||
{
|
if (identificators.count(sname))
|
||||||
if (*it == s->var(i)->symbol()->identifier())
|
identificators.erase(sname);
|
||||||
{
|
|
||||||
identificators.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (stmt->variant() == INTENT_STMT)
|
else if (stmt->variant() == INTENT_STMT)
|
||||||
{
|
{
|
||||||
SgIntentStmt* s = (SgIntentStmt*)stmt;
|
SgIntentStmt* s = (SgIntentStmt*)stmt;
|
||||||
if (s->attribute()->variant() == intentVariant)
|
if (s->attribute()->variant() == intentVariant)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < s->numberOfVars(); i++)
|
for (int i = 0; i < s->numberOfVars(); i++)
|
||||||
{
|
{
|
||||||
for (auto it = identificators.begin(); it != identificators.end(); it++)
|
auto sname = s->var(i)->symbol()->identifier();
|
||||||
{
|
if (identificators.count(sname))
|
||||||
if (*it == s->var(i)->symbol()->identifier())
|
identificators.erase(sname);
|
||||||
{
|
|
||||||
identificators.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (identificators.size() > 0)
|
SgExpression* attr = new SgExpression(intentVariant);
|
||||||
|
SgExpression* args = NULL;
|
||||||
|
for (auto& par : identificators)
|
||||||
{
|
{
|
||||||
SgExpression* attr = new SgExpression(intentVariant);
|
if (parSym.count(par) == 0)
|
||||||
SgExpression* args = NULL;
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
for (auto& par : identificators)
|
auto s = parSym.at(par);
|
||||||
{
|
|
||||||
SgExprListExp* tempArgs = new SgExprListExp();
|
|
||||||
SgVarRefExp* tempPar = new SgVarRefExp(parSym[par]);
|
|
||||||
tempArgs->setLhs(tempPar);
|
|
||||||
if (args)
|
|
||||||
tempArgs->setRhs(args);
|
|
||||||
args = tempArgs;
|
|
||||||
parSym[par]->setAttribute(parSym[par]->attributes() | intentBit);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
SgExprListExp* tempArgs = new SgExprListExp();
|
||||||
|
SgVarRefExp* tempPar = new SgVarRefExp(s);
|
||||||
|
tempArgs->setLhs(tempPar);
|
||||||
if (args)
|
if (args)
|
||||||
{
|
tempArgs->setRhs(args);
|
||||||
SgIntentStmt* intent = new SgIntentStmt(*args, *attr);
|
args = tempArgs;
|
||||||
lastDecl->insertStmtAfter(*intent, (header == lastDecl) ? *header : *lastDecl->controlParent());
|
s->setAttribute(s->attributes() | intentBit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args)
|
||||||
|
{
|
||||||
|
SgIntentStmt* intent = new SgIntentStmt(*args, *attr);
|
||||||
|
lastDecl->insertStmtAfter(*intent, (header == lastDecl) ? *header : *lastDecl->controlParent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,12 +470,14 @@ static SgSymbol* getParameter(SgStatement* stat, int n)
|
|||||||
|
|
||||||
static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
|
static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
|
||||||
{
|
{
|
||||||
vector <string> InIdentificators;
|
if (func->funcPointer->variant() == ENTRY_STAT)
|
||||||
vector <string> OutIdentificators;
|
return;
|
||||||
vector <string> InOutIdentificators;
|
|
||||||
|
|
||||||
|
|
||||||
map <string, SgSymbol*> parSym;
|
set<string> InIdentificators;
|
||||||
|
set<string> OutIdentificators;
|
||||||
|
set<string> InOutIdentificators;
|
||||||
|
|
||||||
|
map<string, SgSymbol*> parSym;
|
||||||
set<string> intentS;
|
set<string> intentS;
|
||||||
auto intentsByStat = fillFromIntent(headerSt);
|
auto intentsByStat = fillFromIntent(headerSt);
|
||||||
for (auto& elem : intentsByStat)
|
for (auto& elem : intentsByStat)
|
||||||
@@ -494,8 +490,7 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
|
|||||||
SgSymbol* parS = getParameter(headerSt, i);
|
SgSymbol* parS = getParameter(headerSt, i);
|
||||||
const string ident = parS->identifier();
|
const string ident = parS->identifier();
|
||||||
|
|
||||||
if (ident == "*" ||
|
if (ident == "*" || parS->attributes() & EXTERNAL_BIT)
|
||||||
parS->attributes() & EXTERNAL_BIT)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
parSym[ident] = parS;
|
parSym[ident] = parS;
|
||||||
@@ -503,11 +498,41 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (func->funcParams.isArgInOut(i))
|
if (func->funcParams.isArgInOut(i))
|
||||||
InOutIdentificators.push_back(ident);
|
InOutIdentificators.insert(ident);
|
||||||
else if (func->funcParams.isArgIn(i))
|
else if (func->funcParams.isArgIn(i))
|
||||||
InIdentificators.push_back(ident);
|
InIdentificators.insert(ident);
|
||||||
else if (func->funcParams.isArgOut(i))
|
else if (func->funcParams.isArgOut(i))
|
||||||
OutIdentificators.push_back(ident);
|
OutIdentificators.insert(ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove conflicted intents
|
||||||
|
for (auto& entry : func->entry)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < entry->funcParams.countOfPars; i++)
|
||||||
|
{
|
||||||
|
const auto& ident = entry->funcParams.identificators[i];
|
||||||
|
if (entry->funcParams.isArgInOut(i))
|
||||||
|
{
|
||||||
|
if (InIdentificators.count(ident))
|
||||||
|
InIdentificators.erase(ident);
|
||||||
|
if (OutIdentificators.count(ident))
|
||||||
|
OutIdentificators.erase(ident);
|
||||||
|
}
|
||||||
|
else if (entry->funcParams.isArgIn(i))
|
||||||
|
{
|
||||||
|
if (InOutIdentificators.count(ident))
|
||||||
|
InOutIdentificators.erase(ident);
|
||||||
|
if (OutIdentificators.count(ident))
|
||||||
|
OutIdentificators.erase(ident);
|
||||||
|
}
|
||||||
|
else if (entry->funcParams.isArgOut(i))
|
||||||
|
{
|
||||||
|
if (InIdentificators.count(ident))
|
||||||
|
InIdentificators.erase(ident);
|
||||||
|
if (InOutIdentificators.count(ident))
|
||||||
|
InOutIdentificators.erase(ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
insertIntents(InOutIdentificators, headerSt, parSym, INOUT_OP, INOUT_BIT);
|
insertIntents(InOutIdentificators, headerSt, parSym, INOUT_OP, INOUT_BIT);
|
||||||
@@ -985,7 +1010,7 @@ void commonTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo, const map
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static string changeData(const string data, const map<string, string>& constSymVars, const map<string, string>& locVars)
|
static string changeData(const string& data, const map<string, string>& constSymVars, const map<string, string>& locVars)
|
||||||
{
|
{
|
||||||
int curChar = 0;
|
int curChar = 0;
|
||||||
string ident = "";
|
string ident = "";
|
||||||
@@ -2066,7 +2091,6 @@ static bool isIntrincis(const string& name)
|
|||||||
intrinsicF.insert(string("trailz"));
|
intrinsicF.insert(string("trailz"));
|
||||||
intrinsicF.insert(string("trim"));
|
intrinsicF.insert(string("trim"));
|
||||||
intrinsicF.insert(string("xor"));
|
intrinsicF.insert(string("xor"));
|
||||||
intrinsicF.insert(string("wtime"));
|
|
||||||
intrinsicF.insert(string("zabs"));
|
intrinsicF.insert(string("zabs"));
|
||||||
intrinsicF.insert(string("zcos"));
|
intrinsicF.insert(string("zcos"));
|
||||||
intrinsicF.insert(string("zexp"));
|
intrinsicF.insert(string("zexp"));
|
||||||
|
|||||||
@@ -30,19 +30,33 @@ static void FillCommonTypes(map<char, SgType*>& types)
|
|||||||
types[letter.first] = new SgType(T_FLOAT);
|
types[letter.first] = new SgType(T_FLOAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FindAllVars(SgExpression* expr, set<SgSymbol*>& allVars, set<SgSymbol*>& allVarsConst)
|
static void FindAllVars(SgExpression* expr, set<SgSymbol*>& allVars, set<SgSymbol*>& allVarsConst, SgStatement* scope)
|
||||||
{
|
{
|
||||||
if (expr == NULL)
|
if (expr == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const int var = expr->variant();
|
const int var = expr->variant();
|
||||||
if (var == VAR_REF || var == ARRAY_REF)
|
if (var == VAR_REF || var == ARRAY_REF || var == FUNC_CALL)
|
||||||
allVars.insert(expr->symbol());
|
{
|
||||||
if (var == CONST_REF)
|
auto s = expr->symbol();
|
||||||
|
if ((s->attributes() & EXTERNAL_BIT))
|
||||||
|
{
|
||||||
|
if (var == FUNC_CALL && !IS_BY_USE(s) && s->scope() == scope)
|
||||||
|
allVars.insert(s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!IS_BY_USE(s) && s->scope() == scope)
|
||||||
|
{
|
||||||
|
allVars.insert(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (var == CONST_REF)
|
||||||
allVarsConst.insert(expr->symbol());
|
allVarsConst.insert(expr->symbol());
|
||||||
|
|
||||||
FindAllVars(expr->lhs(), allVars, allVarsConst);
|
FindAllVars(expr->lhs(), allVars, allVarsConst, scope);
|
||||||
FindAllVars(expr->rhs(), allVars, allVarsConst);
|
FindAllVars(expr->rhs(), allVars, allVarsConst, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char getValue(SgExpression* ex)
|
static char getValue(SgExpression* ex)
|
||||||
@@ -85,7 +99,7 @@ static void AddLettersToMap(SgExpression* expr, SgType* type, map<char, SgType*>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static vector<SgSymbol*> getVars(const char* funcSymbol, set<SgSymbol*>& toRename,
|
static vector<SgSymbol*> getVars(const set<string>& functionSymbs, set<SgSymbol*>& toRename,
|
||||||
const set<SgSymbol*>& allVars, const map<char, SgType*>& types)
|
const set<SgSymbol*>& allVars, const map<char, SgType*>& types)
|
||||||
{
|
{
|
||||||
vector<SgSymbol*> varsWithoutDecl;
|
vector<SgSymbol*> varsWithoutDecl;
|
||||||
@@ -99,7 +113,7 @@ static vector<SgSymbol*> getVars(const char* funcSymbol, set<SgSymbol*>& toRenam
|
|||||||
|
|
||||||
for (auto& var : allVars)
|
for (auto& var : allVars)
|
||||||
{
|
{
|
||||||
if (string(var->identifier()) == funcSymbol)
|
if (functionSymbs.count(var->identifier()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vector<SgStatement*> allDecls;
|
vector<SgStatement*> allDecls;
|
||||||
@@ -180,16 +194,77 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
|
|||||||
else if (st->variant() == CONTAINS_STMT || isSgExecutableStatement(st) != NULL)
|
else if (st->variant() == CONTAINS_STMT || isSgExecutableStatement(st) != NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set<int> skip = { EXTERN_STAT };
|
||||||
|
|
||||||
|
set<SgSymbol*> allDataSymbols;
|
||||||
|
for (auto s = function->symbol()->next(); s; s = s->next())
|
||||||
|
if ((s->attributes() & DATA_BIT) && s->scope() == function)
|
||||||
|
allDataSymbols.insert(s);
|
||||||
|
|
||||||
|
set<string> functionSymbs = { function->symbol()->identifier() };
|
||||||
|
if (isSgFuncHedrStmt(function))
|
||||||
|
{
|
||||||
|
SgFuncHedrStmt* hedr = isSgFuncHedrStmt(function);
|
||||||
|
if (hedr->resultName())
|
||||||
|
functionSymbs.insert(hedr->resultName()->identifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto st = function->lexNext(); st != endOfFunc && st->variant() != CONTAINS_STMT; st = st->lexNext())
|
||||||
|
{
|
||||||
|
if (skip.count(st->variant()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (isDVM_stat(st) || isSPF_stat(st))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (st->variant() == INTERFACE_STMT)
|
||||||
|
{
|
||||||
|
st = st->lastNodeOfStmt();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->variant() == DATA_DECL)
|
||||||
|
{
|
||||||
|
const string str = st->expr(0)->thellnd->entry.string_val;
|
||||||
|
|
||||||
|
for (auto& data : allDataSymbols)
|
||||||
|
{
|
||||||
|
if (str.find(data->identifier()) != string::npos)
|
||||||
|
allVars.insert(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto st = function; st != endOfFunc && st->variant() != CONTAINS_STMT; st = st->lexNext())
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
FindAllVars(st->expr(i), allVars, allVarsConst);
|
FindAllVars(st->expr(i), allVars, allVarsConst, function);
|
||||||
|
|
||||||
varsWithoutDecl = getVars(function->symbol()->identifier(), toRename, allVars, types);
|
if (st->variant() == FOR_NODE)
|
||||||
varsWithoutDeclConst = getVars(function->symbol()->identifier(), toRename, allVarsConst, types);
|
{
|
||||||
|
auto s = isSgForStmt(st)->doName();
|
||||||
|
if (!IS_BY_USE(s) && s->scope() == function)
|
||||||
|
allVars.insert(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//add parameters
|
||||||
|
auto prog = isSgProgHedrStmt(function);
|
||||||
|
if (prog)
|
||||||
|
{
|
||||||
|
for (int z = 0; z < prog->numberOfParameters(); ++z)
|
||||||
|
{
|
||||||
|
auto s = prog->parameter(z);
|
||||||
|
if ((s->attributes() & EXTERNAL_BIT) == 0)
|
||||||
|
allVars.insert(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
varsWithoutDecl = getVars(functionSymbs, toRename, allVars, types);
|
||||||
|
varsWithoutDeclConst = getVars(functionSymbs, toRename, allVarsConst, types);
|
||||||
|
|
||||||
if (!hasImplicitNone)
|
if (!hasImplicitNone)
|
||||||
{
|
{
|
||||||
|
vector<SgStatement*> macro;
|
||||||
|
|
||||||
for (auto st = function->lexNext();
|
for (auto st = function->lexNext();
|
||||||
st != endOfFunc && st->variant() != CONTAINS_STMT && isSgExecutableStatement(st) == NULL;
|
st != endOfFunc && st->variant() != CONTAINS_STMT && isSgExecutableStatement(st) == NULL;
|
||||||
)
|
)
|
||||||
@@ -200,6 +275,12 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
|
|||||||
st = st->lexNext();
|
st = st->lexNext();
|
||||||
tmpStatement->deleteStmt();
|
tmpStatement->deleteStmt();
|
||||||
}
|
}
|
||||||
|
else if (st->variant() == STMTFN_STAT)
|
||||||
|
{
|
||||||
|
auto stat = st;
|
||||||
|
st = st->lexNext();
|
||||||
|
macro.push_back(stat->extractStmt());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
st = st->lexNext();
|
st = st->lexNext();
|
||||||
}
|
}
|
||||||
@@ -215,16 +296,42 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
|
|||||||
insertPlace->insertStmtAfter(*implNone, *function);
|
insertPlace->insertStmtAfter(*implNone, *function);
|
||||||
insertPlace = insertPlace->lexNext();
|
insertPlace = insertPlace->lexNext();
|
||||||
|
|
||||||
|
if (function->variant() == FUNC_HEDR)
|
||||||
|
{
|
||||||
|
SgFuncHedrStmt* hedr = isSgFuncHedrStmt(function);
|
||||||
|
|
||||||
|
auto type_op = function->expr(1);
|
||||||
|
if (type_op == NULL)
|
||||||
|
{
|
||||||
|
if (hedr->resultName())
|
||||||
|
varsWithoutDecl.push_back(hedr->resultName());
|
||||||
|
else
|
||||||
|
varsWithoutDecl.push_back(function->symbol());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
makeDeclaration(varsWithoutDecl, function);
|
makeDeclaration(varsWithoutDecl, function);
|
||||||
|
|
||||||
auto declList = makeDeclaration(varsWithoutDeclConst, NULL);
|
auto declList = makeDeclaration(varsWithoutDeclConst, NULL);
|
||||||
for (auto& decl : declList)
|
for (auto& decl : declList)
|
||||||
insertPlace->insertStmtAfter(*decl, *function);
|
insertPlace->insertStmtAfter(*decl, *function);
|
||||||
|
|
||||||
|
if (macro.size())
|
||||||
|
{
|
||||||
|
while (!isSgExecutableStatement(insertPlace) && insertPlace != NULL)
|
||||||
|
insertPlace = insertPlace->lexNext();
|
||||||
|
|
||||||
|
if (insertPlace == NULL)
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
|
for (auto& elem : macro)
|
||||||
|
insertPlace->insertStmtBefore(*elem, *function);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& s : toRename)
|
for (auto& s : toRename)
|
||||||
s->changeName(TestAndCorrectName((string(s->identifier()) + "_").c_str()));
|
s->changeName(TestAndCorrectName((string(s->identifier()) + "_").c_str()));
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,9 +339,12 @@ void implicitCheck(SgFile* file)
|
|||||||
{
|
{
|
||||||
map<SgStatement*, map<char, SgType*>> typesByFunctions;
|
map<SgStatement*, map<char, SgType*>> typesByFunctions;
|
||||||
|
|
||||||
for (int func = 0; func < file->numberOfFunctions(); ++func)
|
vector<SgStatement*> modulesAndFunctions;
|
||||||
|
getModulesAndFunctions(file, modulesAndFunctions);
|
||||||
|
|
||||||
|
for (int func = 0; func < modulesAndFunctions.size(); ++func)
|
||||||
{
|
{
|
||||||
SgStatement* function = file->functions(func);
|
SgStatement* function = modulesAndFunctions[func];
|
||||||
typesByFunctions[function] = FunctionImplicitCheck(function, typesByFunctions);
|
typesByFunctions[function] = FunctionImplicitCheck(function, typesByFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -310,6 +310,10 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
|
|||||||
list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(REMOVE_DEAD_CODE);
|
list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(REMOVE_DEAD_CODE);
|
||||||
list({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);
|
list({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);
|
||||||
|
|
||||||
|
Pass(CORRECT_VAR_DECL) <= Pass(SET_IMPLICIT_NONE);
|
||||||
|
|
||||||
|
list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2 }) <= Pass(EXPLORE_IR_LOOPS);
|
||||||
|
|
||||||
passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS,
|
passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS,
|
||||||
EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,
|
EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,
|
||||||
REVERSE_CREATED_NESTED_LOOPS, PREDICT_SCHEME, CALCULATE_STATS_SCHEME, REVERT_SPF_DIRS, CLEAR_SPF_DIRS, TRANSFORM_SHADOW_IF_FULL,
|
REVERSE_CREATED_NESTED_LOOPS, PREDICT_SCHEME, CALCULATE_STATS_SCHEME, REVERT_SPF_DIRS, CLEAR_SPF_DIRS, TRANSFORM_SHADOW_IF_FULL,
|
||||||
|
|||||||
@@ -997,17 +997,19 @@ static bool findSymbol(SgExpression *declLst, const string &toFind)
|
|||||||
SgExpression* ex = exs.top();
|
SgExpression* ex = exs.top();
|
||||||
exs.pop();
|
exs.pop();
|
||||||
|
|
||||||
if (ex->variant() == ARRAY_REF || ex->variant() == VAR_REF)
|
if (ex->variant() == ARRAY_REF || ex->variant() == VAR_REF || ex->variant() == CONST_REF)
|
||||||
{
|
{
|
||||||
if (ex->symbol()->identifier() == toFind)
|
if (ex->symbol()->identifier() == toFind)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ex->lhs())
|
||||||
|
exs.push(ex->lhs());
|
||||||
|
|
||||||
if (ex->lhs())
|
if (ex->rhs())
|
||||||
exs.push(ex->lhs());
|
exs.push(ex->rhs());
|
||||||
|
}
|
||||||
if (ex->rhs())
|
|
||||||
exs.push(ex->rhs());
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1553,7 +1555,9 @@ void constructDefUseStep1(SgFile *file, map<string, vector<DefUseList>> &defUseB
|
|||||||
{
|
{
|
||||||
map<string, vector<FuncInfo*>> curFileFuncInfo;
|
map<string, vector<FuncInfo*>> curFileFuncInfo;
|
||||||
vector<LoopGraph*> tmpL;
|
vector<LoopGraph*> tmpL;
|
||||||
functionAnalyzer(file, curFileFuncInfo, tmpL, messages);
|
map<FuncInfo*, vector<SAPFOR::BasicBlock*>> tmpIR;
|
||||||
|
|
||||||
|
functionAnalyzer(file, curFileFuncInfo, tmpL, messages, tmpIR);
|
||||||
|
|
||||||
//functions not found
|
//functions not found
|
||||||
if (curFileFuncInfo.size() == 0)
|
if (curFileFuncInfo.size() == 0)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION_SPF "2329"
|
#define VERSION_SPF "2341"
|
||||||
|
|||||||
@@ -590,7 +590,6 @@ bool checkAndMoveFormatOperators(SgFile* file, vector<Messages>& currMessages, b
|
|||||||
SgStatement* lastNode = st->lastNodeOfStmt();
|
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||||
|
|
||||||
vector<SgStatement*> toMove;
|
vector<SgStatement*> toMove;
|
||||||
SgStatement* firstExec = NULL;
|
|
||||||
while (st != lastNode)
|
while (st != lastNode)
|
||||||
{
|
{
|
||||||
if (st == NULL)
|
if (st == NULL)
|
||||||
@@ -602,11 +601,8 @@ bool checkAndMoveFormatOperators(SgFile* file, vector<Messages>& currMessages, b
|
|||||||
if (st->variant() == CONTAINS_STMT)
|
if (st->variant() == CONTAINS_STMT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (isSgExecutableStatement(st) && !isDVM_stat(st) && !isSPF_stat(st))
|
if (isSgExecutableStatement(st) && !isDVM_stat(st) && !isSPF_stat(st))
|
||||||
{
|
|
||||||
firstExec = st;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (st->variant() == FORMAT_STAT)
|
if (st->variant() == FORMAT_STAT)
|
||||||
{
|
{
|
||||||
@@ -630,9 +626,8 @@ bool checkAndMoveFormatOperators(SgFile* file, vector<Messages>& currMessages, b
|
|||||||
{
|
{
|
||||||
if (!withError)
|
if (!withError)
|
||||||
{
|
{
|
||||||
checkNull(firstExec, convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
for (auto& format : toMove)
|
for (auto& format : toMove)
|
||||||
firstExec->insertStmtBefore(*format, *firstExec->controlParent());
|
lastNode->insertStmtBefore(*format, *lastNode->controlParent());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user