improved function analysis

This commit is contained in:
ALEXks
2024-05-11 15:38:41 +03:00
parent 0197fd3a4b
commit 00ca5fbfdf
11 changed files with 472 additions and 318 deletions

View File

@@ -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> &regions, const int typeSize) : const VECTOR<STRING> &regions, 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)
{ {

View File

@@ -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,13 +350,11 @@ 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 map<string, vector<SgExpression*>> &commonBlocks, const set<string> &macroNames,
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; vector<string> nameOfCallFunc;
nameOfCallFunc.push_back(curr->symbol()->identifier()); nameOfCallFunc.push_back(curr->symbol()->identifier());
@@ -356,7 +363,7 @@ static void findFuncCalls(SgStatement *parent, SgExpression *curr, vector<FuncIn
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
@@ -364,15 +371,14 @@ static void findFuncCalls(SgStatement *parent, SgExpression *curr, vector<FuncIn
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,
@@ -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);
@@ -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,99 +961,67 @@ 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)
{ {
map<int, LoopGraph*> mapLoopGraph; SgStatement* lastNode = st->lastNodeOfStmt();
createMapLoopGraph(loops, mapLoopGraph);
int funcNum = file->numberOfFunctions(); FuncInfo* currInfo = new FuncInfo(funcName, make_pair(entry->lineNumber(), lastNode->lineNumber()), new Statement(entry));
__spf_print(DEBUG, "functions num in file = %d\n", funcNum); hasThisIds(st, currInfo->linesOfIO, { WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT, PRINT_STAT }, &activeOps);
vector<SgStatement*> containsFunctions; hasThisIds(st, currInfo->linesOfStop, { STOP_STAT, PAUSE_NODE }, &activeOps);
currInfo->isMain = (st->variant() == PROG_HEDR);
fillCommons(currInfo, commonBlocks);
fillFunctionPureStatus(st, currInfo, messagesForFile, activeOps);
for (int i = 0; i < funcNum; ++i) if (st->variant() != PROG_HEDR)
{ {
SgStatement *st = file->functions(i); SgProgHedrStmt* procFuncHedr = ((SgProgHedrStmt*)st);
string containsPrefix = "";
SgStatement *st_cp = st->controlParent(); if (st == entry)
if (st_cp->variant() == PROC_HEDR || st_cp->variant() == PROG_HEDR || st_cp->variant() == FUNC_HEDR) fillFuncParams(currInfo, commonBlocks, procFuncHedr);
containsPrefix = st_cp->symbol()->identifier() + string(".");
else if (st_cp->variant() == INTERFACE_STMT)
continue;
string currFunc = "";
if (st->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());
}
else if (st->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());
}
else if (st->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());
}
else else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); fillFuncParams(currInfo, commonBlocks, entry);
fillInOut(currInfo, st, lastNode, activeOps);
}
SgStatement *lastNode = st->lastNodeOfStmt(); if (isSPF_NoInline(new Statement(st->lexNext())))
{
__spf_print(1, "set NOINLINE attribute for function '%s'\n", funcName.c_str());
currInfo->doNotInline = true;
}
const string fileName = st->fileName(); return currInfo;
}
static void 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); auto it = allFuncInfo.find(fileName);
if (it == allFuncInfo.end()) if (it == allFuncInfo.end())
it = allFuncInfo.insert(it, make_pair(fileName, vector<FuncInfo*>())); it = allFuncInfo.insert(it, make_pair(fileName, vector<FuncInfo*>()));
map<string, vector<SgExpression*>> commonBlocks; map<string, vector<SgExpression*>> commonBlocks;
getCommonBlocksRef(commonBlocks, st, lastNode); getCommonBlocksRef(commonBlocks, function, lastNode);
if (st->controlParent()->variant() == GLOBAL) if (function->controlParent()->variant() == GLOBAL)
containsFunctions.clear(); containsFunctions.clear();
findContainsFunctions(st, containsFunctions); findContainsFunctions(function, containsFunctions);
auto procInfo = createNewFuction(funcName, function, entry, messagesForFile, commonBlocks, activeOps);
FuncInfo *currInfo = new FuncInfo(currFunc, make_pair(st->lineNumber(), lastNode->lineNumber()), new Statement(st)); it->second.push_back(procInfo);
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);
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());
}
if (isSPF_NoInline(new Statement(st->lexNext())))
{
__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; vector<SgStatement*> macroStats;
set<string> macroNames; set<string> macroNames;
while (st != lastNode) while (st != lastNode)
{ {
if (st->variant() == CONTAINS_STMT) if (st->variant() == CONTAINS_STMT)
@@ -1052,7 +1034,7 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
{ {
if (st->variant() == PROC_HEDR || st->variant() == FUNC_HEDR) if (st->variant() == PROC_HEDR || st->variant() == FUNC_HEDR)
{ {
currInfo->interfaceBlocks[st->symbol()->identifier()] = NULL; procInfo->interfaceBlocks[st->symbol()->identifier()] = NULL;
st = st->lastNodeOfStmt(); st = st->lastNodeOfStmt();
} }
st = st->lexNext(); st = st->lexNext();
@@ -1078,8 +1060,9 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
st = st->lexNext(); st = st->lexNext();
} }
SgStatement* origStart = NULL; st = function;
origStart = st = file->functions(i); const string file = st->fileName();
while (st != lastNode) while (st != lastNode)
{ {
if (st == NULL) if (st == NULL)
@@ -1091,19 +1074,32 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
if (st->variant() == CONTAINS_STMT) if (st->variant() == CONTAINS_STMT)
break; break;
if (!__gcov_doesThisLineExecuted(st->fileName(), st->lineNumber())) if (!__gcov_doesThisLineExecuted(st->fileName(), st->lineNumber()) ||
st->variant() == ENTRY_STAT)
{ {
st = st->lexNext(); st = st->lexNext();
continue; 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 // check for external calls
if (st->variant() == EXTERN_STAT) if (st->variant() == EXTERN_STAT)
for (SgExpression* ex = st->expr(0); ex; ex = ex->rhs()) for (SgExpression* ex = st->expr(0); ex; ex = ex->rhs())
if (ex->lhs()->symbol()) if (ex->lhs()->symbol())
currInfo->externalCalls.insert(ex->lhs()->symbol()->identifier()); procInfo->externalCalls.insert(ex->lhs()->symbol()->identifier());
const string prefix = containsPrefix == "" ? currFunc + "." : containsPrefix; const string prefix = containsPrefix == "" ? string(function->symbol()->identifier()) + "." : containsPrefix;
//printf("var %d, line %d, file %s\n", st->variant(), st->lineNumber(), st->fileName()); //printf("var %d, line %d, file %s\n", st->variant(), st->lineNumber(), st->fileName());
if (st->variant() == PROC_STAT) if (st->variant() == PROC_STAT)
{ {
@@ -1114,12 +1110,10 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
for (auto& elem : pureNameOfCallFunc) for (auto& elem : pureNameOfCallFunc)
correctNameIfContains(st, NULL, elem, containsFunctions, prefix); correctNameIfContains(st, NULL, elem, containsFunctions, prefix);
for (auto &proc : entryProcs) if (hasRecCall(procInfo, pureNameOfCallFunc))
{
if (hasRecCall(proc, pureNameOfCallFunc))
continue; continue;
proc->callsFrom.insert(pureNameOfCallFunc.begin(), pureNameOfCallFunc.end()); procInfo->callsFrom.insert(pureNameOfCallFunc.begin(), pureNameOfCallFunc.end());
FuncInfoCallFrom newCall; FuncInfoCallFrom newCall;
newCall.detailCallsFrom = make_pair(pureNameOfCallFunc[1], st->lineNumber()); // original name of call newCall.detailCallsFrom = make_pair(pureNameOfCallFunc[1], st->lineNumber()); // original name of call
@@ -1127,15 +1121,15 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
newCall.parentForPointer = st; newCall.parentForPointer = st;
newCall.actualParams = FuncParam(); newCall.actualParams = FuncParam();
processActualParams(st->expr(0), commonBlocks, newCall.actualParams, proc->externalCalls); processActualParams(st->expr(0), commonBlocks, newCall.actualParams, procInfo->externalCalls);
proc->callsFromDetailed.push_back(newCall); procInfo->callsFromDetailed.push_back(newCall);
// Add func call which we've just found // Add func call which we've just found
NestedFuncCall funcCall(pureNameOfCallFunc[1]); NestedFuncCall funcCall(pureNameOfCallFunc[1]);
proc->funcsCalledFromThis.push_back(funcCall); procInfo->funcsCalledFromThis.push_back(funcCall);
// search for using pars of cur func in pars of called // search for using pars of cur func in pars of called
throughParams(st->expr(0), *proc, containsFunctions, prefix); throughParams(st->expr(0), *procInfo, containsFunctions, prefix);
//find external calls //find external calls
for (SgExpression* par = st->expr(0); par != NULL; par = par->rhs()) for (SgExpression* par = st->expr(0); par != NULL; par = par->rhs())
@@ -1146,7 +1140,7 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
if (curr->variant() == VAR_REF) if (curr->variant() == VAR_REF)
{ {
auto s = curr->symbol(); auto s = curr->symbol();
if (currInfo->externalCalls.find(s->identifier()) != currInfo->externalCalls.end() || if (procInfo->externalCalls.find(s->identifier()) != procInfo->externalCalls.end() ||
(s->attributes() & EXTERNAL_BIT)) (s->attributes() & EXTERNAL_BIT))
{ {
vector<string> nameOfCallFunc; vector<string> nameOfCallFunc;
@@ -1156,7 +1150,7 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
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], st->lineNumber()); // original name of call newCall.detailCallsFrom = make_pair(nameOfCallFunc[1], st->lineNumber()); // original name of call
@@ -1164,8 +1158,7 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
newCall.parentForPointer = st; newCall.parentForPointer = st;
newCall.actualParams = FuncParam(); newCall.actualParams = FuncParam();
proc->callsFromDetailed.push_back(newCall); procInfo->callsFromDetailed.push_back(newCall);
}
} }
} }
} }
@@ -1173,58 +1166,161 @@ void functionAnalyzer(SgFile *file, map<string, vector<FuncInfo*>> &allFuncInfo,
} }
else else
{ {
for (auto &proc : entryProcs)
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
if (st->expr(i)) if (st->expr(i))
findParamUsedInFuncCalls(st->expr(i), *proc, containsFunctions, prefix); findParamUsedInFuncCalls(st->expr(i), *procInfo, containsFunctions, prefix);
} }
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
if (st->expr(i)) if (st->expr(i))
findFuncCalls(st, st->expr(i), entryProcs, st->lineNumber(), commonBlocks, macroNames, containsFunctions, prefix); findFuncCalls(st, st->expr(i), procInfo, 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)) if (isSgExecutableStatement(st))
{ {
for (auto &proc : entryProcs) if (procInfo->isParamUsedAsIndex.size())
if (proc->isParamUsedAsIndex.size())
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
findArrayRef(st->expr(i), *proc, st->variant() == ASSIGN_STAT && i == 0); findArrayRef(st->expr(i), *procInfo, st->variant() == ASSIGN_STAT && i == 0);
if (st->variant() == FOR_NODE) if (st->variant() == FOR_NODE)
{ {
auto itL = mapLoopGraph.find(st->lineNumber()); auto itL = mapLoopGraph.find(st->lineNumber());
if (itL != mapLoopGraph.end()) if (itL != mapLoopGraph.end())
{ procInfo->loopsInFunc.push_back(itL->second);
for (auto &proc : entryProcs)
proc->loopsInFunc.push_back(itL->second);
}
} }
} }
st = st->lexNext(); st = st->lexNext();
} }
}
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)
{
auto func = file->functions(i);
functions.push_back(func);
//find entry points
for (auto st = func->lexNext(); st != func->lastNodeOfStmt(); st = st->lexNext())
{
if (st->variant() == ENTRY_STAT)
functions.push_back(st);
}
}
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 funcName = "";
if (function->variant() == PROG_HEDR)
{
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 (function->variant() == PROC_HEDR)
{
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 (function->variant() == FUNC_HEDR)
{
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__);
set<SgStatement*> activeOps;
if (fullIR.size())
{
if (tmpInfoInIR.count(function) == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
activeOps = fillActiveOperators(fullIR[tmpInfoInIR[function]]);
activeOps.insert(function);
if (isEntry)
activeOps.insert(function->controlParent());
}
analyzeFunction(funcName, containsPrefix, isEntry ? function->controlParent() : function, function, allFuncInfo, mapLoopGraph, messagesForFile, containsFunctions, activeOps);
} }
//fill INTERFACE block from modules //fill INTERFACE block from modules
@@ -1275,6 +1371,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)

View File

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

View File

@@ -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,40 @@ 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->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 +695,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);

View File

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

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

View File

@@ -2776,7 +2776,7 @@ static void findArrayRefs(SgExpression *ex, SgStatement *st, string fName, int p
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())));

View File

@@ -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)
@@ -1293,30 +1295,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)
{ {
@@ -2605,8 +2583,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;

View File

@@ -1553,7 +1553,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)

View File

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