10 Commits

Author SHA1 Message Date
172eedfef1 WIP add analizing IR loop 2024-05-26 12:32:53 +03:00
ALEXks
62e4c5cdfe improved checkpoints 2024-05-16 14:15:02 +03:00
ALEXks
69cba903ee added new implementation of checkpoints by Anton Milienkov 2024-05-16 09:23:02 +03:00
ALEXks
2fa0eb3e42 fixed implicit pass 2024-05-15 17:54:18 +03:00
ALEXks
87a4413472 fixed implicit pass 2024-05-14 12:53:31 +03:00
ALEXks
f88e1f570c improved shared memory parallelization 2024-05-13 18:09:45 +03:00
ALEXks
0b6a915753 fixed implicit none and imterfaces insertion 2024-05-13 10:37:59 +03:00
ALEXks
4a13250d1c improved intent insertion 2024-05-12 13:37:42 +03:00
ALEXks
b0d4a1cac5 improved in/out analysis 2024-05-11 16:45:15 +03:00
ALEXks
00ca5fbfdf improved function analysis 2024-05-11 15:38:41 +03:00
22 changed files with 1679 additions and 885 deletions

2
.gitignore vendored
View File

@@ -74,3 +74,5 @@ sapfor/experts/Sapfor_2017/Sapc++/Sapc++/x64/
sapfor/experts/Sapfor_2017/Sapc++/x64/
/build
sapfor/experts/Sapfor_2017/out/

View File

@@ -1613,3 +1613,118 @@ vector<IR_Block*> buildIR(SgStatement* function, const FuncInfo* func, const vec
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;
}*/
}
}

View File

@@ -313,3 +313,5 @@ SAPFOR::Instruction* getInstructionByNumber(const std::vector<SAPFOR::IR_Block*>
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);
int getParamIndex(SAPFOR::Argument* func_param, int max_index);
void testIR(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>> fullIR);

View File

