Compare commits
15 Commits
d3d546d19a
...
ce980dc387
| Author | SHA1 | Date | |
|---|---|---|---|
| ce980dc387 | |||
| 99d774a601 | |||
| e8ecc8491d | |||
|
|
e7990bda0a | ||
|
|
a49f10cb5b | ||
| 636f2b0af1 | |||
|
|
640e34816f | ||
|
|
b88eccaad4 | ||
|
|
7b0cb828a7 | ||
|
|
06980ee344 | ||
|
|
cde49042ae | ||
|
|
dae0afef45 | ||
|
|
41b4649d83 | ||
|
|
b068a49b0b | ||
|
|
5acbd10a26 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
|||||||
[submodule "projects/dvm"]
|
[submodule "projects/dvm"]
|
||||||
path = projects/dvm
|
path = projects/dvm
|
||||||
url = https://dvmguest:dvmguest@dvm.keldysh.ru/dvm-system/dvm
|
url = https://dvmguest:dvmguest@dvm.keldysh.ru/dvm-system/dvm
|
||||||
|
[submodule "projects/libpredictor"]
|
||||||
|
path = projects/libpredictor
|
||||||
|
url = https://dvmguest:dvmguest@dvm.keldysh.ru/sapfor/dvm-perfm
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ set(sagepp_sources projects/dvm/fdvmh/lib/sage/sage++/)
|
|||||||
set(parser_sources projects/dvm/fdvmh/tools/parser/)
|
set(parser_sources projects/dvm/fdvmh/tools/parser/)
|
||||||
set(pppa_sources projects/dvm/pppa/src/)
|
set(pppa_sources projects/dvm/pppa/src/)
|
||||||
set(zlib_sources projects/dvm/third-party/Zlib/)
|
set(zlib_sources projects/dvm/third-party/Zlib/)
|
||||||
|
set(libpred_sources projects/libpredictor/src/)
|
||||||
|
set(libpred_include projects/libpredictor/include/)
|
||||||
|
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
#Sage lib includes
|
#Sage lib includes
|
||||||
@@ -33,6 +35,8 @@ include_directories(${sage_include_2})
|
|||||||
include_directories(${zlib_sources}/include)
|
include_directories(${zlib_sources}/include)
|
||||||
#PPPA includes
|
#PPPA includes
|
||||||
include_directories(${pppa_sources})
|
include_directories(${pppa_sources})
|
||||||
|
#Libpredictor includes
|
||||||
|
include_directories(${libpred_include})
|
||||||
|
|
||||||
set(PR_PARAM src/ProjectParameters/projectParameters.cpp
|
set(PR_PARAM src/ProjectParameters/projectParameters.cpp
|
||||||
src/ProjectParameters/projectParameters.h)
|
src/ProjectParameters/projectParameters.h)
|
||||||
@@ -109,7 +113,9 @@ set(OMEGA src/SageAnalysisTool/OmegaForSage/add-assert.cpp
|
|||||||
src/SageAnalysisTool/set.cpp)
|
src/SageAnalysisTool/set.cpp)
|
||||||
|
|
||||||
set(PRIV src/PrivateAnalyzer/private_analyzer.cpp
|
set(PRIV src/PrivateAnalyzer/private_analyzer.cpp
|
||||||
src/PrivateAnalyzer/private_analyzer.h)
|
src/PrivateAnalyzer/private_analyzer.h
|
||||||
|
src/PrivateAnalyzer/private_arrays_search.cpp
|
||||||
|
src/PrivateAnalyzer/private_arrays_search.h)
|
||||||
|
|
||||||
set(FDVM ${fdvm_sources}/acc.cpp
|
set(FDVM ${fdvm_sources}/acc.cpp
|
||||||
${fdvm_sources}/acc_across.cpp
|
${fdvm_sources}/acc_across.cpp
|
||||||
@@ -313,6 +319,15 @@ set(MAIN src/Sapfor.cpp
|
|||||||
set(PREDICTOR src/Predictor/PredictScheme.cpp
|
set(PREDICTOR src/Predictor/PredictScheme.cpp
|
||||||
src/Predictor/PredictScheme.h)
|
src/Predictor/PredictScheme.h)
|
||||||
|
|
||||||
|
set(LIBPREDICTOR ${libpred_sources}/cluster.cpp
|
||||||
|
${libpred_sources}/predictor.cpp
|
||||||
|
${libpred_sources}/transfer.cpp
|
||||||
|
${libpred_sources}/utils.cpp
|
||||||
|
${libpred_include}/libpredict/predictor.h
|
||||||
|
${libpred_include}/internal/cluster.h
|
||||||
|
${libpred_include}/internal/transfer.h
|
||||||
|
${libpred_include}/internal/utils.h)
|
||||||
|
|
||||||
set(PROJ_MAN src/ProjectManipulation/ParseFiles.cpp
|
set(PROJ_MAN src/ProjectManipulation/ParseFiles.cpp
|
||||||
src/ProjectManipulation/ParseFiles.h
|
src/ProjectManipulation/ParseFiles.h
|
||||||
src/ProjectManipulation/StdCapture.h
|
src/ProjectManipulation/StdCapture.h
|
||||||
@@ -401,6 +416,7 @@ set(SOURCE_EXE
|
|||||||
${VS_CALLS}
|
${VS_CALLS}
|
||||||
${MAIN}
|
${MAIN}
|
||||||
${PREDICTOR}
|
${PREDICTOR}
|
||||||
|
${LIBPREDICTOR}
|
||||||
${PARSER}
|
${PARSER}
|
||||||
${PPPA}
|
${PPPA}
|
||||||
${ZLIB}
|
${ZLIB}
|
||||||
@@ -455,7 +471,8 @@ source_group (VisualizerCalls FILES ${VS_CALLS})
|
|||||||
source_group (VisualizerCalls\\GraphLayout FILES ${GR_LAYOUT})
|
source_group (VisualizerCalls\\GraphLayout FILES ${GR_LAYOUT})
|
||||||
|
|
||||||
source_group (_SapforMain FILES ${MAIN})
|
source_group (_SapforMain FILES ${MAIN})
|
||||||
source_group (Predictor FILES ${PREDICTOR})
|
source_group (Predictor\\Analyzer FILES ${PREDICTOR})
|
||||||
|
source_group (Predictor\\Library FILES ${LIBPREDICTOR})
|
||||||
source_group (Parser FILES ${PARSER})
|
source_group (Parser FILES ${PARSER})
|
||||||
source_group (PPPA\\PPPA FILES ${PPPA})
|
source_group (PPPA\\PPPA FILES ${PPPA})
|
||||||
source_group (PPPA\\ZLib FILES ${ZLIB})
|
source_group (PPPA\\ZLib FILES ${ZLIB})
|
||||||
|
|||||||
1
projects/libpredictor
Submodule
1
projects/libpredictor
Submodule
Submodule projects/libpredictor added at 840f9d9c1a
@@ -18,6 +18,7 @@
|
|||||||
#include "../GraphLoop/graph_loops_func.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 "../Utils/json.hpp"
|
||||||
#include "../ParallelizationRegions/ParRegions_func.h"
|
#include "../ParallelizationRegions/ParRegions_func.h"
|
||||||
#include "../DynamicAnalysis/gCov_parser_func.h"
|
#include "../DynamicAnalysis/gCov_parser_func.h"
|
||||||
#include "../ExpressionTransform/expr_transform.h"
|
#include "../ExpressionTransform/expr_transform.h"
|
||||||
@@ -37,6 +38,8 @@ using std::cout;
|
|||||||
using std::endl;
|
using std::endl;
|
||||||
using std::stack;
|
using std::stack;
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
//TODO: improve parameter checking
|
//TODO: improve parameter checking
|
||||||
@@ -2592,4 +2595,71 @@ void setInlineAttributeToCalls(const map<string, FuncInfo*>& allFunctions,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static json convertToJson(const FuncInfo* currFunc) {
|
||||||
|
json func;
|
||||||
|
|
||||||
|
if (currFunc)
|
||||||
|
{
|
||||||
|
func["funcName"] = currFunc->funcName;
|
||||||
|
func["line"] = currFunc->linesNum.first;
|
||||||
|
func["lineEnd"] = currFunc->linesNum.second;
|
||||||
|
func["isMain"] = (int)currFunc->isMain;
|
||||||
|
func["needToInline"] = (int)currFunc->needToInline;
|
||||||
|
func["doNotInline"] = (int)currFunc->doNotInline;
|
||||||
|
func["doNotAnalyze"] = (int)currFunc->doNotAnalyze;
|
||||||
|
|
||||||
|
json func_pars = json::array();
|
||||||
|
|
||||||
|
for (int z = 0; z < currFunc->funcParams.countOfPars; ++z)
|
||||||
|
{
|
||||||
|
json par;
|
||||||
|
par["inoutType"] = currFunc->funcParams.inout_types[z];
|
||||||
|
par["identificator"] = currFunc->funcParams.identificators[z];
|
||||||
|
par["parameterT"] = string(paramNames[currFunc->funcParams.parametersT[z]]);
|
||||||
|
|
||||||
|
func_pars.push_back(par);
|
||||||
|
}
|
||||||
|
|
||||||
|
func["params"] = func_pars;
|
||||||
|
|
||||||
|
json calls_from = json::array();
|
||||||
|
for (const auto& call_from : currFunc->callsFromDetailed)
|
||||||
|
{
|
||||||
|
json call;
|
||||||
|
call["line"] = call_from.detailCallsFrom.second;
|
||||||
|
call["funcName"] = call_from.detailCallsFrom.first;
|
||||||
|
|
||||||
|
calls_from.push_back(call);
|
||||||
|
}
|
||||||
|
func["callsFrom"] = calls_from;
|
||||||
|
}
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
json convertToJson(const map<string, vector<FuncInfo*>>& funcsByFileMap) {
|
||||||
|
json loopsByFile = json::array();
|
||||||
|
|
||||||
|
for (auto& byFile : funcsByFileMap)
|
||||||
|
{
|
||||||
|
json func;
|
||||||
|
const string& file = byFile.first;
|
||||||
|
|
||||||
|
json func_array = json::array();
|
||||||
|
for (auto& func : byFile.second)
|
||||||
|
{
|
||||||
|
auto conv = convertToJson(func);
|
||||||
|
if (!conv.empty())
|
||||||
|
func_array.push_back(conv);
|
||||||
|
}
|
||||||
|
|
||||||
|
func["file"] = file;
|
||||||
|
func["functions"] = func_array;
|
||||||
|
|
||||||
|
loopsByFile.push_back(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
json allFuncs;
|
||||||
|
allFuncs["allFunctions"] = loopsByFile;
|
||||||
|
return allFuncs;
|
||||||
|
}
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|||||||
@@ -378,33 +378,6 @@ FuncInfo* isUserFunctionInProject(const string &func)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
string convertToString(const FuncInfo *currFunc)
|
|
||||||
{
|
|
||||||
string result = "";
|
|
||||||
if (currFunc)
|
|
||||||
{
|
|
||||||
result += "|" + currFunc->funcName + "|" + to_string(currFunc->linesNum.first) +
|
|
||||||
"#" + to_string(currFunc->linesNum.second) +
|
|
||||||
"#" + to_string(currFunc->callsFromDetailed.size()) +
|
|
||||||
"#" + to_string(currFunc->needToInline) + "#" + to_string(currFunc->doNotInline) +
|
|
||||||
"#" + to_string(currFunc->doNotAnalyze) + "#" + to_string((int)currFunc->isMain);
|
|
||||||
|
|
||||||
result += "#" + to_string(currFunc->funcParams.countOfPars);
|
|
||||||
if (currFunc->funcParams.countOfPars)
|
|
||||||
{
|
|
||||||
for (int z = 0; z < currFunc->funcParams.countOfPars; ++z)
|
|
||||||
{
|
|
||||||
result += "#" + currFunc->funcParams.identificators[z] + "#" + to_string(currFunc->funcParams.inout_types[z]);
|
|
||||||
result += "#" + string(paramNames[currFunc->funcParams.parametersT[z]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < currFunc->callsFromDetailed.size(); ++i)
|
|
||||||
result += "|" + currFunc->callsFromDetailed[i].detailCallsFrom.first + "|" + to_string(currFunc->callsFromDetailed[i].detailCallsFrom.second);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find dead functions and fill callTo / callFrom information
|
// Find dead functions and fill callTo / callFrom information
|
||||||
void findDeadFunctionsAndFillCalls(map<string, vector<FuncInfo*>> &allFuncInfo, map<string, vector<Messages>> &allMessages, bool noPrint)
|
void findDeadFunctionsAndFillCalls(map<string, vector<FuncInfo*>> &allFuncInfo, map<string, vector<Messages>> &allMessages, bool noPrint)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "graph_calls.h"
|
#include "graph_calls.h"
|
||||||
#include "../GraphLoop/graph_loops.h"
|
#include "../GraphLoop/graph_loops.h"
|
||||||
#include "../ParallelizationRegions/ParRegions.h"
|
#include "../ParallelizationRegions/ParRegions.h"
|
||||||
|
#include "Utils/json.hpp"
|
||||||
|
|
||||||
namespace Distribution
|
namespace Distribution
|
||||||
{
|
{
|
||||||
@@ -23,7 +24,6 @@ int CreateCallGraphViz(const char *fileName, const std::map<std::string, std::ve
|
|||||||
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);
|
||||||
FuncInfo* isUserFunctionInProject(const std::string &func);
|
FuncInfo* isUserFunctionInProject(const std::string &func);
|
||||||
std::string convertToString(const FuncInfo *currFunc);
|
|
||||||
void findDeadFunctionsAndFillCalls(std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, std::map<std::string, std::vector<Messages>> &allMessages, bool noPrint = false);
|
void findDeadFunctionsAndFillCalls(std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, std::map<std::string, std::vector<Messages>> &allMessages, bool noPrint = false);
|
||||||
void createLinksBetweenFormalAndActualParams(std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls,
|
void createLinksBetweenFormalAndActualParams(std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, 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,
|
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays,
|
||||||
@@ -53,5 +53,6 @@ void findContainsFunctions(SgStatement *st, std::vector<SgStatement*> &found, co
|
|||||||
void correctNameIfContains(SgStatement* call, SgExpression* exCall, std::string& name, const std::vector<SgStatement*>& containsFunctions, const std::string& prefix);
|
void correctNameIfContains(SgStatement* call, SgExpression* exCall, std::string& name, const std::vector<SgStatement*>& containsFunctions, const std::string& prefix);
|
||||||
int countPerfectLoopNest(SgStatement* st);
|
int countPerfectLoopNest(SgStatement* st);
|
||||||
void setInlineAttributeToCalls(const std::map<std::string, FuncInfo*>& allFunctions, const std::map<std::string, std::set<std::pair<std::string, int>>>& inDataChains, const std::map<std::string, std::vector<SgStatement*>>& hiddenData);
|
void setInlineAttributeToCalls(const std::map<std::string, FuncInfo*>& allFunctions, const std::map<std::string, std::set<std::pair<std::string, int>>>& inDataChains, const std::map<std::string, std::vector<SgStatement*>>& hiddenData);
|
||||||
|
nlohmann::json convertToJson(const std::map<std::string, std::vector<FuncInfo*>>& funcsByFile);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -940,28 +940,13 @@ static int getLoopState(const LoopGraph* currLoop)
|
|||||||
return loopState;
|
return loopState;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printToBuffer(const LoopGraph *currLoop, const int childSize, char buf[512])
|
|
||||||
{
|
|
||||||
sprintf(buf, "#%d#%d#%d#%d#%d#%d#%d#%d",
|
|
||||||
currLoop->lineNum, currLoop->lineNumAfterLoop, currLoop->perfectLoop, currLoop->hasGoto, currLoop->hasPrints, childSize, getLoopState(currLoop),
|
|
||||||
currLoop->hasNonRectangularBounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int calculateNormalChildSize(const LoopGraph *currLoop)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
for (auto &elem : currLoop->children)
|
|
||||||
count += (elem->lineNum > 0) ? 1 : 0;
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static json convertToJson(const LoopGraph* currLoop)
|
static json convertToJson(const LoopGraph* currLoop)
|
||||||
{
|
{
|
||||||
json loop;
|
json loop;
|
||||||
const auto& file = currLoop->fileName;
|
|
||||||
if (currLoop && currLoop->lineNum > 0)
|
if (currLoop && currLoop->lineNum > 0)
|
||||||
{
|
{
|
||||||
loop["file"] = file;
|
loop["file"] = currLoop->fileName;
|
||||||
loop["line"] = currLoop->lineNum;
|
loop["line"] = currLoop->lineNum;
|
||||||
loop["lineNumAfterLoop"] = currLoop->lineNumAfterLoop;
|
loop["lineNumAfterLoop"] = currLoop->lineNumAfterLoop;
|
||||||
loop["perfectLoop"] = currLoop->perfectLoop;
|
loop["perfectLoop"] = currLoop->perfectLoop;
|
||||||
@@ -974,8 +959,6 @@ static json convertToJson(const LoopGraph* currLoop)
|
|||||||
json call;
|
json call;
|
||||||
call["line"] = line;
|
call["line"] = line;
|
||||||
call["funcName"] = func;
|
call["funcName"] = func;
|
||||||
call["canBeInlined"] = 0;
|
|
||||||
call["parentLineOffset"] = 0;
|
|
||||||
|
|
||||||
calls.push_back(call);
|
calls.push_back(call);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
|
|
||||||
#include "dvm.h"
|
#include "dvm.h"
|
||||||
#include "../DynamicAnalysis/gcov_info.h"
|
#include "../DynamicAnalysis/gcov_info.h"
|
||||||
|
#include "../DynamicAnalysis/gCov_parser_func.h"
|
||||||
#include "PredictScheme.h"
|
#include "PredictScheme.h"
|
||||||
#include "../Utils/SgUtils.h"
|
#include "../Utils/SgUtils.h"
|
||||||
#include "../DirectiveProcessing/directive_parser.h"
|
#include "../DirectiveProcessing/directive_parser.h"
|
||||||
#include "../Distribution/DvmhDirective.h"
|
#include "../Distribution/DvmhDirective.h"
|
||||||
#include "../GraphLoop/graph_loops_func.h"
|
#include "../GraphLoop/graph_loops_func.h"
|
||||||
#include "../ExpressionTransform/expr_transform.h"
|
#include "../ExpressionTransform/expr_transform.h"
|
||||||
#include "../DirectiveProcessing/directive_parser.h"
|
|
||||||
#include "../LoopAnalyzer/loop_analyzer.h"
|
#include "../LoopAnalyzer/loop_analyzer.h"
|
||||||
#include "../CFGraph/CFGraph.h"
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
|
||||||
@@ -215,6 +215,8 @@ void calculateStatsForPredictor(const map<string, vector<FuncInfo*>>& allFuncInf
|
|||||||
if (loop->variant() != FOR_NODE)
|
if (loop->variant() != FOR_NODE)
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
|
if (__gcov_doesThisLineExecuted(byFile.first, loop->lineNumber()))
|
||||||
|
{
|
||||||
calculateForParallelLoop(loop, gcov, paralle_exec, lines_count);
|
calculateForParallelLoop(loop, gcov, paralle_exec, lines_count);
|
||||||
st = loop->lastNodeOfStmt();
|
st = loop->lastNodeOfStmt();
|
||||||
|
|
||||||
@@ -225,10 +227,12 @@ void calculateStatsForPredictor(const map<string, vector<FuncInfo*>>& allFuncInf
|
|||||||
loop->lineNumber(), byFile.first.c_str(), paralle_exec, lines_count, paralle_exec / (double)lines_count);
|
loop->lineNumber(), byFile.first.c_str(), paralle_exec, lines_count, paralle_exec / (double)lines_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto st = stat->lexNext(); st != stat->lastNodeOfStmt(); st = st->lexNext())
|
for (auto st = stat->lexNext(); st != stat->lastNodeOfStmt(); st = st->lexNext())
|
||||||
{
|
{
|
||||||
if (!isSgExecutableStatement(st) || isDVM_stat(st) || isSPF_stat(st))
|
if (!isSgExecutableStatement(st) || isDVM_stat(st) || isSPF_stat(st) ||
|
||||||
|
!__gcov_doesThisLineExecuted(byFile.first, st->lineNumber()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int line = st->lineNumber();
|
int line = st->lineNumber();
|
||||||
@@ -428,6 +432,7 @@ static void parallelDir(const map<DIST::Array*, int>& byPos, SgExpression* spec,
|
|||||||
parallel["loops_count"] = loopSymbs.size();
|
parallel["loops_count"] = loopSymbs.size();
|
||||||
|
|
||||||
SgStatement* loop = isSgForStmt(st->lexNext());
|
SgStatement* loop = isSgForStmt(st->lexNext());
|
||||||
|
|
||||||
if (loop == NULL)
|
if (loop == NULL)
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
SgStatement* lastNode = loop->lastNodeOfStmt();
|
SgStatement* lastNode = loop->lastNodeOfStmt();
|
||||||
@@ -445,9 +450,11 @@ static void parallelDir(const map<DIST::Array*, int>& byPos, SgExpression* spec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int z = execs.size() - 1; z > 0; --z)
|
for (int z = execs.size() - 1; z > 0; --z)
|
||||||
|
if (execs[z - 1] != 0)
|
||||||
execs[z] /= execs[z - 1];
|
execs[z] /= execs[z - 1];
|
||||||
|
|
||||||
auto& info = getInfo(before, gcov);
|
auto& info = getInfo(before, gcov);
|
||||||
|
if (info.getExecutedCount() && loopSymbs.size() > 1)
|
||||||
execs[0] /= info.getExecutedCount();
|
execs[0] /= info.getExecutedCount();
|
||||||
|
|
||||||
parallel["iterations_count"] = execs;
|
parallel["iterations_count"] = execs;
|
||||||
@@ -501,8 +508,6 @@ static void parallelDir(const map<DIST::Array*, int>& byPos, SgExpression* spec,
|
|||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, true, false, false, true), commonBlocks, allFuncInfo);
|
auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, true, false, false, true), commonBlocks, allFuncInfo);
|
||||||
if (cfg.size() != 1)
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
//TODO IP analysis
|
//TODO IP analysis
|
||||||
|
|
||||||
unsigned countOfAccess = 0;
|
unsigned countOfAccess = 0;
|
||||||
@@ -589,6 +594,9 @@ void parseDvmDirForPredictor(const map<tuple<int, string, string>, pair<DIST::Ar
|
|||||||
|
|
||||||
for (auto st = stat->lexNext(); st != stat->lastNodeOfStmt(); st = st->lexNext())
|
for (auto st = stat->lexNext(); st != stat->lastNodeOfStmt(); st = st->lexNext())
|
||||||
{
|
{
|
||||||
|
if (!__gcov_doesThisLineExecuted(byFile.first, st->lineNumber()))
|
||||||
|
continue;
|
||||||
|
|
||||||
SgExpression* list;
|
SgExpression* list;
|
||||||
SgExpression* dup;
|
SgExpression* dup;
|
||||||
auto line = 0;
|
auto line = 0;
|
||||||
@@ -596,7 +604,10 @@ void parseDvmDirForPredictor(const map<tuple<int, string, string>, pair<DIST::Ar
|
|||||||
switch (st->variant())
|
switch (st->variant())
|
||||||
{
|
{
|
||||||
case DVM_PARALLEL_ON_DIR:
|
case DVM_PARALLEL_ON_DIR:
|
||||||
parallelDir(byPos, st->expr(2), st->expr(0)->symbol(), st->expr(0)->lhs(), st, st->expr(1), gcov, directives, commonBlocks, allFuncInfo);
|
parallelDir(byPos, st->expr(2),
|
||||||
|
st->expr(0) ? st->expr(0)->symbol() : NULL,
|
||||||
|
st->expr(0) ? st->expr(0)->lhs() : NULL,
|
||||||
|
st, st->expr(1), gcov, directives, commonBlocks, allFuncInfo);
|
||||||
break;
|
break;
|
||||||
case DVM_VAR_DECL: // TODO
|
case DVM_VAR_DECL: // TODO
|
||||||
{
|
{
|
||||||
@@ -615,6 +626,7 @@ void parseDvmDirForPredictor(const map<tuple<int, string, string>, pair<DIST::Ar
|
|||||||
list = st->expr(0);
|
list = st->expr(0);
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
|
if (type->lhs()) // if ALIGN A(...) with B(...)
|
||||||
directives["align"].push_back(parseAlign(byPos, list->lhs()->symbol(), type->rhs()->symbol(), type->lhs(), type->rhs()->lhs(), st->lineNumber()));
|
directives["align"].push_back(parseAlign(byPos, list->lhs()->symbol(), type->rhs()->symbol(), type->lhs(), type->rhs()->lhs(), st->lineNumber()));
|
||||||
list = list->rhs();
|
list = list->rhs();
|
||||||
}
|
}
|
||||||
@@ -627,6 +639,9 @@ void parseDvmDirForPredictor(const map<tuple<int, string, string>, pair<DIST::Ar
|
|||||||
case DVM_ALIGN_DIR:
|
case DVM_ALIGN_DIR:
|
||||||
directives["align"].push_back(parseAlign(byPos, st->expr(0)->lhs()->symbol(), st->expr(2)->symbol(), st->expr(1), st->expr(2)->lhs(), st->lineNumber()));
|
directives["align"].push_back(parseAlign(byPos, st->expr(0)->lhs()->symbol(), st->expr(2)->symbol(), st->expr(1), st->expr(2)->lhs(), st->lineNumber()));
|
||||||
break;
|
break;
|
||||||
|
case DVM_REALIGN_DIR:
|
||||||
|
directives["realign"].push_back(parseAlign(byPos, st->expr(0)->lhs()->symbol(), st->expr(2)->symbol(), st->expr(1), st->expr(2)->lhs(), st->lineNumber()));
|
||||||
|
break;
|
||||||
case DVM_SHADOW_DIR:
|
case DVM_SHADOW_DIR:
|
||||||
//dirs << "1;" << "SHADOW;" << st->expr(0)->unparse() << "(" << st->expr(1)->unparse() << ");\n";
|
//dirs << "1;" << "SHADOW;" << st->expr(0)->unparse() << "(" << st->expr(1)->unparse() << ");\n";
|
||||||
break;
|
break;
|
||||||
|
|||||||
714
src/PrivateAnalyzer/private_arrays_search.cpp
Normal file
714
src/PrivateAnalyzer/private_arrays_search.cpp
Normal file
@@ -0,0 +1,714 @@
|
|||||||
|
#include <map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
#include <numeric>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "private_arrays_search.h"
|
||||||
|
#include "../Utils/SgUtils.h"
|
||||||
|
#include "../GraphLoop/graph_loops.h"
|
||||||
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void print_info(LoopGraph* loop)
|
||||||
|
{
|
||||||
|
cout << "loopSymbol: " << loop->loopSymbol << endl;
|
||||||
|
for (const auto& ops : loop->writeOpsForLoop)
|
||||||
|
{
|
||||||
|
cout << "Array name: " << ops.first->GetShortName() << endl;
|
||||||
|
for (const auto i : ops.second)
|
||||||
|
{
|
||||||
|
i.printInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!loop->children.empty())
|
||||||
|
{
|
||||||
|
for (const auto child : loop->children)
|
||||||
|
{
|
||||||
|
print_info(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isParentStmt(SgStatement* stmt, SgStatement* parent)
|
||||||
|
{
|
||||||
|
for (; stmt; stmt = stmt->controlParent())
|
||||||
|
if (stmt == parent)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*returns head block and loop*/
|
||||||
|
pair<SAPFOR::BasicBlock*, unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(LoopGraph* loop, vector<SAPFOR::BasicBlock*> blocks)
|
||||||
|
{
|
||||||
|
unordered_set<SAPFOR::BasicBlock*> block_loop;
|
||||||
|
SAPFOR::BasicBlock* head_block = nullptr;
|
||||||
|
auto loop_operator = loop->loop->GetOriginal();
|
||||||
|
for (const auto& block : blocks)
|
||||||
|
{
|
||||||
|
if (!block || (block->getInstructions().size() == 0))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SgStatement* first = block->getInstructions().front()->getInstruction()->getOperator();
|
||||||
|
SgStatement* last = block->getInstructions().back()->getInstruction()->getOperator();
|
||||||
|
if (isParentStmt(first, loop_operator) && isParentStmt(last, loop_operator))
|
||||||
|
{
|
||||||
|
block_loop.insert(block);
|
||||||
|
|
||||||
|
if ((!head_block) && (first == loop_operator) && (last == loop_operator) &&
|
||||||
|
(block->getInstructions().size() == 2) &&
|
||||||
|
(block->getInstructions().back()->getInstruction()->getOperation() == SAPFOR::CFG_OP::JUMP_IF))
|
||||||
|
{
|
||||||
|
head_block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { head_block, block_loop };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void BuildLoopIndex(map<string, LoopGraph*>& loopForIndex, LoopGraph* loop) {
|
||||||
|
string index = loop->loopSymbol;
|
||||||
|
loopForIndex[index] = loop;
|
||||||
|
for (const auto& childLoop : loop->children) {
|
||||||
|
BuildLoopIndex(loopForIndex, childLoop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, LoopGraph*>& loopForIndex) {
|
||||||
|
unordered_set<SAPFOR::Argument*> args = {block->getInstructions()[pos]->getInstruction()->getArg1()};
|
||||||
|
|
||||||
|
for (int i = pos-1; i >= 0; i--) {
|
||||||
|
SAPFOR::Argument* res = block->getInstructions()[i]->getInstruction()->getResult();
|
||||||
|
if (res && args.find(res) != args.end()) {
|
||||||
|
SAPFOR::Argument* arg1 = block->getInstructions()[i]->getInstruction()->getArg1();
|
||||||
|
SAPFOR::Argument* arg2 = block->getInstructions()[i]->getInstruction()->getArg2();
|
||||||
|
if (arg1) {
|
||||||
|
string name = arg1->getValue();
|
||||||
|
int idx = name.find('%');
|
||||||
|
if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end())
|
||||||
|
return name.substr(idx + 1);
|
||||||
|
else {
|
||||||
|
args.insert(arg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (arg2) {
|
||||||
|
string name = arg2->getValue();
|
||||||
|
int idx = name.find('%');
|
||||||
|
if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end())
|
||||||
|
return name.substr(idx + 1);
|
||||||
|
else {
|
||||||
|
args.insert(arg2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use) {
|
||||||
|
auto instructions = block->getInstructions();
|
||||||
|
map<string, LoopGraph*> loopForIndex;
|
||||||
|
BuildLoopIndex(loopForIndex, loop);
|
||||||
|
for(int i = 0; i < instructions.size(); i++)
|
||||||
|
{
|
||||||
|
auto instruction = instructions[i];
|
||||||
|
if(!instruction->getInstruction()->getArg1()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto operation = instruction->getInstruction()->getOperation();
|
||||||
|
auto type = instruction->getInstruction()->getArg1()->getType();
|
||||||
|
if ((operation == SAPFOR::CFG_OP::STORE || operation == SAPFOR::CFG_OP::LOAD) && type == SAPFOR::CFG_ARG_TYPE::ARRAY)
|
||||||
|
{
|
||||||
|
vector<SAPFOR::Argument*> index_vars;
|
||||||
|
vector<int> refPos;
|
||||||
|
string array_name;
|
||||||
|
if (operation == SAPFOR::CFG_OP::STORE)
|
||||||
|
{
|
||||||
|
array_name = instruction->getInstruction()->getArg1()->getValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_name = instruction->getInstruction()->getArg2()->getValue();
|
||||||
|
}
|
||||||
|
int j = i - 1;
|
||||||
|
while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF)
|
||||||
|
{
|
||||||
|
index_vars.push_back(instructions[j]->getInstruction()->getArg1());
|
||||||
|
refPos.push_back(j);
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
/*to choose correct dimension*/
|
||||||
|
int n = index_vars.size();
|
||||||
|
vector<ArrayDimension> accessPoint(n);
|
||||||
|
/*if (operation == SAPFOR::CFG_OP::STORE)
|
||||||
|
{
|
||||||
|
if (def[array_name].empty())
|
||||||
|
{
|
||||||
|
def[array_name].resize(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (use[array_name].empty())
|
||||||
|
{
|
||||||
|
use[array_name].resize(n);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
SgArrayRefExp* ref = (SgArrayRefExp*)instruction->getInstruction()->getExpression();
|
||||||
|
vector<pair<int, int>> coefsForDims;
|
||||||
|
for (int i = 0; i < ref->numberOfSubscripts(); ++i)
|
||||||
|
{
|
||||||
|
const vector<int*>& coefs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
|
||||||
|
if (coefs.size() == 1)
|
||||||
|
{
|
||||||
|
const pair<int, int> coef(coefs[0][0], coefs[0][1]);
|
||||||
|
coefsForDims.push_back(coef);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!index_vars.empty())
|
||||||
|
{
|
||||||
|
auto var = index_vars.back();
|
||||||
|
int currentVarPos = refPos.back();
|
||||||
|
pair currentCoefs = coefsForDims.back();
|
||||||
|
ArrayDimension current_dim;
|
||||||
|
if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST) {
|
||||||
|
current_dim = { stoul(var->getValue()), 1, 1 };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string name, full_name = var->getValue();
|
||||||
|
int pos = full_name.find('%');
|
||||||
|
LoopGraph* currentLoop;
|
||||||
|
if (pos != -1) {
|
||||||
|
name = full_name.substr(pos+1);
|
||||||
|
if (loopForIndex.find(name) != loopForIndex.end()) {
|
||||||
|
currentLoop = loopForIndex[name];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = FindIndexName(currentVarPos, block, loopForIndex);
|
||||||
|
if (name == "") {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (loopForIndex.find(name) != loopForIndex.end()) {
|
||||||
|
currentLoop = loopForIndex[name];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint64_t start = currentLoop->startVal * currentCoefs.first + currentCoefs.second;
|
||||||
|
uint64_t step = currentCoefs.first;
|
||||||
|
current_dim = { start, step, (uint64_t)currentLoop->calculatedCountOfIters };
|
||||||
|
}
|
||||||
|
/*if (operation == SAPFOR::CFG_OP::STORE)
|
||||||
|
{
|
||||||
|
def[array_name][n - index_vars.size()].push_back(current_dim);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
use[array_name][n - index_vars.size()].push_back(current_dim);
|
||||||
|
}*/
|
||||||
|
accessPoint[n - index_vars.size()] = current_dim;
|
||||||
|
index_vars.pop_back();
|
||||||
|
refPos.pop_back();
|
||||||
|
coefsForDims.pop_back();
|
||||||
|
}
|
||||||
|
if (operation == SAPFOR::CFG_OP::STORE)
|
||||||
|
{
|
||||||
|
def[array_name].Insert(accessPoint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
use[array_name].Insert(accessPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<uint64_t> FindParticularSolution(const ArrayDimension& dim1, const ArrayDimension& dim2)
|
||||||
|
{
|
||||||
|
for (uint64_t i = 0; i < dim1.tripCount; i++)
|
||||||
|
{
|
||||||
|
uint64_t leftPart = dim1.start + i * dim1.step;
|
||||||
|
for (uint64_t j = 0; j < dim2.tripCount; j++)
|
||||||
|
{
|
||||||
|
uint64_t rightPart = dim2.start + j * dim2.step;
|
||||||
|
if (leftPart == rightPart)
|
||||||
|
{
|
||||||
|
return {i, j};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dim1 /\ dim2 */
|
||||||
|
static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const ArrayDimension& dim2)
|
||||||
|
{
|
||||||
|
vector<uint64_t> partSolution = FindParticularSolution(dim1, dim2);
|
||||||
|
if (partSolution.empty())
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int64_t x0 = partSolution[0], y0 = partSolution[1];
|
||||||
|
/* x = x_0 + c * t */
|
||||||
|
/* y = y_0 + d * t */
|
||||||
|
int64_t c = dim2.step / gcd(dim1.step, dim2.step);
|
||||||
|
int64_t d = dim1.step / gcd(dim1.step, dim2.step);
|
||||||
|
int64_t tXMin, tXMax, tYMin, tYMax;
|
||||||
|
tXMin = -x0 / c;
|
||||||
|
tXMax = (dim1.tripCount - 1 - x0) / c;
|
||||||
|
tYMin = -y0 / d;
|
||||||
|
tYMax = (dim2.tripCount - 1 - y0) / d;
|
||||||
|
int64_t tMin = max(tXMin, tYMin);
|
||||||
|
uint64_t tMax = min(tXMax, tYMax);
|
||||||
|
if (tMin > tMax)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
uint64_t start3 = dim1.start + x0 * dim1.step;
|
||||||
|
uint64_t step3 = c * dim1.step;
|
||||||
|
ArrayDimension* result = new(ArrayDimension){ start3, step3, tMax + 1 };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dim1 / dim2 */
|
||||||
|
static vector<ArrayDimension> DimensionDifference(const ArrayDimension& dim1, const ArrayDimension& dim2)
|
||||||
|
{
|
||||||
|
ArrayDimension* intersection = DimensionIntersection(dim1, dim2);
|
||||||
|
if (!intersection)
|
||||||
|
{
|
||||||
|
return {dim1};
|
||||||
|
}
|
||||||
|
vector<ArrayDimension> result;
|
||||||
|
/* add the part before intersection */
|
||||||
|
if (dim1.start < intersection->start)
|
||||||
|
{
|
||||||
|
result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step });
|
||||||
|
}
|
||||||
|
/* add the parts between intersection steps */
|
||||||
|
uint64_t start = (intersection->start - dim1.start) / dim1.step;
|
||||||
|
uint64_t interValue = intersection->start;
|
||||||
|
for (int64_t i = start; dim1.start + i * dim1.step <= intersection->start + intersection->step * (intersection->tripCount - 1); i++)
|
||||||
|
{
|
||||||
|
uint64_t centerValue = dim1.start + i * dim1.step;
|
||||||
|
if (centerValue == interValue)
|
||||||
|
{
|
||||||
|
if (i - start > 1)
|
||||||
|
{
|
||||||
|
result.push_back({ dim1.start + (start + 1) * dim1.step, dim1.step, i - start - 1 });
|
||||||
|
start = i;
|
||||||
|
}
|
||||||
|
interValue += intersection->step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* add the part after intersection */
|
||||||
|
if (intersection->start + intersection->step * (intersection->tripCount - 1) < dim1.start + dim1.step * (dim1.tripCount - 1))
|
||||||
|
{
|
||||||
|
/* first value after intersection */
|
||||||
|
uint64_t right_start = intersection->start + intersection->step * (intersection->tripCount - 1) + dim1.step;
|
||||||
|
uint64_t tripCount = (dim1.start + dim1.step * dim1.tripCount - right_start) / dim1.step;
|
||||||
|
result.push_back({right_start, dim1.step, tripCount});
|
||||||
|
}
|
||||||
|
delete(intersection);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static vector<ArrayDimension> DimensionUnion(const ArrayDimension& dim1, const ArrayDimension& dim2)
|
||||||
|
{
|
||||||
|
vector<ArrayDimension> res;
|
||||||
|
ArrayDimension* inter = DimensionIntersection(dim1, dim2);
|
||||||
|
if(!inter)
|
||||||
|
{
|
||||||
|
return { dim1, dim2 };
|
||||||
|
}
|
||||||
|
res.push_back(*inter);
|
||||||
|
delete(inter);
|
||||||
|
vector<ArrayDimension> diff1, diff2;
|
||||||
|
diff1 = DimensionDifference(dim1, dim2);
|
||||||
|
diff2 = DimensionDifference(dim2, dim1);
|
||||||
|
res.insert(res.end(), diff1.begin(), diff1.end());
|
||||||
|
res.insert(res.end(), diff2.begin(), diff2.end());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>& firstElement, const vector<ArrayDimension>& secondElement)
|
||||||
|
{
|
||||||
|
if(firstElement.empty() || secondElement.empty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
size_t dimAmount = firstElement.size();
|
||||||
|
/* check if there is no intersecction */
|
||||||
|
for(size_t i = 0; i < dimAmount; i++)
|
||||||
|
{
|
||||||
|
if(FindParticularSolution(firstElement[i], secondElement[i]).empty()){
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<ArrayDimension> result(dimAmount);
|
||||||
|
for(size_t i = 0; i < dimAmount; i++)
|
||||||
|
{
|
||||||
|
ArrayDimension* resPtr = DimensionIntersection(firstElement[i], secondElement[i]);
|
||||||
|
if(resPtr)
|
||||||
|
{
|
||||||
|
result[i] = *resPtr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<vector<ArrayDimension>> ElementsDifference(const vector<ArrayDimension>& firstElement,
|
||||||
|
const vector<ArrayDimension>& secondElement)
|
||||||
|
{
|
||||||
|
if(firstElement.empty() || secondElement.empty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
vector<ArrayDimension> intersection = ElementsIntersection(firstElement, secondElement);
|
||||||
|
vector<vector<ArrayDimension>> result;
|
||||||
|
if(intersection.empty())
|
||||||
|
{
|
||||||
|
return {firstElement};
|
||||||
|
}
|
||||||
|
for(int i = 0; i < firstElement.size(); i++)
|
||||||
|
{
|
||||||
|
auto dimDiff = DimensionDifference(firstElement[i], secondElement[i]);
|
||||||
|
if(!dimDiff.empty())
|
||||||
|
{
|
||||||
|
vector<ArrayDimension> firstCopy = firstElement;
|
||||||
|
for(const auto& range: dimDiff)
|
||||||
|
{
|
||||||
|
firstCopy[i] = range;
|
||||||
|
result.push_back(firstCopy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ElementsUnion(const vector<ArrayDimension>& firstElement, const vector<ArrayDimension>& secondElement,
|
||||||
|
vector<vector<ArrayDimension>>& lc, vector<vector<ArrayDimension>>& rc,
|
||||||
|
vector<ArrayDimension>& intersection)
|
||||||
|
{
|
||||||
|
/* lc(rc) is a set of ranges, which only exist in first(second) element*/
|
||||||
|
intersection = ElementsIntersection(firstElement, secondElement);
|
||||||
|
lc = ElementsDifference(firstElement, intersection);
|
||||||
|
rc = ElementsDifference(secondElement, intersection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessingSet::FindUncovered(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const{
|
||||||
|
vector<vector<ArrayDimension>> newTails;
|
||||||
|
result.push_back(element);
|
||||||
|
for(const auto& currentElement: allElements)
|
||||||
|
{
|
||||||
|
for(const auto& tailLoc: result)
|
||||||
|
{
|
||||||
|
auto intersection = ElementsIntersection(tailLoc, currentElement);
|
||||||
|
auto diff = ElementsDifference(tailLoc, intersection);
|
||||||
|
if(!diff.empty()) {
|
||||||
|
newTails.insert(newTails.end(), diff.begin(), diff.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = move(newTails);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AccessingSet::ContainsElement(const vector<ArrayDimension>& element) const
|
||||||
|
{
|
||||||
|
vector<vector<ArrayDimension>> tails;
|
||||||
|
FindUncovered(element, tails);
|
||||||
|
return !tails.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessingSet::FindCoveredBy(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const
|
||||||
|
{
|
||||||
|
for(const auto& currentElement: allElements)
|
||||||
|
{
|
||||||
|
auto intersection = ElementsIntersection(element, currentElement);
|
||||||
|
if(!intersection.empty()) {
|
||||||
|
result.push_back(intersection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<vector<ArrayDimension>> AccessingSet::GetElements() const
|
||||||
|
{
|
||||||
|
return allElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessingSet::Insert(const vector<ArrayDimension>& element)
|
||||||
|
{
|
||||||
|
vector<vector<ArrayDimension>> tails;
|
||||||
|
FindUncovered(element, tails);
|
||||||
|
allElements.insert(allElements.end(), tails.begin(), tails.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessingSet AccessingSet::Union(const AccessingSet& source) {
|
||||||
|
AccessingSet result;
|
||||||
|
for(auto& element: source.GetElements()) {
|
||||||
|
result.Insert(element);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessingSet AccessingSet::Intersect(const AccessingSet& secondSet) const
|
||||||
|
{
|
||||||
|
vector<vector<ArrayDimension>> result;
|
||||||
|
for(const auto& element: allElements)
|
||||||
|
{
|
||||||
|
if(secondSet.ContainsElement(element))
|
||||||
|
{
|
||||||
|
result.push_back(element);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vector<vector<ArrayDimension>> coveredBy;
|
||||||
|
secondSet.FindCoveredBy(element, coveredBy);
|
||||||
|
if(!coveredBy.empty())
|
||||||
|
{
|
||||||
|
result.insert(result.end(), coveredBy.begin(), coveredBy.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AccessingSet(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessingSet AccessingSet::Diff(const AccessingSet& secondSet) const
|
||||||
|
{
|
||||||
|
AccessingSet intersection = this->Intersect(secondSet);
|
||||||
|
AccessingSet uncovered = *this;
|
||||||
|
vector<vector<ArrayDimension>> result;
|
||||||
|
for (const auto& element : intersection.GetElements())
|
||||||
|
{
|
||||||
|
vector<vector<ArrayDimension>> current_uncovered;
|
||||||
|
uncovered.FindUncovered(element, current_uncovered);
|
||||||
|
uncovered = AccessingSet(current_uncovered);
|
||||||
|
}
|
||||||
|
return uncovered;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const ArrayDimension& lhs, const ArrayDimension& rhs)
|
||||||
|
{
|
||||||
|
return lhs.start == rhs.start && lhs.step == rhs.step && lhs.tripCount == rhs.tripCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator==(const AccessingSet& lhs, const AccessingSet& rhs)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < lhs.allElements.size(); i++)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < lhs.allElements[i].size(); j++)
|
||||||
|
{
|
||||||
|
if (lhs.allElements[i][j] != rhs.allElements[i][j])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collapse(Region* region)
|
||||||
|
{
|
||||||
|
//Region* newBlock = new Region();
|
||||||
|
for (auto& [arrayName, arrayRanges] : region->getHeader()->array_out)
|
||||||
|
{
|
||||||
|
for (Region* byBlock : region->getBasickBlocks())
|
||||||
|
{
|
||||||
|
AccessingSet intersection = byBlock->array_def[arrayName].Intersect(arrayRanges);
|
||||||
|
region->array_def[arrayName] = region->array_def[arrayName].Union(intersection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& byBlock : region->getBasickBlocks()) {
|
||||||
|
for (auto& [arrayName, arrayRanges] : byBlock->array_use)
|
||||||
|
{
|
||||||
|
AccessingSet diff = byBlock->array_use[arrayName].Diff(byBlock->array_in[arrayName]);
|
||||||
|
region->array_use[arrayName] = region->array_use[arrayName].Union(diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Region* prevBlock : region->getHeader()->getPrevRegions())
|
||||||
|
{
|
||||||
|
prevBlock->replaceInNextRegions(region, region->getHeader());
|
||||||
|
}
|
||||||
|
for (Region* nextBlock : region->getHeader()->getNextRegions())
|
||||||
|
{
|
||||||
|
nextBlock->replaceInPrevRegions(region, region->getHeader());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet)
|
||||||
|
{
|
||||||
|
for (SAPFOR::BasicBlock* block : blockSet)
|
||||||
|
{
|
||||||
|
for (SAPFOR::BasicBlock* nextBlock : block->getNext())
|
||||||
|
{
|
||||||
|
if (bbToRegion.find(nextBlock) != bbToRegion.end())
|
||||||
|
{
|
||||||
|
bbToRegion[block]->addNextRegion(bbToRegion[nextBlock]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (SAPFOR::BasicBlock* prevBlock : block->getPrev())
|
||||||
|
{
|
||||||
|
if (bbToRegion.find(prevBlock) != bbToRegion.end())
|
||||||
|
{
|
||||||
|
bbToRegion[block]->addPrevRegion(bbToRegion[prevBlock]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, const unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
|
||||||
|
{
|
||||||
|
Region* region = new Region;
|
||||||
|
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks);
|
||||||
|
for (SAPFOR::BasicBlock* block : Blocks)
|
||||||
|
{
|
||||||
|
region->addBasickBlocks(bbToRegion.at(block));
|
||||||
|
}
|
||||||
|
for (LoopGraph* childLoop : loop->children)
|
||||||
|
{
|
||||||
|
region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion));
|
||||||
|
}
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
Region::Region(LoopGraph* loop, vector<SAPFOR::BasicBlock*>& Blocks)
|
||||||
|
{
|
||||||
|
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks);
|
||||||
|
unordered_map<SAPFOR::BasicBlock*, Region*> bbToRegion;
|
||||||
|
for (auto poiner : blockSet)
|
||||||
|
{
|
||||||
|
bbToRegion[poiner] = new Region(*poiner);
|
||||||
|
}
|
||||||
|
this->header = bbToRegion[header];
|
||||||
|
SetConnections(bbToRegion, blockSet);
|
||||||
|
//create subRegions
|
||||||
|
for (LoopGraph* childLoop : loop->children)
|
||||||
|
{
|
||||||
|
subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolveDataFlowIteratively(Region* DFG)
|
||||||
|
{
|
||||||
|
unordered_set<Region*> worklist(DFG->getBasickBlocks());
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Region* b = *worklist.begin();
|
||||||
|
ArrayAccessingIndexes newIn;
|
||||||
|
for (Region* prevBlock : b->getPrevRegions())
|
||||||
|
{
|
||||||
|
for (const auto& [arrayName, accessSet] : prevBlock->array_out)
|
||||||
|
{
|
||||||
|
newIn[arrayName] = newIn[arrayName].Intersect(accessSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b->array_in = newIn;
|
||||||
|
ArrayAccessingIndexes newOut;
|
||||||
|
for (auto& [arrayName, accessSet] : b->array_in)
|
||||||
|
{
|
||||||
|
newOut[arrayName] = b->array_in[arrayName].Union(b->array_def[arrayName]);
|
||||||
|
}
|
||||||
|
/* can not differ */
|
||||||
|
if (newOut != b->array_out)
|
||||||
|
{
|
||||||
|
b->array_out = newOut;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
worklist.erase(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!worklist.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolveDataFlow(Region* DFG)
|
||||||
|
{
|
||||||
|
SolveDataFlowIteratively(DFG);
|
||||||
|
for (Region* subRegion : DFG->getSubRegions())
|
||||||
|
{
|
||||||
|
SolveDataFlow(subRegion);
|
||||||
|
}
|
||||||
|
Collapse(DFG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindPrivateArrays(map<string, vector<LoopGraph*>> &loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
|
||||||
|
{
|
||||||
|
for (const auto& curr_graph_pair: loopGraph)
|
||||||
|
{
|
||||||
|
for (const auto& curr_loop : curr_graph_pair.second)
|
||||||
|
{
|
||||||
|
auto block_loop = GetBasicBlocksForLoop(curr_loop, (*FullIR.begin()).second);
|
||||||
|
for (const auto& bb : block_loop.second) {
|
||||||
|
ArrayAccessingIndexes def, use;
|
||||||
|
//GetDefUseArray(bb, curr_loop, def, use);
|
||||||
|
}
|
||||||
|
ArrayAccessingIndexes loopDimensionsInfo;
|
||||||
|
//GetDimensionInfo(curr_loop, loopDimensionsInfo, 0);
|
||||||
|
//print_info(curr_loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetDimensionInfo(LoopGraph* loop, map<DIST::Array*, vector<vector<ArrayDimension>>>& loopDimensionsInfo, int level)
|
||||||
|
{
|
||||||
|
cout << "line_num: " << loop->lineNum << endl;
|
||||||
|
for (const auto& writeOpPairs : loop->writeOpsForLoop)
|
||||||
|
{
|
||||||
|
vector<vector<ArrayDimension>> arrayDimensions(writeOpPairs.first->GetDimSize());
|
||||||
|
loopDimensionsInfo[writeOpPairs.first] = arrayDimensions;
|
||||||
|
for (const auto& writeOp : writeOpPairs.second)
|
||||||
|
{
|
||||||
|
for (const auto& coeficient_pair : writeOp.coefficients)
|
||||||
|
{
|
||||||
|
uint64_t start, step, tripCount;
|
||||||
|
start = loop->startVal * coeficient_pair.first.first + coeficient_pair.first.second;
|
||||||
|
step = loop->stepVal * coeficient_pair.first.first;
|
||||||
|
tripCount = (loop->endVal - coeficient_pair.first.second) / step;
|
||||||
|
if (start <= loop->endVal)
|
||||||
|
{
|
||||||
|
loopDimensionsInfo[writeOpPairs.first][level].push_back({start, step, tripCount});
|
||||||
|
cout << "level: " << level << endl;
|
||||||
|
cout << "start: " << start << endl;
|
||||||
|
cout << "step: " << step << endl;
|
||||||
|
cout << "trip_count: " << tripCount << endl;
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << "line_num_after: " << loop->lineNumAfterLoop << endl;
|
||||||
|
if (!loop->children.empty())
|
||||||
|
{
|
||||||
|
for (const auto& childLoop : loop->children)
|
||||||
|
{
|
||||||
|
GetDimensionInfo(childLoop, loopDimensionsInfo, level+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
123
src/PrivateAnalyzer/private_arrays_search.h
Normal file
123
src/PrivateAnalyzer/private_arrays_search.h
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../GraphLoop/graph_loops.h"
|
||||||
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
using std::map;
|
||||||
|
using std::string;
|
||||||
|
using std::set;
|
||||||
|
using std::unordered_set;
|
||||||
|
using std::pair;
|
||||||
|
|
||||||
|
struct ArrayDimension
|
||||||
|
{
|
||||||
|
uint64_t start, step, tripCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AccessingSet {
|
||||||
|
private:
|
||||||
|
vector<vector<ArrayDimension>> allElements;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AccessingSet(vector<vector<ArrayDimension>> input) : allElements(input) {};
|
||||||
|
AccessingSet() {};
|
||||||
|
vector<vector<ArrayDimension>> GetElements() const;
|
||||||
|
void Insert(const vector<ArrayDimension>& element);
|
||||||
|
AccessingSet Union(const AccessingSet& source);
|
||||||
|
AccessingSet Intersect(const AccessingSet& secondSet) const;
|
||||||
|
AccessingSet Diff(const AccessingSet& secondSet) const;
|
||||||
|
bool ContainsElement(const vector<ArrayDimension>& element) const;
|
||||||
|
void FindCoveredBy(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const;
|
||||||
|
void FindUncovered(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const;
|
||||||
|
friend bool operator==(const AccessingSet& lhs, const AccessingSet& rhs);
|
||||||
|
};
|
||||||
|
|
||||||
|
using ArrayAccessingIndexes = map<string, AccessingSet>;
|
||||||
|
|
||||||
|
class Region: public SAPFOR::BasicBlock {
|
||||||
|
public:
|
||||||
|
Region()
|
||||||
|
{
|
||||||
|
header = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Region(SAPFOR::BasicBlock block) : SAPFOR::BasicBlock::BasicBlock(block)
|
||||||
|
{
|
||||||
|
header = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Region(LoopGraph* loop, vector<SAPFOR::BasicBlock*>& Blocks);
|
||||||
|
|
||||||
|
Region* getHeader()
|
||||||
|
{
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_set<Region*>& getBasickBlocks()
|
||||||
|
{
|
||||||
|
return basickBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addBasickBlocks(Region* region)
|
||||||
|
{
|
||||||
|
basickBlocks.insert(region);
|
||||||
|
}
|
||||||
|
unordered_set<Region*> getPrevRegions()
|
||||||
|
{
|
||||||
|
return prevRegions;
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_set<Region*> getNextRegions()
|
||||||
|
{
|
||||||
|
return nextRegions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPrevRegion(Region* region)
|
||||||
|
{
|
||||||
|
prevRegions.insert(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addNextRegion(Region* region)
|
||||||
|
{
|
||||||
|
nextRegions.insert(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
void replaceInPrevRegions(Region* source, Region* destination)
|
||||||
|
{
|
||||||
|
prevRegions.erase(destination);
|
||||||
|
prevRegions.insert(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void replaceInNextRegions(Region* source, Region* destination)
|
||||||
|
{
|
||||||
|
nextRegions.erase(destination);
|
||||||
|
nextRegions.insert(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_set<Region*> getSubRegions()
|
||||||
|
{
|
||||||
|
return subRegions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addSubRegions(Region* region)
|
||||||
|
{
|
||||||
|
subRegions.insert(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayAccessingIndexes array_def, array_use, array_out, array_in;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unordered_set<Region*> subRegions, basickBlocks;
|
||||||
|
/*next Region which is BB for current BB Region*/
|
||||||
|
unordered_set<Region*> nextRegions;
|
||||||
|
/*prev Regions which is BBs for current BB Region*/
|
||||||
|
unordered_set<Region*> prevRegions;
|
||||||
|
Region* header;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void Collapse(Region* region);
|
||||||
|
void FindPrivateArrays(map<string, vector<LoopGraph*>>& loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR);
|
||||||
|
void GetDimensionInfo(LoopGraph* loop, map<DIST::Array*, vector<vector<ArrayDimension>>>& loopDimensionsInfo, int level);
|
||||||
|
pair<SAPFOR::BasicBlock*, unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(LoopGraph* loop, vector<SAPFOR::BasicBlock*> blocks);
|
||||||
@@ -331,7 +331,7 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
|
|||||||
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile,
|
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile,
|
||||||
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, false, true);
|
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, false, true);
|
||||||
auto itI = filesToInclude.find(file_name);
|
auto itI = filesToInclude.find(file_name);
|
||||||
for (auto& incl : itI->second)
|
for (auto& [_, incl] : itI->second)
|
||||||
if (allIncludeFiles.find(incl) != allIncludeFiles.end())
|
if (allIncludeFiles.find(incl) != allIncludeFiles.end())
|
||||||
allIncludeFiles.erase(incl);
|
allIncludeFiles.erase(incl);
|
||||||
}
|
}
|
||||||
@@ -827,20 +827,27 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
{
|
{
|
||||||
auto fileIt = includeDependencies.find(file_name);
|
auto fileIt = includeDependencies.find(file_name);
|
||||||
if (fileIt == includeDependencies.end())
|
if (fileIt == includeDependencies.end())
|
||||||
fileIt = includeDependencies.insert(fileIt, make_pair(file_name, set<string>()));
|
fileIt = includeDependencies.insert(fileIt, make_pair(file_name, vector<pair<int, string>>()));
|
||||||
|
|
||||||
set<string> modFiles;
|
set<string> modFiles;
|
||||||
for (auto& elem : moduleDecls)
|
for (auto& elem : moduleDecls)
|
||||||
modFiles.insert(elem.second);
|
modFiles.insert(elem.second);
|
||||||
|
|
||||||
for (SgStatement *first = file->firstStatement(); first; first = first->lexNext())
|
SgStatement* lastFromFile = NULL;
|
||||||
|
for (SgStatement *st = file->firstStatement(); st; st = st->lexNext())
|
||||||
{
|
{
|
||||||
if (strcmp(file_name, first->fileName()))
|
if (st->variant() == MODULE_STMT && modFiles.find(st->fileName()) != modFiles.end())
|
||||||
{
|
st = st->lastNodeOfStmt();
|
||||||
if (first->variant() == MODULE_STMT && modFiles.find(first->fileName()) != modFiles.end())
|
|
||||||
first = first->lastNodeOfStmt();
|
|
||||||
else
|
else
|
||||||
fileIt->second.insert(first->fileName());
|
{
|
||||||
|
if (strcmp(file_name, st->fileName()))
|
||||||
|
{
|
||||||
|
if (lastFromFile == NULL)
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
fileIt->second.push_back(make_pair(lastFromFile->lineNumber(), st->fileName()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lastFromFile = st;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1596,9 +1603,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
set<string> includedToThisFile;
|
set<string> includedToThisFile;
|
||||||
if (itDep != includeDependencies.end())
|
if (itDep != includeDependencies.end())
|
||||||
{
|
{
|
||||||
for (auto &inclDep : itDep->second)
|
for (auto& [_, incl] : itDep->second)
|
||||||
{
|
{
|
||||||
auto comm = commentsToInclude.find(inclDep);
|
auto comm = commentsToInclude.find(incl);
|
||||||
if (comm != commentsToInclude.end())
|
if (comm != commentsToInclude.end())
|
||||||
for (auto &allComm : comm->second)
|
for (auto &allComm : comm->second)
|
||||||
includedToThisFile.insert(allComm.second.begin(), allComm.second.end());
|
includedToThisFile.insert(allComm.second.begin(), allComm.second.end());
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ std::map<std::string, std::map<int, std::set<std::string>>> commentsToInclude;
|
|||||||
//
|
//
|
||||||
|
|
||||||
//for INSERT_INCLUDES
|
//for INSERT_INCLUDES
|
||||||
std::map<std::string, std::set<std::string>> filesToInclude; // file -> includes
|
std::map<std::string, std::vector<std::pair<int, std::string>>> filesToInclude; // file -> includes [nearest line, include]
|
||||||
//
|
//
|
||||||
|
|
||||||
//for PASSES DEPENDENSIES
|
//for PASSES DEPENDENSIES
|
||||||
@@ -96,7 +96,7 @@ std::set<passes> passesIgnoreStateDone;
|
|||||||
//for files info
|
//for files info
|
||||||
std::map<std::string, int> lineInfo; // file -> lines count
|
std::map<std::string, int> lineInfo; // file -> lines count
|
||||||
std::map<std::string, std::pair<std::set<int>, std::set<int>>> dirsInfo; // file -> dirs <lines SPF, lines DVM> count
|
std::map<std::string, std::pair<std::set<int>, std::set<int>>> dirsInfo; // file -> dirs <lines SPF, lines DVM> count
|
||||||
std::map<std::string, std::set<std::string>> includeDependencies; // file -> includes
|
std::map<std::string, std::vector<std::pair<int, std::string>>> includeDependencies; // file -> includes [nearest line, include]
|
||||||
std::vector<std::string> filesCompilationOrder; // order of files for unite to one file
|
std::vector<std::string> filesCompilationOrder; // order of files for unite to one file
|
||||||
std::map<std::string, std::map<SgStatement*, std::vector<SgStatement*>>> exctactedModuleStats; // file -> hided excluded modules
|
std::map<std::string, std::map<SgStatement*, std::vector<SgStatement*>>> exctactedModuleStats; // file -> hided excluded modules
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -309,6 +309,8 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
|
|||||||
|
|
||||||
Pass(REMOVE_OMP_DIRS) <= Pass(REMOVE_OMP_DIRS_TRANSFORM);
|
Pass(REMOVE_OMP_DIRS) <= Pass(REMOVE_OMP_DIRS_TRANSFORM);
|
||||||
|
|
||||||
|
Pass(VERIFY_INCLUDES) <= Pass(RENAME_INLCUDES);
|
||||||
|
|
||||||
list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(REMOVE_DEAD_CODE);
|
list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(REMOVE_DEAD_CODE);
|
||||||
list({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);
|
list({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION_SPF "2404"
|
#define VERSION_SPF "2413"
|
||||||
|
|||||||
@@ -552,15 +552,7 @@ int SPF_GetGraphFunctions(void*& context, int winHandler, short *options, short
|
|||||||
{
|
{
|
||||||
runPassesForVisualizer(projName, { FILL_PAR_REGIONS_LINES } );
|
runPassesForVisualizer(projName, { FILL_PAR_REGIONS_LINES } );
|
||||||
|
|
||||||
string resVal = "";
|
string resVal = convertToJson(allFuncInfo).dump();
|
||||||
resVal = to_string(allFuncInfo.size());
|
|
||||||
for (auto f = allFuncInfo.begin(); f != allFuncInfo.end(); ++f)
|
|
||||||
{
|
|
||||||
resVal += "|" + f->first + "|" + to_string(f->second.size());
|
|
||||||
for (int i = 0; i < f->second.size(); ++i)
|
|
||||||
resVal += convertToString(f->second[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
copyStringToShort(result, resVal);
|
copyStringToShort(result, resVal);
|
||||||
retSize = (int)resVal.size() + 1;
|
retSize = (int)resVal.size() + 1;
|
||||||
}
|
}
|
||||||
@@ -650,11 +642,19 @@ int SPF_GetGraphFunctionPositions(void*& context, int winHandler, short *options
|
|||||||
|
|
||||||
auto positions = buildLocationOfGraph(allFuncInfo, iters, coef, 0.9 * w, 0.9 * h, sendVisible ? &visible : NULL);
|
auto positions = buildLocationOfGraph(allFuncInfo, iters, coef, 0.9 * w, 0.9 * h, sendVisible ? &visible : NULL);
|
||||||
|
|
||||||
string resVal = "";
|
json pos_array= json::array();
|
||||||
resVal = to_string(positions.size());
|
for (auto& [fname, coords] : positions) {
|
||||||
for (auto& elem : positions)
|
json elem;
|
||||||
resVal += "|" + elem.first + "|" + to_string(elem.second.first) + "|" + to_string(elem.second.second);
|
elem["functionName"] = fname;
|
||||||
|
elem["x"] = (double)coords.first;
|
||||||
|
elem["y"] = (double)coords.second;
|
||||||
|
pos_array.push_back(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
json allPositions;
|
||||||
|
allPositions["allPositions"] = pos_array;
|
||||||
|
|
||||||
|
string resVal = allPositions.dump();
|
||||||
copyStringToShort(result, resVal);
|
copyStringToShort(result, resVal);
|
||||||
retSize = (int)resVal.size() + 1;
|
retSize = (int)resVal.size() + 1;
|
||||||
}
|
}
|
||||||
@@ -680,61 +680,6 @@ int SPF_GetGraphFunctionPositions(void*& context, int winHandler, short *options
|
|||||||
return retSize;
|
return retSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SPF_GetGraphVizOfFunctions(void*& context, short *options, short *projName, short *&result, short *&output, int *&outputSize,
|
|
||||||
short *&outputMessage, int *&outputMessageSize)
|
|
||||||
{
|
|
||||||
MessageManager::clearCache();
|
|
||||||
clearGlobalMessagesBuffer();
|
|
||||||
setOptions(options);
|
|
||||||
|
|
||||||
int retSize = -1;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
runPassesForVisualizer(projName, { FILL_PAR_REGIONS_LINES });
|
|
||||||
|
|
||||||
map<string, CallV> V;
|
|
||||||
vector<string> E;
|
|
||||||
CreateCallGraphViz(NULL, allFuncInfo, V, E);
|
|
||||||
|
|
||||||
string graph = to_string(V.size()) += "|";
|
|
||||||
for (auto &v : V)
|
|
||||||
graph += v.second.to_string() + "|";
|
|
||||||
|
|
||||||
graph += to_string(E.size()) + "|";
|
|
||||||
for (auto &e : E)
|
|
||||||
graph += e + "|";
|
|
||||||
//erase last "|"
|
|
||||||
graph.erase(graph.end() - 1);
|
|
||||||
|
|
||||||
copyStringToShort(result, graph);
|
|
||||||
retSize = (int)graph.size();
|
|
||||||
|
|
||||||
if (showDebug)
|
|
||||||
printf("GraphViz: '%s'\n", graph.c_str());
|
|
||||||
}
|
|
||||||
catch (int ex)
|
|
||||||
{
|
|
||||||
try { __spf_print(1, "catch code %d\n", ex); }
|
|
||||||
catch (...) {}
|
|
||||||
if (ex == -99)
|
|
||||||
return -99;
|
|
||||||
else
|
|
||||||
retSize = -1;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
retSize = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//convertBuffers(outputMessage, outputMessageSize, output, outputSize);
|
|
||||||
|
|
||||||
if (showDebug)
|
|
||||||
printf("SAPFOR: return from DLL\n");
|
|
||||||
|
|
||||||
MessageManager::setWinHandler(-1);
|
|
||||||
return retSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int PASSES_DONE[EMPTY_PASS];
|
extern int PASSES_DONE[EMPTY_PASS];
|
||||||
extern int *ALGORITHMS_DONE[EMPTY_ALGO];
|
extern int *ALGORITHMS_DONE[EMPTY_ALGO];
|
||||||
extern const char *passNames[EMPTY_PASS + 1];
|
extern const char *passNames[EMPTY_PASS + 1];
|
||||||
@@ -1363,13 +1308,12 @@ int SPF_GetIntrinsics(void*& context, short *&result)
|
|||||||
return (int)resVal.size() + 1;
|
return (int)resVal.size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern map<string, set<string>> includeDependencies;
|
extern map<string, vector<pair<int, string>>> includeDependencies;
|
||||||
int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, short *projName, short *&result, short*& output, int*& outputSize,
|
int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, short *projName, short *&result, short*& output, int*& outputSize,
|
||||||
short*& outputMessage, int*& outputMessageSize)
|
short*& outputMessage, int*& outputMessageSize)
|
||||||
{
|
{
|
||||||
MessageManager::clearCache();
|
MessageManager::clearCache();
|
||||||
MessageManager::setWinHandler(winHandler);
|
MessageManager::setWinHandler(winHandler);
|
||||||
string resVal = "";
|
|
||||||
|
|
||||||
setOptions(options);
|
setOptions(options);
|
||||||
int retSize = 0;
|
int retSize = 0;
|
||||||
@@ -1377,23 +1321,28 @@ int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, s
|
|||||||
{
|
{
|
||||||
runPassesForVisualizer(projName, { BUILD_INCLUDE_DEPENDENCIES });
|
runPassesForVisualizer(projName, { BUILD_INCLUDE_DEPENDENCIES });
|
||||||
|
|
||||||
int i = 0;
|
json inc_array = json::array();
|
||||||
for (auto &deps : includeDependencies)
|
for (const auto& deps : includeDependencies)
|
||||||
{
|
{
|
||||||
if (i != 0)
|
json includes;
|
||||||
resVal += "@";
|
includes["file"] = deps.first;
|
||||||
resVal += deps.first + "@";
|
|
||||||
int k = 0;
|
json array = json::array();
|
||||||
for (auto &incl : deps.second)
|
for (const auto& [line, incl] : deps.second)
|
||||||
{
|
{
|
||||||
if (k != 0)
|
json elem;
|
||||||
resVal += "|";
|
elem["line"] = line;
|
||||||
resVal += incl;
|
elem["dependencyFileName"] = incl;
|
||||||
++k;
|
array.push_back(elem);
|
||||||
}
|
}
|
||||||
++i;
|
includes["includes"] = array;
|
||||||
|
inc_array.push_back(includes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json allIncludes;
|
||||||
|
allIncludes["allIncludes"] = inc_array;
|
||||||
|
string resVal = allIncludes.dump();
|
||||||
|
|
||||||
copyStringToShort(result, resVal);
|
copyStringToShort(result, resVal);
|
||||||
retSize = (int)resVal.size() + 1;
|
retSize = (int)resVal.size() + 1;
|
||||||
}
|
}
|
||||||
@@ -1429,15 +1378,7 @@ int SPF_SetFunctionsToInclude(void*& context, int winHandler, short *options, sh
|
|||||||
{
|
{
|
||||||
runPassesForVisualizer(projName, { FIND_FUNC_TO_INCLUDE });
|
runPassesForVisualizer(projName, { FIND_FUNC_TO_INCLUDE });
|
||||||
|
|
||||||
string resVal = "";
|
string resVal = convertToJson(allFuncInfo).dump();
|
||||||
resVal = to_string(allFuncInfo.size());
|
|
||||||
for (auto f = allFuncInfo.begin(); f != allFuncInfo.end(); ++f)
|
|
||||||
{
|
|
||||||
resVal += "|" + f->first + "|" + to_string(f->second.size());
|
|
||||||
for (int i = 0; i < f->second.size(); ++i)
|
|
||||||
resVal += convertToString(f->second[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
copyStringToShort(result, resVal);
|
copyStringToShort(result, resVal);
|
||||||
retSize = (int)resVal.size() + 1;
|
retSize = (int)resVal.size() + 1;
|
||||||
}
|
}
|
||||||
@@ -1523,18 +1464,32 @@ int SPF_GetFileLineInfo(void*& context, int winHandler, short *options, short *p
|
|||||||
{
|
{
|
||||||
runPassesForVisualizer(projName, { FILE_LINE_INFO });
|
runPassesForVisualizer(projName, { FILE_LINE_INFO });
|
||||||
|
|
||||||
string resVal = "";
|
json metric_array = json::array();
|
||||||
for (auto it = lineInfo.begin(); it != lineInfo.end(); ++it)
|
for (const auto& fileInfo : lineInfo)
|
||||||
{
|
{
|
||||||
if (it != lineInfo.begin())
|
json fileMetric;
|
||||||
resVal += "@";
|
|
||||||
|
|
||||||
auto itD = dirsInfo.find(it->first);
|
fileMetric["file"] = fileInfo.first;
|
||||||
if (itD == dirsInfo.end())
|
fileMetric["linesCount"] = fileInfo.second;
|
||||||
resVal += it->first + "@" + to_string(it->second) + "_0_0";
|
|
||||||
else
|
auto it = dirsInfo.find(fileInfo.first);
|
||||||
resVal += it->first + "@" + to_string(it->second) + "_" + to_string(itD->second.first.size()) + "_" + to_string(itD->second.second.size());
|
if (it == dirsInfo.end())
|
||||||
|
{
|
||||||
|
fileMetric["numSPF"] = 0;
|
||||||
|
fileMetric["numDVM"] = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileMetric["numSPF"] = (int)it->second.first.size();
|
||||||
|
fileMetric["numDVM"] = (int)it->second.second.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
metric_array.push_back(fileMetric);
|
||||||
|
}
|
||||||
|
|
||||||
|
json allMetrics;
|
||||||
|
allMetrics["allMetrics"] = metric_array;
|
||||||
|
string resVal = allMetrics.dump();
|
||||||
|
|
||||||
copyStringToShort(result, resVal);
|
copyStringToShort(result, resVal);
|
||||||
retSize = (int)resVal.size() + 1;
|
retSize = (int)resVal.size() + 1;
|
||||||
@@ -2234,38 +2189,44 @@ int SPF_InlineProcedures(void*& context, int winHandler, short* options, short*
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern map<string, set<string>> filesToInclude;
|
extern map<string, vector<pair<int, string>>> filesToInclude;
|
||||||
int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *filesToInclude,
|
int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *visFilesToInclude,
|
||||||
short *&output, int *&outputSize, short *&outputMessage, int *&outputMessageSize)
|
short *&output, int *&outputSize, short *&outputMessage, int *&outputMessageSize)
|
||||||
{
|
{
|
||||||
MessageManager::clearCache();
|
MessageManager::clearCache();
|
||||||
MessageManager::setWinHandler(winHandler);
|
MessageManager::setWinHandler(winHandler);
|
||||||
|
|
||||||
if (filesToInclude == NULL)
|
if (visFilesToInclude == NULL)
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
vector<string> splited;
|
vector<string> splited;
|
||||||
//printf("%s\n", conv);
|
//printf("%s\n", conv);
|
||||||
splitString(filesToInclude, '|', splited);
|
splitString(visFilesToInclude, '|', splited);
|
||||||
|
|
||||||
if (splited.size() == 0)
|
if (splited.size() == 0)
|
||||||
return -3;
|
return -3;
|
||||||
|
|
||||||
::filesToInclude.clear();
|
filesToInclude.clear();
|
||||||
for (int i = 0; i < splited.size(); ++i)
|
unsigned i = 0;
|
||||||
|
while (i < splited.size())
|
||||||
{
|
{
|
||||||
string file = splited[i];
|
string file = splited[i++];
|
||||||
int num = 0;
|
int num = 0;
|
||||||
if (sscanf(splited[i + 1].c_str(), "%d", &num) == -1)
|
if (sscanf(splited[i++].c_str(), "%d", &num) == -1)
|
||||||
return -3;
|
return -4;
|
||||||
|
|
||||||
__spf_print(1, "file = %s:\n", file.c_str());
|
__spf_print(1, "file = %s:\n", file.c_str());
|
||||||
for (int k = i + 2; k < i + 2 + num; ++k)
|
for (int k = i; k < i + 2 * num; k += 2)
|
||||||
{
|
{
|
||||||
::filesToInclude[file].insert(splited[k]);
|
int line = 0;
|
||||||
__spf_print(1, " include = %s\n", splited[k].c_str());
|
if (sscanf(splited[k].c_str(), "%d", &line) == -1)
|
||||||
|
return -5;
|
||||||
|
|
||||||
|
auto pair = make_pair(line, splited[k + 1]);
|
||||||
|
filesToInclude[file].push_back(pair);
|
||||||
|
__spf_print(1, " include = [%d %s]\n", pair.first, pair.second.c_str());
|
||||||
}
|
}
|
||||||
i += 1 + num;
|
i += 2 * num;
|
||||||
}
|
}
|
||||||
return simpleTransformPass(INSERT_INCLUDES, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
|
return simpleTransformPass(INSERT_INCLUDES, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
|
||||||
}
|
}
|
||||||
@@ -2479,8 +2440,6 @@ const wstring Sapfor_RunAnalysis(const char* analysisName_c, const char* options
|
|||||||
retCode = SPF_GetGraphFunctions(context, winHandler, optSh, projSh, result, output, outputSize, outputMessage, outputMessageSize);
|
retCode = SPF_GetGraphFunctions(context, winHandler, optSh, projSh, result, output, outputSize, outputMessage, outputMessageSize);
|
||||||
else if (whichRun == "SPF_GetGraphFunctionPositions")
|
else if (whichRun == "SPF_GetGraphFunctionPositions")
|
||||||
retCode = SPF_GetGraphFunctionPositions(context, winHandler, optSh, projSh, result, output, outputSize, outputMessage, outputMessageSize);
|
retCode = SPF_GetGraphFunctionPositions(context, winHandler, optSh, projSh, result, output, outputSize, outputMessage, outputMessageSize);
|
||||||
else if (whichRun == "SPF_GetGraphVizOfFunctions")
|
|
||||||
retCode = SPF_GetGraphVizOfFunctions(context, optSh, projSh, result, output, outputSize, outputMessage, outputMessageSize);
|
|
||||||
else if (whichRun == "SPF_GetArrayDistribution")
|
else if (whichRun == "SPF_GetArrayDistribution")
|
||||||
retCode = SPF_GetArrayDistribution(context, winHandler, optSh, projSh, result, output, outputSize, outputMessage, outputMessageSize, 0);
|
retCode = SPF_GetArrayDistribution(context, winHandler, optSh, projSh, result, output, outputSize, outputMessage, outputMessageSize, 0);
|
||||||
else if (whichRun == "SPF_GetArrayDistributionOnlyAnalysis")
|
else if (whichRun == "SPF_GetArrayDistributionOnlyAnalysis")
|
||||||
|
|||||||
Reference in New Issue
Block a user