@@ -158,10 +158,10 @@ namespace Distribution
Array(const STRING &name, const STRING &shortName, const int dimSize, const unsigned id,
const STRING &declFile, const int declLine, const PAIR<arrayLocation, STRING> &locationPos,
Symbol *declSymbol, bool inOmpThreadPriv, bool privateInLoop, bool inEquivalence,
const VECTOR<STRING> &regions, const int typeSize) :
const VECTOR<STRING> &regions, const int typeSize, const distFlag flag = DISTR) :
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),
ompThreadPrivate(inOmpThreadPriv), privateInLoop(privateInLoop), inEquivalence(inEquivalence)
{

View File

@@ -960,10 +960,12 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
st = copy->lexNext();
while (st != last)
{
if (st->variant() == VAR_DECL
|| st->variant() == VAR_DECL_90
|| st->variant() == DIM_STAT
|| st->variant() == INTENT_STMT)
const int var = st->variant();
if (var == VAR_DECL
|| var == VAR_DECL_90
|| var == DIM_STAT
|| var == INTENT_STMT
|| var == EXTERN_STAT)
{
bool empty = filterFromList(st, idents);
if (empty)

View File

@@ -12,13 +12,14 @@
#include <stack>
#include "dvm.h"
#include "../GraphLoop/graph_loops_func.h"
#include "graph_calls_func.h"
#include "../CFGraph/CFGraph.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../Utils/SgUtils.h"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "acc_analyzer.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../VerificationCode/verifications.h"
@@ -203,8 +204,16 @@ static void fillFuncParams(FuncInfo *currInfo, const map<string, vector<SgExpres
currParams.init(numOfParams);
if (numOfParams > 0)
{
for (int i = 0; i < numOfParams; ++i)
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)
@@ -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> &macroNames,
const vector<SgStatement*> &containsFunctions, const string &prefix)
{
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());
nameOfCallFunc.push_back(OriginalSymbol(curr->symbol())->identifier());
vector<string> nameOfCallFunc;
nameOfCallFunc.push_back(curr->symbol()->identifier());
nameOfCallFunc.push_back(OriginalSymbol(curr->symbol())->identifier());
for (auto& elem : nameOfCallFunc)
correctNameIfContains(NULL, curr, elem, containsFunctions, prefix);
for (auto& elem : nameOfCallFunc)
correctNameIfContains(NULL, curr, elem, containsFunctions, prefix);
proc->callsFrom.insert(nameOfCallFunc.begin(), nameOfCallFunc.end());
procInfo->callsFrom.insert(nameOfCallFunc.begin(), nameOfCallFunc.end());
FuncInfoCallFrom newCall;
newCall.detailCallsFrom = make_pair(nameOfCallFunc[1], line); // original name of call
newCall.pointerDetailCallsFrom = make_pair(curr, FUNC_CALL);
newCall.parentForPointer = parent;
newCall.actualParams = FuncParam();
FuncInfoCallFrom newCall;
newCall.detailCallsFrom = make_pair(nameOfCallFunc[1], line); // original name of call
newCall.pointerDetailCallsFrom = make_pair(curr, FUNC_CALL);
newCall.parentForPointer = parent;
newCall.actualParams = FuncParam();
processActualParams(curr->lhs(), commonBlocks, newCall.actualParams, proc->externalCalls);
proc->callsFromDetailed.push_back(newCall);
}
processActualParams(curr->lhs(), commonBlocks, newCall.actualParams, procInfo->externalCalls);
procInfo->callsFromDetailed.push_back(newCall);
}
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())
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,
@@ -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 != "")
{
auto it = parNames.find(symb);
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());
if (valExp->value() == string("unit"))
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)
@@ -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)
return;
@@ -786,6 +792,12 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
if (isSgExecutableStatement(st) == NULL || st->lineNumber() <= 0)
continue;
if (activeOps.size() && activeOps.find(st) == activeOps.end())
{
st = st->lastNodeOfStmt();
continue;
}
if (st->variant() == ASSIGN_STAT)
{
SgExpression *left = st->expr(0);
@@ -802,7 +814,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
if (left->lhs()->symbol())
symb = left->lhs()->symbol()->identifier();
}
fillOut(currF, symb, parNames);
fillType(currF, symb, parNames, OUT_BIT);
} // TODO: need to extend
else if (st->variant() == READ_STAT)
{
@@ -818,7 +830,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
string symb = "";
if (item->symbol())
symb = item->symbol()->identifier();
fillOut(currF, symb, parNames);
fillType(currF, symb, parNames, OUT_BIT);
}
else if (item->variant() == IOACCESS)
{
@@ -839,7 +851,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
string symb = "";
if (item->symbol())
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__);
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)
fillIn(currF, arg, parNames);
}
@@ -894,12 +906,12 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last)
}
//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)
{
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);
if (declaratedAsPure && !hasIntent && ((SgProgHedrStmt*)header)->numberOfParameters())
@@ -913,7 +925,9 @@ static void fillFunctionPureStatus(SgStatement *header, FuncInfo *currInfo, vect
lines.clear();
bool has = hasThisIds(header, lines, { DATA_DECL, SAVE_DECL, USE_STMT,
WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT,
PRINT_STAT, STOP_STAT, PAUSE_NODE });
PRINT_STAT, STOP_STAT, PAUSE_NODE },
&activeOps);
if (!has || declaratedAsPure)
currInfo->isPure = true;
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;
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();
__spf_print(DEBUG, "functions num in file = %d\n", funcNum);
vector<SgStatement*> containsFunctions;
vector<SgStatement*> functions;
for (int i = 0; i < funcNum; ++i)
{
SgStatement *st = file->functions(i);
string containsPrefix = "";
auto func = file->functions(i);
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)
containsPrefix = st_cp->symbol()->identifier() + string(".");
else if (st_cp->variant() == INTERFACE_STMT)
continue;
string currFunc = "";
if (st->variant() == PROG_HEDR)
string funcName = "";
if (function->variant() == PROG_HEDR)
{
SgProgHedrStmt *progH = (SgProgHedrStmt*)st;
currFunc = progH->nameWithContains();
__spf_print(DEBUG, "*** Program <%s> started at line %d / %s\n", progH->symbol()->identifier(), st->lineNumber(), st->fileName());
SgProgHedrStmt* progH = (SgProgHedrStmt*)function;
funcName = progH->nameWithContains();
__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;
currFunc = procH->nameWithContains();
__spf_print(DEBUG, "*** Function <%s> started at line %d / %s\n", procH->symbol()->identifier(), st->lineNumber(), st->fileName());
SgProcHedrStmt* procH = (SgProcHedrStmt*)function;
funcName = procH->nameWithContains();
__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;
currFunc = funcH->nameWithContains();
__spf_print(DEBUG, "*** Function <%s> started at line %d / %s\n", funcH->symbol()->identifier(), st->lineNumber(), st->fileName());
SgFuncHedrStmt* funcH = (SgFuncHedrStmt*)function;
funcName = funcH->nameWithContains();
__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
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement *lastNode = st->lastNodeOfStmt();
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)
set<SgStatement*> activeOps;
if (fullIR.size())
{
SgProgHedrStmt *procFuncHedr = ((SgProgHedrStmt*)st);
if (tmpInfoInIR.count(function) == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
fillFuncParams(currInfo, commonBlocks, procFuncHedr);
// Fill in names of function parameters
for (int i = 0; i < procFuncHedr->numberOfParameters(); ++i)
{
currInfo->funcParams.identificators.push_back((procFuncHedr->parameter(i))->identifier());
currInfo->isParamUsedAsIndex.push_back(false);
}
fillInOut(currInfo, st, st->lastNodeOfStmt());
activeOps = fillActiveOperators(fullIR[tmpInfoInIR[function]]);
activeOps.insert(function);
if (isEntry)
activeOps.insert(function->controlParent());
}
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());
currInfo->doNotInline = true;
}
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();
if (!lastNonEntry)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
lastNonEntry->entry.push_back(procInfo);
}
else
lastNonEntry = procInfo;
}
//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)

View File

@@ -37,10 +37,17 @@ struct FuncParam
parametersT.resize(numPar);
inout_types.resize(numPar);
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
{
if (num >= countOfPars)
@@ -142,6 +149,8 @@ struct FuncInfo
std::map<std::string, FuncInfo*> interfaceBlocks;
std::map<std::string, FuncInfo*> interfaceSynonims;
std::vector<FuncInfo*> entry; // all entry points
std::set<std::string> externalCalls;
bool isPure; // does this func or funcs called from this have common block[s] and have no side effects

View File

@@ -14,6 +14,11 @@ namespace 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 CreateFuncInfo(const char *fileName, const std::map<std::string, std::vector<FuncInfo*>> &funcByFile);
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);
#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,
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,

View File

@@ -318,24 +318,32 @@ bool checkRegionEntries(SgStatement *begin,
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;
SgStatement *end = start->lastNodeOfStmt();
SgStatement *curr = start;
while (curr != end)
for ( ; curr != end; curr = curr->lexNext())
{
const int var = curr->variant();
if (var == CONTAINS_STMT || var == ENTRY_STAT)
if (var == CONTAINS_STMT)
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())
{
has = true;
lines.insert(curr->lineNumber());
}
curr = curr->lexNext();
}
return has;
@@ -564,6 +572,43 @@ static bool isLoopStat(SgStatement* st)
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)
{
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->isFor = isSgForStmt(st) ? true : false;
newLoop->inCanonicalFrom = isSgForStmt(st) ? true : false;
newLoop->hasSubstringRefs = hasSubstringRef(st);
if (isSgForStmt(st))
newLoop->hasNonRectangularBounds = hasNonRect(((SgForStmt*)st), parentLoops, messages);

View File

@@ -73,6 +73,7 @@ public:
isFor = false;
inCanonicalFrom = false;
hasAccessToSubArray = false;
hasSubstringRefs = false;
}
~LoopGraph()
@@ -112,7 +113,7 @@ public:
{
return hasUnknownArrayDep || hasUnknownScalarDep || hasGoto || hasPrints || (hasConflicts.size() != 0) || hasStops || hasNonPureProcedures ||
hasUnknownArrayAssigns || hasNonRectangularBounds || hasIndirectAccess || hasWritesToNonDistribute || hasDifferentAlignRules || hasDvmIntervals ||
!isFor || lastprivateScalars.size() || hasAccessToSubArray;
!isFor || lastprivateScalars.size() || hasAccessToSubArray || hasSubstringRefs;
}
bool hasLimitsToSplit() const
@@ -440,12 +441,15 @@ public:
bool hasNonPureProcedures;
bool hasDvmIntervals;
// make sense only for NODIST regime
bool hasAccessToSubArray;
bool hasSubstringRefs;
bool isFor;
bool inCanonicalFrom;
// make sense only for NODIST regime
bool hasAccessToSubArray;
std::vector<LoopGraph*> children;
std::vector<LoopGraph*> funcChildren;

View File

@@ -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::vector<std::tuple<DIST::Array*, std::vector<long>, std::pair<std::string, int>>> findAllSingleRemotes(SgFile *file, const uint64_t regId, std::vector<ParallelRegion*> &regions);
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*> &parallelRegions, std::map<std::string, std::vector<Messages>> &SPF_messages);
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);

View File

@@ -2774,9 +2774,9 @@ static void findArrayRefs(SgExpression *ex, SgStatement *st, string fName, int p
{
DIST::Array* arrayToAdd =
new DIST::Array(getShortName(uniqKey), symb->identifier(), ((SgArrayType*)(symb->type()))->dimension(),
getUniqArrayId(), decl->fileName(), decl->lineNumber(), arrayLocation, new Symbol(symb),
findOmpThreadPrivDecl(scope, ompThreadPrivate, symb), false, false,
inRegion, typeSize);
getUniqArrayId(), decl->fileName(), decl->lineNumber(), arrayLocation, new Symbol(symb),
findOmpThreadPrivDecl(scope, ompThreadPrivate, symb), false, false,
inRegion, typeSize, mpiProgram ? DIST::NO_DISTR : DIST::DISTR);
itNew = declaredArrays.insert(itNew, make_pair(uniqKey, make_pair(arrayToAdd, new DIST::ArrayAccessInfo())));

View File

@@ -497,7 +497,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{
auto it = allFuncInfo.find(file_name);
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)
{
@@ -905,7 +905,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
if (it == allFuncInfo_IR.end())
{
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)
@@ -1034,26 +1036,10 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
if(func->funcPointer->variant() != ENTRY_STAT)
countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
}
else if (curr_regime == EXPLORE_IR_LOOPS)
testIR(fullIR);
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
}
@@ -1293,30 +1279,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
removeDistrStateFromDeadFunctions(allFuncInfo, declaredArrays);
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)
{
@@ -1955,7 +1917,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == FIX_COMMON_BLOCKS)
fixCommonBlocks(allFuncInfo, commonBlocks, &project);
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)
{
@@ -2472,7 +2434,7 @@ int main(int argc, char **argv)
int numVar = 0;
out_free_form = 0; // F90 style out
out_upper_case = 1;
out_upper_case = 0;
out_line_unlimit = 0;
bool printText = false;
@@ -2605,8 +2567,10 @@ int main(int argc, char **argv)
pppaAnalyzer(argc - i, argv + i);
else if (string(curr_arg) == "-fdvm")
convertFiles(argc - i, argv + i);
else if (string(curr_arg) == "-mpi")
else if (string(curr_arg) == "-mpi") {
mpiProgram = 1;
ignoreArrayDistributeState = true;
}
else if (string(curr_arg) == "-client")
{
runAsClient = true;

View File

@@ -178,6 +178,7 @@ enum passes {
INSERT_NO_DISTR_FLAGS_FROM_GUI,
SET_IMPLICIT_NONE,
EXPLORE_IR_LOOPS,
TEST_PASS,
EMPTY_PASS
@@ -360,6 +361,7 @@ static void setPassValues()
passNames[CONVERT_TO_C] = "CONVERT_TO_C";
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
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";
}

File diff suppressed because it is too large Load Diff

View File

@@ -369,8 +369,11 @@ map<SgStatement*, set<string>> fillFromIntent(SgStatement* header)
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)
while (isSgProgHedrStmt(header) == NULL)
header = header->controlParent();
@@ -397,14 +400,9 @@ static void insertIntents(vector<string> identificators, SgStatement* header, ma
{
for (int i = 0; i < s->numberOfVars(); i++)
{
for (auto it = identificators.begin(); it != identificators.end(); it++)
{
if (*it == s->var(i)->symbol()->identifier())
{
identificators.erase(it);
break;
}
}
auto sname = s->var(i)->symbol()->identifier();
if (identificators.count(sname))
identificators.erase(sname);
}
}
}
@@ -416,39 +414,35 @@ static void insertIntents(vector<string> identificators, SgStatement* header, ma
{
for (int i = 0; i < s->numberOfVars(); i++)
{
for (auto it = identificators.begin(); it != identificators.end(); it++)
{
if (*it == s->var(i)->symbol()->identifier())
{
identificators.erase(it);
break;
}
}
auto sname = s->var(i)->symbol()->identifier();
if (identificators.count(sname))
identificators.erase(sname);
}
}
}
}
if (identificators.size() > 0)
SgExpression* attr = new SgExpression(intentVariant);
SgExpression* args = NULL;
for (auto& par : identificators)
{
SgExpression* attr = new SgExpression(intentVariant);
SgExpression* args = NULL;
for (auto& par : identificators)
{
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);
}
if (parSym.count(par) == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto s = parSym.at(par);
SgExprListExp* tempArgs = new SgExprListExp();
SgVarRefExp* tempPar = new SgVarRefExp(s);
tempArgs->setLhs(tempPar);
if (args)
{
SgIntentStmt* intent = new SgIntentStmt(*args, *attr);
lastDecl->insertStmtAfter(*intent, (header == lastDecl) ? *header : *lastDecl->controlParent());
}
tempArgs->setRhs(args);
args = tempArgs;
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)
{
vector <string> InIdentificators;
vector <string> OutIdentificators;
vector <string> InOutIdentificators;
if (func->funcPointer->variant() == ENTRY_STAT)
return;
set<string> InIdentificators;
set<string> OutIdentificators;
set<string> InOutIdentificators;
map <string, SgSymbol*> parSym;
map<string, SgSymbol*> parSym;
set<string> intentS;
auto intentsByStat = fillFromIntent(headerSt);
for (auto& elem : intentsByStat)
@@ -494,8 +490,7 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
SgSymbol* parS = getParameter(headerSt, i);
const string ident = parS->identifier();
if (ident == "*" ||
parS->attributes() & EXTERNAL_BIT)
if (ident == "*" || parS->attributes() & EXTERNAL_BIT)
continue;
parSym[ident] = parS;
@@ -503,11 +498,41 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
continue;
if (func->funcParams.isArgInOut(i))
InOutIdentificators.push_back(ident);
InOutIdentificators.insert(ident);
else if (func->funcParams.isArgIn(i))
InIdentificators.push_back(ident);
InIdentificators.insert(ident);
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);
@@ -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;
string ident = "";
@@ -2066,7 +2091,6 @@ static bool isIntrincis(const string& name)
intrinsicF.insert(string("trailz"));
intrinsicF.insert(string("trim"));
intrinsicF.insert(string("xor"));
intrinsicF.insert(string("wtime"));
intrinsicF.insert(string("zabs"));
intrinsicF.insert(string("zcos"));
intrinsicF.insert(string("zexp"));

View File

@@ -30,19 +30,33 @@ static void FillCommonTypes(map<char, SgType*>& types)
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)
return;
const int var = expr->variant();
if (var == VAR_REF || var == ARRAY_REF)
allVars.insert(expr->symbol());
if (var == CONST_REF)
if (var == VAR_REF || var == ARRAY_REF || var == FUNC_CALL)
{
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());
FindAllVars(expr->lhs(), allVars, allVarsConst);
FindAllVars(expr->rhs(), allVars, allVarsConst);
FindAllVars(expr->lhs(), allVars, allVarsConst, scope);
FindAllVars(expr->rhs(), allVars, allVarsConst, scope);
}
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)
{
vector<SgSymbol*> varsWithoutDecl;
@@ -99,7 +113,7 @@ static vector<SgSymbol*> getVars(const char* funcSymbol, set<SgSymbol*>& toRenam
for (auto& var : allVars)
{
if (string(var->identifier()) == funcSymbol)
if (functionSymbs.count(var->identifier()))
continue;
vector<SgStatement*> allDecls;
@@ -181,15 +195,76 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
break;
}
for (auto st = function; st != endOfFunc && st->variant() != CONTAINS_STMT; st = st->lexNext())
for (int i = 0; i < 3; ++i)
FindAllVars(st->expr(i), allVars, allVarsConst);
set<int> skip = { EXTERN_STAT };
varsWithoutDecl = getVars(function->symbol()->identifier(), toRename, allVars, types);
varsWithoutDeclConst = getVars(function->symbol()->identifier(), toRename, allVarsConst, types);
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 (int i = 0; i < 3; ++i)
FindAllVars(st->expr(i), allVars, allVarsConst, function);
if (st->variant() == FOR_NODE)
{
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)
{
vector<SgStatement*> macro;
for (auto st = function->lexNext();
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();
tmpStatement->deleteStmt();
}
else if (st->variant() == STMTFN_STAT)
{
auto stat = st;
st = st->lexNext();
macro.push_back(stat->extractStmt());
}
else
st = st->lexNext();
}
@@ -215,11 +296,37 @@ static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map
insertPlace->insertStmtAfter(*implNone, *function);
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);
auto declList = makeDeclaration(varsWithoutDeclConst, NULL);
for (auto& decl : declList)
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)
@@ -232,9 +339,12 @@ void implicitCheck(SgFile* file)
{
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);
}

View File

@@ -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({ 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,
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,

View File

@@ -997,17 +997,19 @@ static bool findSymbol(SgExpression *declLst, const string &toFind)
SgExpression* ex = exs.top();
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)
return true;
}
else
{
if (ex->lhs())
exs.push(ex->lhs());
if (ex->lhs())
exs.push(ex->lhs());
if (ex->rhs())
exs.push(ex->rhs());
if (ex->rhs())
exs.push(ex->rhs());
}
}
return false;
}
@@ -1553,7 +1555,9 @@ void constructDefUseStep1(SgFile *file, map<string, vector<DefUseList>> &defUseB
{
map<string, vector<FuncInfo*>> curFileFuncInfo;
vector<LoopGraph*> tmpL;
functionAnalyzer(file, curFileFuncInfo, tmpL, messages);
map<FuncInfo*, vector<SAPFOR::BasicBlock*>> tmpIR;
functionAnalyzer(file, curFileFuncInfo, tmpL, messages, tmpIR);
//functions not found
if (curFileFuncInfo.size() == 0)

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2329"
#define VERSION_SPF "2341"

View File

@@ -590,7 +590,6 @@ bool checkAndMoveFormatOperators(SgFile* file, vector<Messages>& currMessages, b
SgStatement* lastNode = st->lastNodeOfStmt();
vector<SgStatement*> toMove;
SgStatement* firstExec = NULL;
while (st != lastNode)
{
if (st == NULL)
@@ -603,10 +602,7 @@ bool checkAndMoveFormatOperators(SgFile* file, vector<Messages>& currMessages, b
break;
if (isSgExecutableStatement(st) && !isDVM_stat(st) && !isSPF_stat(st))
{
firstExec = st;
break;
}
if (st->variant() == FORMAT_STAT)
{
@@ -630,9 +626,8 @@ bool checkAndMoveFormatOperators(SgFile* file, vector<Messages>& currMessages, b
{
if (!withError)
{
checkNull(firstExec, convertFileName(__FILE__).c_str(), __LINE__);
for (auto& format : toMove)
firstExec->insertStmtBefore(*format, *firstExec->controlParent());
lastNode->insertStmtBefore(*format, *lastNode->controlParent());
}
else
{