42 Commits

Author SHA1 Message Date
Egor Mayorov
00f205457c swap operators in AST 2025-05-27 15:55:02 +03:00
Egor Mayorov
59ce77c938 Use more complex algorythm for building new order of statements 2025-05-27 01:41:50 +03:00
Egor Mayorov
247a96b8ac update in new order 2025-05-24 23:15:30 +03:00
Egor Mayorov
ec28779d5b biulding new order 2025-05-24 19:56:15 +03:00
Egor Mayorov
8c0ee5a5ef some loop analysis done 2025-05-22 22:41:09 +03:00
Egor Mayorov
a8e65ccf26 Add _bin to gitignore 2025-05-19 22:23:36 +03:00
ALEXks
c1b1972d61 fixed 2025-05-19 21:21:13 +03:00
ALEXks
7ab4e7555a added json to SPF_GetArrayLinks 2025-05-19 21:21:13 +03:00
ALEXks
b59dcfffe1 fixed typo 2025-05-19 21:21:13 +03:00
ALEXks
563fd2d41a fixed AlignRuleBase::toJson() 2025-05-19 21:21:13 +03:00
ALEXks
96c1f8098b fixed Array::toJson() 2025-05-19 21:21:13 +03:00
ALEXks
4c85799c14 version updated 2025-05-19 21:21:13 +03:00
ALEXks
e278a1db91 added json for SPF_GetArrayDistribution pass 2025-05-19 21:21:13 +03:00
ALEXks
37d87dc645 added json for SPF_GetAllDeclaratedArrays pass 2025-05-19 21:21:13 +03:00
ALEXks
0f374ada8d fixed NULL error in matchParallelAndDist function 2025-05-19 21:21:13 +03:00
ALEXks
fb6e7eece6 fixed BUILD_INCLUDE_DEPENDENCIES pass 2025-05-19 21:21:13 +03:00
ALEXks
9e8a632cd6 updated submodule 2025-05-19 21:21:13 +03:00
ALEXks
abc23ecc38 fixed getNameInLocation 2025-05-19 21:21:13 +03:00
ALEXks
9ab4f8aba0 fixed module utils 2025-05-19 21:21:13 +03:00
ALEXks
fb93a5b1aa fixed gcov 2025-05-19 21:21:13 +03:00
ALEXks
d0b5558805 added json for SPF_GetGCovInfo pass 2025-05-19 21:21:13 +03:00
ALEXks
01b376a2bf fixed getInterfaceBlock 2025-05-19 21:21:13 +03:00
ALEXks
794e2daded fixed SPF_InsertIncludesPass unpacking 2025-05-19 21:21:13 +03:00
ALEXks
15d8a8dd8f added predictor library to Sapfor 2025-05-19 21:21:13 +03:00
f190c9ac48 added predictor library to submodule 2025-05-19 21:21:13 +03:00
ALEXks
38a51d7ad1 fixed predictor 2025-05-19 21:21:13 +03:00
ALEXks
c3a08e0c64 added json for line info 2025-05-19 21:21:13 +03:00
ALEXks
11cc671416 fixed dumping statistics 2025-05-19 21:21:13 +03:00
ALEXks
d9bf9eeb8e added pass dependency for RENAME_INLCUDES 2025-05-19 21:21:13 +03:00
ALEXks
264649d748 moved SPF_GetIncludeDependencies to json 2025-05-19 21:21:13 +03:00
ALEXks
731816035f added json for call graph positions, removed SPF_GetGraphVizOfFunctions 2025-05-19 21:21:13 +03:00
ALEXks
50c80f7ea1 added json for call graph 2025-05-19 21:21:13 +03:00
ALEXks
8e90d2517d removed checking from predictor 2025-05-19 21:21:13 +03:00
ALEXks
c4f20df7fc fixed 2025-05-19 21:21:13 +03:00
ALEXks
5f6bcdf974 version 2025-05-19 21:21:13 +03:00
ALEXks
7236f5bdf0 declare for module in progess 2025-05-19 21:21:13 +03:00
ALEXks
c8961828bc moved LoopGraph to json 2025-05-19 21:21:13 +03:00
ALEXks
c808e47805 moved LoopGraph to json 2025-05-19 21:21:13 +03:00
Egor Mayorov
600094f13a Some actions simplify analyzing IR 2025-05-13 00:47:25 +03:00
Egor Mayorov
5052e7e218 Pass with output file added 2025-04-15 18:10:13 +03:00
Egor Mayorov
d78c86a7dc change pass deps 2025-03-29 15:41:58 +03:00
Egor Mayorov
83c07da3cc New pass 2025-03-25 15:20:13 +03:00
30 changed files with 23778 additions and 400 deletions

1
.gitignore vendored
View File

@@ -77,3 +77,4 @@ Sapfor/Sapc++/x64/
Sapfor/out/
Sapfor/_bin/*
_bin/*

3
.gitmodules vendored
View File

@@ -1,3 +1,6 @@
[submodule "projects/dvm"]
path = projects/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

View File

@@ -13,16 +13,18 @@ add_definitions("-D YYDEBUG")
set(CMAKE_CXX_STANDARD 17)
set(fdvm_include projects/dvm/fdvmh/include/fdvmh/)
set(fdvm_sources projects/dvm/fdvmh/tools/fdvmh/)
set(sage_include_1 projects/dvm/fdvmh/include/sage/lib/)
set(sage_include_2 projects/dvm/fdvmh/include/sage/h/)
set(libdb_sources projects/dvm/fdvmh/lib/sage/db/)
set(sage_sources projects/dvm/fdvmh/lib/sage/sage/)
set(sagepp_sources projects/dvm/fdvmh/lib/sage/sage++/)
set(parser_sources projects/dvm/fdvmh/tools/parser/)
set(pppa_sources projects/dvm/pppa/src/)
set(zlib_sources projects/dvm/third-party/Zlib/)
set(fdvm_include projects/dvm/fdvmh/include/fdvmh/)
set(fdvm_sources projects/dvm/fdvmh/tools/fdvmh/)
set(sage_include_1 projects/dvm/fdvmh/include/sage/lib/)
set(sage_include_2 projects/dvm/fdvmh/include/sage/h/)
set(libdb_sources projects/dvm/fdvmh/lib/sage/db/)
set(sage_sources projects/dvm/fdvmh/lib/sage/sage/)
set(sagepp_sources projects/dvm/fdvmh/lib/sage/sage++/)
set(parser_sources projects/dvm/fdvmh/tools/parser/)
set(pppa_sources projects/dvm/pppa/src/)
set(zlib_sources projects/dvm/third-party/Zlib/)
set(libpred_sources projects/libpredictor/src/)
set(libpred_include projects/libpredictor/include/)
include_directories(src)
#Sage lib includes
@@ -33,6 +35,8 @@ include_directories(${sage_include_2})
include_directories(${zlib_sources}/include)
#PPPA includes
include_directories(${pppa_sources})
#Libpredictor includes
include_directories(${libpred_include})
set(PR_PARAM src/ProjectParameters/projectParameters.cpp
src/ProjectParameters/projectParameters.h)
@@ -54,7 +58,7 @@ set(VS_CALLS src/VisualizerCalls/get_information.cpp
src/VisualizerCalls/SendMessage.h
src/VisualizerCalls/BuildGraph.cpp
src/VisualizerCalls/BuildGraph.h)
set(VERIF src/VerificationCode/CorrectVarDecl.cpp
src/VerificationCode/IncludeChecker.cpp
src/VerificationCode/StructureChecker.cpp
@@ -76,7 +80,8 @@ set(UTILS src/Utils/AstWrapper.h
src/Utils/utils.h
src/Utils/version.h
src/Utils/module_utils.h
src/Utils/module_utils.cpp)
src/Utils/module_utils.cpp
src/Utils/json.hpp)
set(OMEGA src/SageAnalysisTool/OmegaForSage/add-assert.cpp
src/SageAnalysisTool/OmegaForSage/affine.cpp
@@ -177,6 +182,8 @@ set(TR_IMPLICIT_NONE src/Transformations/set_implicit_none.cpp
src/Transformations/set_implicit_none.h)
set(TR_REPLACE_ARRAYS_IN_IO src/Transformations/replace_dist_arrays_in_io.cpp
src/Transformations/replace_dist_arrays_in_io.h)
SET(SWAP_OPERATORS src/SwapOperators/swapOperators.cpp
src/SwapOperators/swapOperators.h)
set(TRANSFORMS
${TR_DEAD_CODE}
@@ -311,6 +318,15 @@ set(MAIN src/Sapfor.cpp
set(PREDICTOR src/Predictor/PredictScheme.cpp
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
src/ProjectManipulation/ParseFiles.h
@@ -400,12 +416,14 @@ set(SOURCE_EXE
${VS_CALLS}
${MAIN}
${PREDICTOR}
${LIBPREDICTOR}
${PARSER}
${PPPA}
${ZLIB}
${GR_LAYOUT}
${PR_PARAM}
${PROJ_MAN})
${PROJ_MAN}
${SWAP_OPERATORS})
add_executable(Sapfor_F ${SOURCE_EXE})
source_group (CFGraph FILES ${CFG})
@@ -449,12 +467,14 @@ source_group (Utils FILES ${UTILS})
source_group (VerificationCode FILES ${VERIF})
source_group (ProjectParameters FILES ${PR_PARAM})
source_group (ProjectManipulation FILES ${PROJ_MAN})
source_group (SwapOperators FILES ${SWAP_OPERATORS})
source_group (VisualizerCalls FILES ${VS_CALLS})
source_group (VisualizerCalls\\GraphLayout FILES ${GR_LAYOUT})
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 (PPPA\\PPPA FILES ${PPPA})
source_group (PPPA\\ZLib FILES ${ZLIB})

1
projects/libpredictor Submodule

Submodule projects/libpredictor added at d0772cdb57

View File

@@ -1601,7 +1601,7 @@ static bool matchParallelAndDist(const pair<DIST::Array*, const DistrVariant*>&
parallelOn = NULL;
for (auto& refOn : realRefs)
{
linkWithTempl = parallelOn->GetLinksWithTemplate(regionId);
linkWithTempl = refOn->GetLinksWithTemplate(regionId);
int z = 0;
for (int k = 0; k < linkWithTempl.size(); ++k)
if (linkWithTempl[k] != -1)

View File

@@ -9,6 +9,7 @@
#include "DvmhDirectiveBase.h"
#include "../Utils/utils.h"
#include "../Utils/errors.h"
#include "../Utils/json.hpp"
class Symbol;
class Expression;
@@ -20,6 +21,7 @@ struct FuncInfo;
#define MAP std::map
#define SET std::set
#define TO_STR std::to_string
#define JSON nlohmann::json
#if __SPF
extern int sharedMemoryParallelization;
@@ -104,7 +106,7 @@ namespace Distribution
MAP<STRING, SET<int>> usagePlaces;
VECTOR<bool> mappedDims;
VECTOR<bool> depracateToDistribute;
VECTOR<bool> deprecateToDistribute;
bool ompThreadPrivate;
bool privateInLoop;
@@ -169,7 +171,7 @@ namespace Distribution
sizes.resize(dimSize);
sizesExpr.resize(dimSize);
mappedDims.resize(dimSize);
depracateToDistribute.resize(dimSize);
deprecateToDistribute.resize(dimSize);
for (int z = 0; z < dimSize; ++z)
{
@@ -177,7 +179,7 @@ namespace Distribution
PAIR<int, int> initVal = std::make_pair(0, 0);
sizesExpr[z] = std::make_pair(std::make_pair((Expression*)NULL, initVal), std::make_pair((Expression*)NULL, initVal));
mappedDims[z] = false;
depracateToDistribute[z] = false;
deprecateToDistribute[z] = false;
}
GenUniqKey();
@@ -212,7 +214,7 @@ namespace Distribution
uniqKey = copy.uniqKey;
containsInRegions = copy.containsInRegions;
mappedDims = copy.mappedDims;
depracateToDistribute = copy.depracateToDistribute;
deprecateToDistribute = copy.deprecateToDistribute;
ompThreadPrivate = copy.ompThreadPrivate;
privateInLoop = copy.privateInLoop;
inEquivalence = copy.inEquivalence;
@@ -224,7 +226,7 @@ namespace Distribution
int countToRem = 0;
for (int z = 0; z < dimSize; ++z)
{
if (!mappedDims[z] || depracateToDistribute[z])
if (!mappedDims[z] || deprecateToDistribute[z])
{
needToRemove = true;
countToRem++;
@@ -244,19 +246,19 @@ namespace Distribution
for (int z = 0; z < dimSize; ++z)
{
if (mappedDims[z] && !depracateToDistribute[z])
if (mappedDims[z] && !deprecateToDistribute[z])
{
newSizes.push_back(sizes[z]);
newSizesExpr.push_back(sizesExpr[z]);
newMappedDims.push_back(mappedDims[z]);
newDepr.push_back(depracateToDistribute[z]);
newDepr.push_back(deprecateToDistribute[z]);
}
}
sizes = newSizes;
sizesExpr = newSizesExpr;
mappedDims = newMappedDims;
depracateToDistribute = newDepr;
deprecateToDistribute = newDepr;
dimSize = (int)sizes.size();
return false;
@@ -424,48 +426,64 @@ namespace Distribution
void ClearShadowSpecs() { allShadowSpecs.clear(); }
STRING toString()
JSON toJson()
{
STRING retVal = "";
retVal += TO_STR(id);
retVal += "#" + name;
retVal += "#" + shortName;
retVal += "#" + TO_STR(dimSize);
retVal += "#" + TO_STR(typeSize);
retVal += "#" + TO_STR(isNonDistribute);
retVal += "#" + TO_STR(locationPos.first);
retVal += "#" + locationPos.second;
JSON retVal;
retVal += "#" + TO_STR(sizes.size());
for (int i = 0; i < sizes.size(); ++i)
retVal += "#" + TO_STR(sizes[i].first) + "#" + TO_STR(sizes[i].second);
retVal["id"] = (int64_t)id;
retVal["name"] = name;
retVal["shortName"] = shortName;
retVal["packedAddress"] = std::to_string((long long)this);
retVal += "#" + TO_STR(depracateToDistribute.size());
for (int i = 0; i < depracateToDistribute.size(); ++i)
retVal += "#" + TO_STR((int)depracateToDistribute[i]);
retVal["dimSize"] = dimSize;
retVal["typeSize"] = typeSize;
retVal["state"] = (int)isNonDistribute;
retVal["location"] = (int)locationPos.first;
retVal["locName"] = locationPos.second;
retVal += "#" + TO_STR(mappedDims.size());
retVal["isTemplFlag"] = (int)isTemplFlag;
retVal["isLoopArrayFlag"] = (int)isLoopArrayFlag;
JSON deprToDist = nlohmann::json::array();
for (int i = 0; i < deprecateToDistribute.size(); ++i)
deprToDist.push_back((int)deprecateToDistribute[i]);
retVal["deprecateToDist"] = deprToDist;
JSON mappedDimsJ = nlohmann::json::array();
for (int i = 0; i < mappedDims.size(); ++i)
retVal += "#" + TO_STR((int)mappedDims[i]);
mappedDimsJ.push_back((int)mappedDims[i]);
retVal["mappedDims"] = mappedDimsJ;
retVal += "#" + TO_STR(templateInfo.size());
for (auto it = templateInfo.begin(); it != templateInfo.end(); ++it)
retVal += "#" + TO_STR(it->first) + it->second->toString();
retVal += "#" + TO_STR((int)isTemplFlag);
retVal += "|" + TO_STR((int)isLoopArrayFlag);
retVal += "|" + TO_STR(declPlaces.size());
JSON sizesJ = nlohmann::json::array();
for (int i = 0; i < sizes.size(); ++i)
{
JSON pair;
pair["key"] = sizes[i].first;
pair["value"] = sizes[i].second;
sizesJ.push_back(pair);
}
retVal["sizes"] = sizesJ;
for (auto &place : declPlaces)
retVal += "|" + place.first + "|" + TO_STR(place.second);
JSON regions = nlohmann::json::array();
for (auto& reg : containsInRegions)
regions.push_back(reg);
retVal["regions"] = regions;
JSON declPlacesJ = nlohmann::json::array();
for (auto& place : declPlaces)
{
JSON elem;
elem["file"] = place.first;
elem["line"] = place.second;
declPlacesJ.push_back(elem);
}
retVal["declPlaces"] = declPlacesJ;
retVal += "|" + TO_STR(containsInRegions.size());
for (auto &reg : containsInRegions)
retVal += "|" + reg;
return retVal;
}
Array* GetTemplateArray(const uint64_t regionId, bool withCheck = true)
{
TemplateLink *currLink = getTemlateInfo(regionId, withCheck);
@@ -587,13 +605,13 @@ namespace Distribution
{
if (dim >= dimSize)
return;
depracateToDistribute[dim] = value;
deprecateToDistribute[dim] = value;
}
void DeprecateAllDims()
{
for (int dim = 0; dim < dimSize; ++dim)
depracateToDistribute[dim] = true;
deprecateToDistribute[dim] = true;
}
bool IsDimDepracated(const int dim) const
@@ -603,9 +621,9 @@ namespace Distribution
else
{
if (templateDimsOrder.size() == 0)
return depracateToDistribute[dim];
return deprecateToDistribute[dim];
else
return depracateToDistribute[templateDimsOrder[dim]];
return deprecateToDistribute[templateDimsOrder[dim]];
}
}
@@ -613,11 +631,11 @@ namespace Distribution
{
bool ret = true;
for (int z = 0; z < dimSize; ++z)
ret = ret && depracateToDistribute[z];
ret = ret && deprecateToDistribute[z];
return ret;
}
const VECTOR<bool>& GetDeprecetedDims() const { return depracateToDistribute; }
const VECTOR<bool>& GetDeprecetedDims() const { return deprecateToDistribute; }
int GetTypeSize() const { return typeSize; }

View File

@@ -199,15 +199,6 @@ static set<string> fillUsedSymbols(SgStatement *loop)
return usedS;
}
static string correctSymbolModuleName(const string& origFull)
{
auto it = origFull.find("::");
if (it == string::npos)
return origFull;
else
return origFull.substr(it + 2);
}
static SgStatement* getModuleScope(const string& origFull, vector<SgStatement*>& moduleList, SgStatement *local)
{
auto it = origFull.find("::");
@@ -959,7 +950,7 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
SgSymbol* redS;
string clearName = correctSymbolModuleName(red);
if (clearName != red)
redS = getNameInLocation(parentFunc, clearName, getModuleScope(red, moduleList, parentFunc)->symbol()->identifier());
redS = getNameInLocation(parentFunc, red, getModuleScope(red, moduleList, parentFunc)->symbol()->identifier());
else
redS = findSymbolOrCreate(file, clearName, NULL, parentFunc);
@@ -1017,12 +1008,12 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
string clearName2 = correctSymbolModuleName(get<1>(list));
if (clearName1 != get<0>(list))
redS1 = getNameInLocation(parentFunc, clearName1, getModuleScope(get<0>(list), moduleList, parentFunc)->symbol()->identifier());
redS1 = getNameInLocation(parentFunc, get<0>(list), getModuleScope(get<0>(list), moduleList, parentFunc)->symbol()->identifier());
else
redS1 = findSymbolOrCreate(file, clearName1, NULL, parentFunc);
if (clearName2 != get<1>(list))
redS2 = getNameInLocation(parentFunc, clearName2, getModuleScope(get<1>(list), moduleList, parentFunc)->symbol()->identifier());
redS2 = getNameInLocation(parentFunc, get<1>(list), getModuleScope(get<1>(list), moduleList, parentFunc)->symbol()->identifier());
else
redS2 = findSymbolOrCreate(file, clearName2, NULL, parentFunc);

View File

@@ -12,6 +12,8 @@
#include "../Distribution/GraphCSR.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../Utils/json.hpp"
#include "../GraphCall/graph_calls_func.h"
using std::vector;
@@ -27,6 +29,8 @@ using std::make_pair;
using std::min;
using std::max;
using nlohmann::json;
template<typename setT>
static void uniteSets(const set<setT> &first, const set<setT> &second, set<setT> &result)
{
@@ -732,30 +736,34 @@ string AlignRuleBase::GenRuleBase() const
return retVal;
}
string AlignRuleBase::toString()
json AlignRuleBase::toJson()
{
string retVal = "";
json retVal;
if (alignArray)
retVal += "#" + std::to_string((long long)alignArray);
else
retVal += "#-1";
retVal["packedAlignArrayAddress"] = alignArray ? std::to_string((long long)alignArray) : std::to_string((long long)-1);
retVal["packedAlignWithAddress"] = alignWith ? std::to_string((long long)alignWith) : std::to_string((long long)-1);
if (alignWith)
retVal += "#" + std::to_string((long long)alignWith);
else
retVal += "#-1";
json alignRules = json::array();
for (auto& rule : alignRule)
{
json pair;
pair["key"] = rule.first;
pair["value"] = rule.second;
alignRules.push_back(pair);
}
retVal["alignRule"] = alignRules;
retVal += "#" + std::to_string(alignRule.size());
for (int i = 0; i < alignRule.size(); ++i)
retVal += "#" + std::to_string(alignRule[i].first) + "#" + std::to_string(alignRule[i].second);
retVal += "#" + std::to_string(alignRuleWith.size());
for (int i = 0; i < alignRuleWith.size(); ++i)
retVal += "#" + std::to_string(alignRuleWith[i].first)
+ "#" + std::to_string(alignRuleWith[i].second.first)
+ "#" + std::to_string(alignRuleWith[i].second.second);
json alignRuleWithJ = json::array();
for (auto& [dimNum, AB] : alignRuleWith)
{
json tuple;
tuple["dimNum"] = dimNum;
tuple["a"] = AB.first;
tuple["b"] = AB.second;
alignRuleWithJ.push_back(tuple);
}
retVal["alignRuleWith"] = alignRuleWithJ;
return retVal;
}

View File

@@ -3,6 +3,8 @@
#include <vector>
#include <string>
#include "../Utils/json.hpp"
typedef enum lang : int { LANG_C, LANG_F } language;
typedef enum dist : int { BLOCK, NONE } distType;
typedef std::pair<std::pair<int, int>, std::pair<int, int>> attrType;
@@ -48,7 +50,7 @@ public:
public:
std::string GenRuleBase() const;
std::string toString();
nlohmann::json toJson();
public:
DIST::Array *alignArray;

View File

@@ -17,7 +17,6 @@
using namespace std;
#define DVMH_REG_RD 0
#define DVMH_REG_WT 1
@@ -835,19 +834,21 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
auto copy = duplicateProcedure(func, NULL, false, false, false, true);
const set<string> idents(pars.identificators.begin(), pars.identificators.end());
bool need = (func->symbol()->identifier() == string("bl182"));
//remove all exec
SgStatement* st = copy->lexNext();
SgStatement* last = copy->lastNodeOfStmt();
vector<SgStatement*> toExtract;
while (st != last)
{
if (isDVM_stat(st) || isSPF_stat(st))
{
if (st->variant() != ACC_ROUTINE_DIR)
{
SgStatement* next = st->lexNext();
st->extractStmt();
st = next;
toExtract.push_back(st);
st = st->lexNext();
}
else
st = st->lexNext();
@@ -869,6 +870,7 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
while (st != last)
{
const int var = st->variant();
if (var == VAR_DECL
|| var == VAR_DECL_90
|| var == DIM_STAT
@@ -878,9 +880,8 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
bool empty = filterFromList(st, idents);
if (empty)
{
SgStatement* next = st->lexNext();
toExtract.push_back(st);
st = next;
st = st->lexNext();
continue;
}
}
@@ -1428,21 +1429,15 @@ static set<DIST::Array*>
for (auto& realArray : realRef)
{
if (added.count(realArray) != 0 || !realArray->IsNotDistribute())
if (added.count(realArray) != 0)
continue;
if (!realArray->IsNotDistribute())
continue;
SgStatement* declStat = NULL;
if (realArray->GetLocation().first != DIST::l_COMMON)
{
if (std::count(usedAll.begin(), usedAll.end(), realArray) == 0)
{
auto declInfo = *realArray->GetDeclInfo().begin();
declStat = SgStatement::getStatementByFileAndLine(declInfo.first, declInfo.second);
checkNull(declStat, convertFileName(__FILE__).c_str(), __LINE__);
}
}
else
if (realArray->GetLocation().first == DIST::l_COMMON)
{
commonArrays.insert(realArray);
auto decls = realArray->GetDeclInfo();
@@ -1471,6 +1466,19 @@ static set<DIST::Array*>
}
}
}
else if (realArray->GetLocation().first == DIST::l_MODULE)
{
//TODO
}
else
{
if (std::count(usedAll.begin(), usedAll.end(), realArray) == 0)
{
auto declInfo = *realArray->GetDeclInfo().begin();
declStat = SgStatement::getStatementByFileAndLine(declInfo.first, declInfo.second);
checkNull(declStat, convertFileName(__FILE__).c_str(), __LINE__);
}
}
if (declStat)
{

View File

@@ -18,6 +18,7 @@
#include "../GraphLoop/graph_loops_func.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../Utils/SgUtils.h"
#include "../Utils/json.hpp"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "../ExpressionTransform/expr_transform.h"
@@ -37,6 +38,8 @@ using std::cout;
using std::endl;
using std::stack;
using json = nlohmann::json;
#define DEBUG 0
//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

View File

@@ -378,33 +378,6 @@ FuncInfo* isUserFunctionInProject(const string &func)
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
void findDeadFunctionsAndFillCalls(map<string, vector<FuncInfo*>> &allFuncInfo, map<string, vector<Messages>> &allMessages, bool noPrint)
{

View File

@@ -7,6 +7,7 @@
#include "graph_calls.h"
#include "../GraphLoop/graph_loops.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "Utils/json.hpp"
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);
std::string removeString(const std::string &toRemove, const std::string &inStr);
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 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,
@@ -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);
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);
nlohmann::json convertToJson(const std::map<std::string, std::vector<FuncInfo*>>& funcsByFile);
#endif

View File

@@ -26,11 +26,11 @@
#include "../Utils/errors.h"
#include "../Utils/AstWrapper.h"
#include "../Utils/json.hpp"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "../GraphCall/graph_calls_func.h"
#include "../Transformations/array_assign_to_loop.h"
using std::vector;
@@ -40,6 +40,8 @@ using std::string;
using std::wstring;
using std::pair;
using json = nlohmann::json;
#define DEBUG 0
static inline void insertLabels(SgExpression *lb, map<int, vector<int>> &gotoLabels, const int line)
{
@@ -918,7 +920,7 @@ void* LoopGraph::getRealStat(const char* file) const
}
extern int PASSES_DONE[EMPTY_PASS];
static void printToBuffer(const LoopGraph *currLoop, const int childSize, char buf[512])
static int getLoopState(const LoopGraph* currLoop)
{
int loopState = 0; // 0 - unknown, 1 - good, 2 - bad
if (PASSES_DONE[CREATE_TEMPLATE_LINKS] ||
@@ -934,49 +936,92 @@ static void printToBuffer(const LoopGraph *currLoop, const int childSize, char b
if (currLoop->hasLimitsToParallel())
loopState = 2;
}
sprintf(buf, "#%d#%d#%d#%d#%d#%d#%d#%d",
currLoop->lineNum, currLoop->lineNumAfterLoop, currLoop->perfectLoop, currLoop->hasGoto, currLoop->hasPrints, childSize, loopState,
currLoop->hasNonRectangularBounds);
return loopState;
}
static int calculateNormalChildSize(const LoopGraph *currLoop)
static json convertToJson(const LoopGraph* currLoop)
{
int count = 0;
for (auto &elem : currLoop->children)
count += (elem->lineNum > 0) ? 1 : 0;
return count;
}
json loop;
void convertToString(const LoopGraph *currLoop, string &result)
{
if (currLoop && currLoop->lineNum > 0)
{
char buf[512];
result += "#" + std::to_string(currLoop->calls.size());
for (int i = 0; i < currLoop->calls.size(); ++i)
result += "#" + currLoop->calls[i].first + "#" + std::to_string(currLoop->calls[i].second);
printToBuffer(currLoop, calculateNormalChildSize(currLoop), buf);
result += string(buf);
loop["file"] = currLoop->fileName;
loop["line"] = currLoop->lineNum;
loop["lineNumAfterLoop"] = currLoop->lineNumAfterLoop;
loop["perfectLoop"] = currLoop->perfectLoop;
loop["loopState"] = getLoopState(currLoop);
loop["hasNonRectangularBounds"] = (int)currLoop->hasNonRectangularBounds;
result += "#" + std::to_string(currLoop->linesOfExternalGoTo.size());
for (int i = 0; i < currLoop->linesOfExternalGoTo.size(); ++i)
result += "#" + std::to_string(currLoop->linesOfExternalGoTo[i]);
json calls = json::array();
for (auto& [func, line] : currLoop->calls)
{
json call;
call["line"] = line;
call["funcName"] = func;
result += "#" + std::to_string(currLoop->linesOfInternalGoTo.size());
for (int i = 0; i < currLoop->linesOfInternalGoTo.size(); ++i)
result += "#" + std::to_string(currLoop->linesOfInternalGoTo[i]);
calls.push_back(call);
}
loop["funcCalls"] = calls;
result += "#" + std::to_string(currLoop->linesOfIO.size());
for (auto& i : currLoop->linesOfIO)
result += "#" + std::to_string(i);
json e_gotos = json::array();
for (auto& line : currLoop->linesOfExternalGoTo)
e_gotos.push_back(line);
loop["extGotos"] = e_gotos;
result += "#" + std::to_string(currLoop->linesOfStop.size());
for (auto& i : currLoop->linesOfStop)
result += "#" + std::to_string(i);
json i_gotos = json::array();
for (auto& line : currLoop->linesOfInternalGoTo)
i_gotos.push_back(line);
loop["intGotos"] = i_gotos;
for (int i = 0; i < (int)currLoop->children.size(); ++i)
convertToString(currLoop->children[i], result);
json ios = json::array();
for (auto& line : currLoop->linesOfIO)
ios.push_back(line);
loop["ios"] = ios;
json stops = json::array();
for (auto& line : currLoop->linesOfStop)
stops.push_back(line);
loop["stops"] = stops;
json children = json::array();
for (const auto& ch : currLoop->children)
{
auto conv = convertToJson(ch);
if (!conv.empty())
children.push_back(conv);
}
loop["children"] = children;
}
return loop;
}
json convertToJson(const map<string, vector<LoopGraph*>>& loopsByFileMap)
{
json loopsByFile = json::array();
for (auto& byFile : loopsByFileMap)
{
json loop;
const string& file = byFile.first;
json loops_array = json::array();
for (auto& loop : byFile.second)
{
auto conv = convertToJson(loop);
if (!conv.empty())
loops_array.push_back(conv);
}
loop["file"] = file;
loop["loops"] = loops_array;
loopsByFile.push_back(loop);
}
json allLoops;
allLoops["allLoops"] = loopsByFile;
return allLoops;
}
void createMapLoopGraph(const vector<LoopGraph*> &loops, map<int, LoopGraph*> &mapGraph)

View File

@@ -497,7 +497,6 @@ void processLoopInformationForFunction(std::map<LoopGraph*, std::map<DIST::Array
void addToDistributionGraph(const std::map<LoopGraph*, std::map<DIST::Array*, ArrayInfo*>>& loopInfo, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
void selectFreeLoopsForParallelization(const std::vector<LoopGraph*>& loops, const std::string& funcName, bool isDistribute, const std::vector<ParallelRegion*>& regions, std::vector<Messages>& messagesForFile);
void convertToString(const LoopGraph* currLoop, std::string& result);
int printLoopGraph(const char* fileName, const std::map<std::string, std::vector<LoopGraph*>>& loopGraph, bool withRegs = false);
void checkCountOfIter(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, std::map<std::string, std::vector<Messages>>& SPF_messages);

View File

@@ -2,8 +2,10 @@
#include <vector>
#include <map>
#include <string>
#include "graph_loops.h"
#include "../Distribution/DvmhDirective.h"
#include "Utils/json.hpp"
struct SpfInterval;
@@ -17,4 +19,6 @@ bool checkRegionEntries(SgStatement *begin, SgStatement *end, const std::map<std
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);
bool detectMpiCalls(SgProject* proj, std::map<std::string, std::vector<Messages>>& SPF_messages);
int calculateLoopIters(SgExpression* start, SgExpression* end, SgExpression* step, std::tuple<int, int, int>& result);
int calculateLoopIters(SgExpression* start, SgExpression* end, SgExpression* step, std::tuple<int, int, int>& result);
nlohmann::json convertToJson(const std::map<std::string, std::vector<LoopGraph*>>& loopsByFile);

View File

@@ -11,6 +11,8 @@
#include "../Distribution/Distribution.h"
#include "../Utils/AstWrapper.h"
#include "../Utils/json.hpp"
#if __SPF
#include "../Utils/SgUtils.h"
#endif
@@ -235,35 +237,42 @@ public:
return retVal;
}
std::string toString()
nlohmann::json toJson()
{
std::string retVal = "";
nlohmann::json retVal;
retVal += "#" + std::to_string(regionId);
retVal += "#" + originalName;
retVal += "#" + std::to_string(lines.size());
retVal["packedRegionId"] = std::to_string(regionId);
retVal["originalName"] = originalName;
for (auto it = lines.begin(); it != lines.end(); ++it)
nlohmann::json arrays = nlohmann::json::array();
for (auto& array : allArrays.GetArrays())
arrays.push_back(array->toJson());
retVal["packedArrays"] = arrays;
nlohmann::json linesInfo = nlohmann::json::array();
for (auto& [file, linesByFile] : lines)
{
retVal += "|" + it->first + "|";
retVal += std::to_string(it->second.size());
for (int i = 0; i < it->second.size(); ++i)
retVal += "#" + std::to_string(it->second[i].lines.first) + "#" + std::to_string(it->second[i].lines.second);
nlohmann::json linesRegs;
nlohmann::json lines = nlohmann::json::array();
for (auto& elem : linesByFile)
{
JSON pair;
pair["key"] = elem.lines.first;
pair["value"] = elem.lines.second;
lines.push_back(pair);
}
linesRegs["file"] = file;
linesRegs["lines"] = lines;
linesInfo.push_back(linesRegs);
}
retVal["regionsLines"] = linesInfo;
const std::set<DIST::Array*> &arrays = allArrays.GetArrays();
retVal += "#" + std::to_string(arrays.size());
//create map<array_address, DIST::Array_toString()>
for (auto it = arrays.begin(); it != arrays.end(); ++it)
{
retVal += "#" + std::to_string((long long)(*it));
retVal += "#" + (*it)->toString();
}
retVal += "#" + std::to_string(dataDirectives.alignRules.size());
for (int i = 0; i < dataDirectives.alignRules.size(); ++i)
retVal += dataDirectives.alignRules[i].toString();
nlohmann::json alignRules = nlohmann::json::array();
for (auto& rule : dataDirectives.alignRules)
alignRules.push_back(rule.toJson());
retVal["alignRules"] = alignRules;
return retVal;
}

View File

@@ -14,13 +14,13 @@
#include "dvm.h"
#include "../DynamicAnalysis/gcov_info.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "PredictScheme.h"
#include "../Utils/SgUtils.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../Distribution/DvmhDirective.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../CFGraph/CFGraph.h"
@@ -208,27 +208,31 @@ void calculateStatsForPredictor(const map<string, vector<FuncInfo*>>& allFuncInf
uint64_t paralle_exec = 0;
uint64_t lines_count = 0;
if (st->variant() == DVM_PARALLEL_ON_DIR)
if (st->variant() == DVM_PARALLEL_ON_DIR)
{
auto loop = st->lexNext();
checkNull(loop, convertFileName(__FILE__).c_str(), __LINE__);
if (loop->variant() != FOR_NODE)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
calculateForParallelLoop(loop, gcov, paralle_exec, lines_count);
st = loop->lastNodeOfStmt();
if (__gcov_doesThisLineExecuted(byFile.first, loop->lineNumber()))
{
calculateForParallelLoop(loop, gcov, paralle_exec, lines_count);
st = loop->lastNodeOfStmt();
parallel_exec_count += paralle_exec;
count_of_parallel_lines += lines_count;
parallel_exec_count += paralle_exec;
count_of_parallel_lines += lines_count;
__spf_print(1, " PAR LOOP [%d %s] total exec %llu, total exec lines %llu, avg %.16e\n",
loop->lineNumber(), byFile.first.c_str(), paralle_exec, lines_count, paralle_exec / (double)lines_count);
__spf_print(1, " PAR LOOP [%d %s] total exec %llu, total exec lines %llu, avg %.16e\n",
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())
{
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;
int line = st->lineNumber();
@@ -428,6 +432,7 @@ static void parallelDir(const map<DIST::Array*, int>& byPos, SgExpression* spec,
parallel["loops_count"] = loopSymbs.size();
SgStatement* loop = isSgForStmt(st->lexNext());
if (loop == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* lastNode = loop->lastNodeOfStmt();
@@ -444,11 +449,13 @@ static void parallelDir(const map<DIST::Array*, int>& byPos, SgExpression* spec,
loop = loop->lexNext();
}
for (int z = execs.size() - 1; z > 0; --z)
execs[z] /= execs[z - 1];
for (int z = execs.size() - 1; z > 0; --z)
if (execs[z - 1] != 0)
execs[z] /= execs[z - 1];
auto& info = getInfo(before, gcov);
execs[0] /= info.getExecutedCount();
if (info.getExecutedCount() && loopSymbs.size() > 1)
execs[0] /= info.getExecutedCount();
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__);
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
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())
{
if (!__gcov_doesThisLineExecuted(byFile.first, st->lineNumber()))
continue;
SgExpression* list;
SgExpression* dup;
auto line = 0;
@@ -596,7 +604,10 @@ void parseDvmDirForPredictor(const map<tuple<int, string, string>, pair<DIST::Ar
switch (st->variant())
{
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;
case DVM_VAR_DECL: // TODO
{
@@ -615,7 +626,8 @@ void parseDvmDirForPredictor(const map<tuple<int, string, string>, pair<DIST::Ar
list = st->expr(0);
while (list)
{
directives["align"].push_back(parseAlign(byPos, list->lhs()->symbol(), type->rhs()->symbol(), type->lhs(), type->rhs()->lhs(), st->lineNumber()));
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()));
list = list->rhs();
}
}
@@ -627,6 +639,9 @@ void parseDvmDirForPredictor(const map<tuple<int, string, string>, pair<DIST::Ar
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()));
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:
//dirs << "1;" << "SHADOW;" << st->expr(0)->unparse() << "(" << st->expr(1)->unparse() << ");\n";
break;

View File

@@ -70,6 +70,8 @@
#include "VisualizerCalls/SendMessage.h"
#include "VisualizerCalls/BuildGraph.h"
#include "SwapOperators/swapOperators.h"
#include "Transformations/enddo_loop_converter.h"
#include "Transformations/loop_transform.h"
#include "Transformations/array_assign_to_loop.h"
@@ -331,9 +333,10 @@ 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,
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, false, true);
auto itI = filesToInclude.find(file_name);
for (auto& incl : itI->second)
if (allIncludeFiles.find(incl) != allIncludeFiles.end())
allIncludeFiles.erase(incl);
for (auto& [_, incls] : itI->second)
for (auto& incl : incls)
if (allIncludeFiles.find(incl) != allIncludeFiles.end())
allIncludeFiles.erase(incl);
}
else
{
@@ -827,20 +830,27 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{
auto fileIt = includeDependencies.find(file_name);
if (fileIt == includeDependencies.end())
fileIt = includeDependencies.insert(fileIt, make_pair(file_name, set<string>()));
fileIt = includeDependencies.insert(fileIt, make_pair(file_name, map<int, set<string>>()));
set<string> modFiles;
for (auto& elem : moduleDecls)
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();
else
{
if (first->variant() == MODULE_STMT && modFiles.find(first->fileName()) != modFiles.end())
first = first->lastNodeOfStmt();
if (strcmp(file_name, st->fileName()))
{
if (lastFromFile == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
fileIt->second[lastFromFile->lineNumber()].insert(st->fileName());
}
else
fileIt->second.insert(first->fileName());
lastFromFile = st;
}
}
@@ -938,6 +948,10 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
internalExit = err;
}
}
else if (curr_regime == SWAP_OPERATORS)
{
runSwapOperators(file, loopGraph, fullIR, countOfTransform);
}
else if (curr_regime == PRIVATE_REMOVING_ANALYSIS)
{
auto itFound = loopGraph.find(file->filename());
@@ -1034,7 +1048,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
PRIVATE_REMOVING,
PRIVATE_ARRAYS_EXPANSION,
PRIVATE_ARRAYS_SHRINKING,
REMOVE_DEAD_CODE };
REMOVE_DEAD_CODE,
SWAP_OPERATORS };
if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end())
{
@@ -1561,6 +1576,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{
if (keepFiles)
printLoopGraph("_loopGraph.txt", loopGraph);
//printf("%s\n", convertToJson(loopGraph).dump(2).c_str());
}
else if (curr_regime == FILL_COMMON_BLOCKS)
{
@@ -1595,12 +1611,15 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
set<string> includedToThisFile;
if (itDep != includeDependencies.end())
{
for (auto &inclDep : itDep->second)
for (auto& [_, incls] : itDep->second)
{
auto comm = commentsToInclude.find(inclDep);
if (comm != commentsToInclude.end())
for (auto &allComm : comm->second)
includedToThisFile.insert(allComm.second.begin(), allComm.second.end());
for (auto& incl : incls)
{
auto comm = commentsToInclude.find(incl);
if (comm != commentsToInclude.end())
for (auto& allComm : comm->second)
includedToThisFile.insert(allComm.second.begin(), allComm.second.end());
}
}
}
@@ -2325,6 +2344,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case INSERT_NO_DISTR_FLAGS_FROM_GUI:
case PRIVATE_REMOVING:
case RENAME_INLCUDES:
case SWAP_OPERATORS:
runAnalysis(*project, curr_regime, true, "", folderName);
break;
case INLINE_PROCEDURES:

View File

@@ -122,6 +122,8 @@ enum passes {
CREATE_INTER_TREE,
INSERT_INTER_TREE,
SWAP_OPERATORS,
SHADOW_GROUPING,
INLINE_PROCEDURES,
FILL_PARALLEL_REG_IR,
@@ -315,6 +317,7 @@ static void setPassValues()
passNames[CHECK_PAR_REG_DIR] = "CHECK_PAR_REG_DIR";
passNames[CREATE_INTER_TREE] = "CREATE_INTER_TREE";
passNames[INSERT_INTER_TREE] = "INSERT_INTER_TREE";
passNames[SWAP_OPERATORS] = "SWAP_OPERATORS";
passNames[CREATE_PARALLEL_REGIONS] = "CREATE_PARALLEL_REGIONS";
passNames[PRIVATE_REMOVING_ANALYSIS] = "PRIVATE_REMOVING_ANALYSIS";
passNames[PRIVATE_REMOVING] = "PRIVATE_REMOVING";

View File

@@ -85,7 +85,7 @@ std::map<std::string, std::map<int, std::set<std::string>>> commentsToInclude;
//
//for INSERT_INCLUDES
std::map<std::string, std::set<std::string>> filesToInclude; // file -> includes
std::map<std::string, std::map<int, std::set<std::string>>> filesToInclude; // file -> includes [nearest line, include]
//
//for PASSES DEPENDENSIES
@@ -96,7 +96,7 @@ std::set<passes> passesIgnoreStateDone;
//for files info
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::set<std::string>> includeDependencies; // file -> includes
std::map<std::string, std::map<int, std::set<std::string>>> includeDependencies; // file -> includes [nearest line, include]
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
//

View File

@@ -0,0 +1,353 @@
#include <map>
#include <unordered_set>
#include <vector>
#include <queue>
#include <iostream>
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "../GraphCall/graph_calls.h"
#include "../GraphCall/graph_calls_func.h"
#include "../CFGraph/CFGraph.h"
#include "../CFGraph/IR.h"
#include "../GraphLoop/graph_loops.h"
#include "swapOperators.h"
using namespace std;
unordered_set<int> loop_tags = {FOR_NODE/*, FORALL_NODE, WHILE_NODE, DO_WHILE_NODE*/};
unordered_set<int> importantDepsTags = {FOR_NODE, IF_NODE};
unordered_set<int> importantUpdDepsTags = {ELSEIF_NODE};
unordered_set<int> importantEndTags = {CONTROL_END};
vector<SAPFOR::IR_Block*> findInstructionsFromOperator(SgStatement* st, vector<SAPFOR::BasicBlock*> Blocks)
{
vector<SAPFOR::IR_Block*> result;
string filename = st -> fileName();
for (auto& block: Blocks)
{
vector<SAPFOR::IR_Block*> instructionsInBlock = block -> getInstructions();
for (auto& instruction: instructionsInBlock)
{
SgStatement* curOperator = instruction -> getInstruction() -> getOperator();
if (curOperator -> lineNumber() == st -> lineNumber())
result.push_back(instruction);
}
}
return result;
}
vector<SAPFOR::BasicBlock*> findFuncBlocksByFuncStatement(SgStatement *st, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
{
vector<SAPFOR::BasicBlock*> result;
Statement* forSt = (Statement*)st;
for (auto& func: FullIR)
{
if (func.first -> funcPointer -> getCurrProcessFile() == forSt -> getCurrProcessFile()
&& func.first -> funcPointer -> lineNumber() == forSt -> lineNumber())
result = func.second;
}
return result;
}
map<SgForStmt*, vector<SAPFOR::BasicBlock*>> findAndAnalyzeLoops(SgStatement *st, vector<SAPFOR::BasicBlock*> blocks)
{
map<SgForStmt*, vector<SAPFOR::BasicBlock*>> result;
SgStatement *lastNode = st->lastNodeOfStmt();
while (st && st != lastNode)
{
if (loop_tags.find(st -> variant()) != loop_tags.end())
{
// part with find statements of loop
SgForStmt *forSt = (SgForStmt*)st;
SgStatement *loopBody = forSt -> body();
SgStatement *lastLoopNode = st->lastNodeOfStmt();
// part with find blocks and instructions of loops
unordered_set<int> blocks_nums;
while (loopBody && loopBody != lastLoopNode)
{
SAPFOR::IR_Block* IR = findInstructionsFromOperator(loopBody, blocks).front();
if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end())
{
result[forSt].push_back(IR -> getBasicBlock());
blocks_nums.insert(IR -> getBasicBlock() -> getNumber());
}
loopBody = loopBody -> lexNext();
}
std::sort(result[forSt].begin(), result[forSt].end());
}
st = st -> lexNext();
}
return result;
}
map<SgStatement*, set<SgStatement*>> AnalyzeLoopAndFindDeps(SgForStmt* forStatement, vector<SAPFOR::BasicBlock*> loopBlocks, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
{
map<SgStatement*, set<SgStatement*>> result;
for (SAPFOR::BasicBlock* bb: loopBlocks)
{
map<SAPFOR::Argument*, set<int>> blockReachingDefinitions = bb -> getRD_In();
vector<SAPFOR::IR_Block*> instructions = bb -> getInstructions();
for (SAPFOR::IR_Block* irBlock: instructions)
{
// TODO: Think about what to do with function calls and array references. Because there are also dependencies there that are not reflected in RD, but they must be taken into account
SAPFOR::Instruction* instr = irBlock -> getInstruction();
result[instr -> getOperator()];
// take Argument 1 and it's RD and push operators to final set
if (instr -> getArg1() != NULL)
{
SAPFOR::Argument* arg = instr -> getArg1();
set<int> prevInstructionsNumbers = blockReachingDefinitions[arg];
for (int i: prevInstructionsNumbers)
{
SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first;
if (foundInstruction != NULL)
{
SgStatement* prevOp = foundInstruction -> getOperator();
if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber()
&& prevOp -> lineNumber() > forStatement -> lineNumber())
result[instr -> getOperator()].insert(prevOp);
}
}
}
// take Argument 2 (if exists) and it's RD and push operators to final set
if (instr -> getArg2() != NULL)
{
SAPFOR::Argument* arg = instr -> getArg2();
set<int> prevInstructionsNumbers = blockReachingDefinitions[arg];
for (int i: prevInstructionsNumbers)
{
SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first;
if (foundInstruction != NULL)
{
SgStatement* prevOp = foundInstruction -> getOperator();
if (prevOp != forStatement && instr -> getOperator() != forStatement&& instr -> getOperator() -> lineNumber() > prevOp -> lineNumber()
&& prevOp -> lineNumber() > forStatement -> lineNumber())
result[instr -> getOperator()].insert(prevOp);
}
}
}
// update RD
if (instr -> getResult() != NULL)
blockReachingDefinitions[instr -> getResult()] = {instr -> getNumber()};
}
}
return result;
}
void buildAdditionalDeps(SgForStmt* forStatement, map<SgStatement*, set<SgStatement*>>& dependencies)
{
SgStatement* lastNode = forStatement->lastNodeOfStmt();
vector<SgStatement*> importantDeps;
SgStatement* st = (SgStatement*) forStatement;
st = st -> lexNext();
SgStatement* logIfOp = NULL;
while (st && st != lastNode)
{
if(importantDeps.size() != 0)
{
if (st != importantDeps.back())
{
dependencies[st].insert(importantDeps.back());
}
}
if (logIfOp != NULL)
{
dependencies[st].insert(logIfOp);
logIfOp = NULL;
}
if (st -> variant() == LOGIF_NODE)
{
logIfOp = st;
}
if (importantDepsTags.find(st -> variant()) != importantDepsTags.end())
{
importantDeps.push_back(st);
}
if (importantUpdDepsTags.find(st -> variant()) != importantUpdDepsTags.end())
{
importantDeps.pop_back();
importantDeps.push_back(st);
}
if (importantEndTags.find(st -> variant()) != importantEndTags.end())
{
if(importantDeps.size() != 0)
{
importantDeps.pop_back();
}
}
st = st -> lexNext();
}
}
struct ReadyOp {
SgStatement* stmt;
int degree;
size_t arrival;
ReadyOp(SgStatement* s, int d, size_t a): stmt(s), degree(d), arrival(a) {}
};
struct ReadyOpCompare {
bool operator()(const ReadyOp& a, const ReadyOp& b) const {
if (a.degree != b.degree)
return a.degree > b.degree;
else
return a.arrival > b.arrival;
}
};
vector<SgStatement*> scheduleOperations(const map<SgStatement*, set<SgStatement*>>& dependencies)
{
// get all statements
unordered_set<SgStatement*> allStmtsSet;
for (const auto& pair : dependencies)
{
allStmtsSet.insert(pair.first);
for (SgStatement* dep : pair.second)
{
allStmtsSet.insert(dep);
}
}
vector<SgStatement*> allStmts(allStmtsSet.begin(), allStmtsSet.end());
// count deps and build reversed graph
unordered_map<SgStatement*, vector<SgStatement*>> graph;
unordered_map<SgStatement*, int> inDegree;
unordered_map<SgStatement*, int> degree;
for (auto op : allStmts)
inDegree[op] = 0;
// find and remember initial dependencies
unordered_set<SgStatement*> dependentStmts;
for (const auto& pair : dependencies)
{
SgStatement* op = pair.first;
const auto& deps = pair.second;
degree[op] = deps.size();
inDegree[op] = deps.size();
if (!deps.empty())
dependentStmts.insert(op);
for (auto dep : deps)
graph[dep].push_back(op);
}
for (SgStatement* op : allStmts)
{
if (!degree.count(op))
{
degree[op] = 0;
}
}
// build queues
using PQ = priority_queue<ReadyOp, vector<ReadyOp>, ReadyOpCompare>;
PQ readyDependent;
queue<SgStatement*> readyIndependent;
size_t arrivalCounter = 0;
for (auto op : allStmts)
{
if (inDegree[op] == 0)
{
if (dependentStmts.count(op))
{
readyDependent.emplace(op, degree[op], arrivalCounter++);
}
else
{
readyIndependent.push(op);
}
}
}
// main sort algorythm
vector<SgStatement*> executionOrder;
while (!readyDependent.empty() || !readyIndependent.empty())
{
SgStatement* current = nullptr;
if (!readyDependent.empty())
{
current = readyDependent.top().stmt;
readyDependent.pop();
}
else
{
current = readyIndependent.front();
readyIndependent.pop();
}
executionOrder.push_back(current);
for (SgStatement* neighbor : graph[current])
{
inDegree[neighbor]--;
if (inDegree[neighbor] == 0) {
if (dependentStmts.count(neighbor))
{
readyDependent.emplace(neighbor, degree[neighbor], arrivalCounter++);
}
else
{
readyIndependent.push(neighbor);
}
}
}
}
return executionOrder;
}
void buildNewAST(SgStatement* loop, vector<SgStatement*>& newBody)
{
SgStatement* endDo = loop->lastNodeOfStmt();
SgStatement* st = loop;
int lineNum = loop -> lineNumber() + 1;
for (int i = 0; i < newBody.size(); i++)
{
st -> setLexNext(*newBody[i]);
st = st -> lexNext();
st -> setlineNumber(lineNum);
lineNum++;
}
st -> setLexNext(*endDo);
}
void runSwapOperators(SgFile *file, std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform)
{
std::cout << "SWAP_OPERATORS Pass" << std::endl; // to remove
countOfTransform += 1; // to remove
const int funcNum = file -> numberOfFunctions();
for (int i = 0; i < funcNum; ++i)
{
SgStatement *st = file -> functions(i);
vector<SAPFOR::BasicBlock*> blocks = findFuncBlocksByFuncStatement(st, FullIR);
map<SgForStmt*, vector<SAPFOR::BasicBlock*>> loopsMapping = findAndAnalyzeLoops(st, blocks);
for (pair<SgForStmt*, vector<SAPFOR::BasicBlock*>> loopForAnalyze: loopsMapping)
{
map<SgStatement*, set<SgStatement*>> dependencyGraph = AnalyzeLoopAndFindDeps(loopForAnalyze.first, loopForAnalyze.second, FullIR);
// TODO: Write a function that will go through the operators and update all dependencies so that there are no mix-ups and splits inside the semantic blocks (for if, do and may be some other cases)
buildAdditionalDeps(loopForAnalyze.first, dependencyGraph);
cout << endl;
int firstLine = loopForAnalyze.first -> lineNumber();
int lastLine = loopForAnalyze.first -> lastNodeOfStmt() -> lineNumber();
cout << "LOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES" << endl;
// for (auto &v: dependencyGraph) {
// cout << "OPERATOR: " << v.first -> lineNumber() << " " << v.first -> variant() << "\nDEPENDS ON:" << endl;
// if (v.second.size() != 0)
// for (auto vv: v.second)
// cout << vv -> lineNumber() << " ";
// cout << endl;
// }
vector<SgStatement*> new_order = scheduleOperations(dependencyGraph);
cout << "RESULT ORDER:" << endl;
for (auto v: new_order)
if (v -> lineNumber() > firstLine)
cout << v -> lineNumber() << endl;
buildNewAST(loopForAnalyze.first, new_order);
st = loopForAnalyze.first -> lexNext();
while (st != loopForAnalyze.first -> lastNodeOfStmt())
{
cout << st -> lineNumber() << " " << st -> sunparse() << endl;
st = st -> lexNext();
}
}
}
return;
};

View File

@@ -0,0 +1,6 @@
#pragma once
#include "../GraphLoop/graph_loops.h"
#include "../CFGraph/CFGraph.h"
void runSwapOperators(SgFile *file, std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform);

View File

@@ -212,6 +212,8 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE);
list({BUILD_IR, CALL_GRAPH2}) <= Pass(SWAP_OPERATORS);
list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS);
list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING);
@@ -309,6 +311,8 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
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({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);

22828
src/Utils/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -310,8 +310,17 @@ static void getModuleSymbols(SgStatement* func, set<SgSymbol*>& symbs)
SgSymbol* s = func->symbol()->next();
while (s)
{
if (IS_BY_USE(s) && s->scope() && s->scope()->symbol()->identifier() == currScope)
symbs.insert(s);
if (func->variant() == MODULE_STMT)
{
if (s->scope() && s->scope()->symbol() && s->scope()->symbol()->identifier())
if (s->scope()->symbol()->identifier() == currScope)
symbs.insert(s);
}
else
{
if (IS_BY_USE(s) && s->scope() && s->scope()->symbol()->identifier() == currScope)
symbs.insert(s);
}
s = s->next();
}
}
@@ -325,18 +334,18 @@ const set<SgSymbol*>& getModuleSymbols(SgStatement *func)
set<SgSymbol*> symbs;
getModuleSymbols(func, symbs);
//if function in contains
//if function or module in contains
auto cp = func->controlParent();
if (isSgProgHedrStmt(cp))
if (isSgProgHedrStmt(cp) || cp->variant() == MODULE_STMT)
getModuleSymbols(cp, symbs);
symbolsForFunc[func->symbol()->identifier()] = symbs;
return symbs;
}
SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const string& locName)
static void findSymbol(SgStatement* func, const string& varName, const string& locName,
map<string, SgSymbol*>& altNames)
{
map<string, SgSymbol*> altNames;
for (const auto& s : getModuleSymbols(func))
{
SgSymbol* orig = OriginalSymbol(s);
@@ -344,11 +353,22 @@ SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const stri
if (orig->identifier() == varName && orig->scope()->symbol()->identifier() == locName)
altNames[s->identifier()] = s;
}
}
SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const string& locName)
{
const string clearName = correctSymbolModuleName(varName);
map<string, SgSymbol*> altNames;
findSymbol(func, varName, locName, altNames);
if (altNames.size() == 0 && clearName != varName)
findSymbol(func, clearName, locName, altNames);
if (altNames.size() > 0)
return altNames.begin()->second;
else {
__spf_print(1, "%s %s %s\n", func->symbol()->identifier(), varName.c_str(), locName.c_str());
__spf_print(1, "%s (%s %s) %s\n", func->symbol()->identifier(), clearName.c_str(), varName.c_str(), locName.c_str());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
@@ -384,6 +404,15 @@ SgSymbol* getNameInLocation(SgSymbol* curr, SgStatement* location)
return returnVal;
}
string correctSymbolModuleName(const string& origFull)
{
auto it = origFull.find("::");
if (it == string::npos)
return origFull;
else
return origFull.substr(it + 2);
}
namespace Distribution
{
const string Array::GetNameInLocation(void* location_p) const

View File

@@ -1,5 +1,6 @@
#pragma once
std::string correctSymbolModuleName(const std::string& origFull);
const std::set<SgSymbol*>& getModuleSymbols(SgStatement* func);
void getModulesAndFunctions(SgFile* file, std::vector<SgStatement*>& modulesAndFunctions);
void findModulesInFile(SgFile* file, std::vector<SgStatement*>& modules);

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2401"
#define VERSION_SPF "2421"

View File

@@ -41,6 +41,7 @@
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../DirectiveProcessing/insert_directive.h"
#include "../ProjectManipulation/PerfAnalyzer.h"
#include "Utils/json.hpp"
#include "BuildGraph.h"
@@ -61,6 +62,7 @@ using std::pair;
using std::tuple;
using std::to_string;
using std::make_pair;
using json = nlohmann::json;
extern set<short*> allocated;
extern set<int*> allocatedInt;
@@ -510,26 +512,7 @@ int SPF_GetGraphLoops(void*& context, int winHandler, short *options, short *pro
{
runPassesForVisualizer(projName, { LOOP_GRAPH } );
string resVal = "";
for (auto f = loopGraph.begin(); f != loopGraph.end(); ++f)
{
if (resVal != "")
resVal += "|";
int realLoops = 0;
for (int i = 0; i < f->second.size(); ++i)
if (f->second[i]->lineNum > 0)
realLoops++;
resVal += f->first + "|" + to_string(realLoops);
for (int i = 0; i < f->second.size(); ++i)
{
string localRes = "";
convertToString(f->second[i], localRes);
resVal += localRes;
}
}
string resVal = convertToJson(loopGraph).dump();
copyStringToShort(result, resVal);
retSize = (int)resVal.size() + 1;
}
@@ -569,15 +552,7 @@ int SPF_GetGraphFunctions(void*& context, int winHandler, short *options, short
{
runPassesForVisualizer(projName, { FILL_PAR_REGIONS_LINES } );
string resVal = "";
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]);
}
string resVal = convertToJson(allFuncInfo).dump();
copyStringToShort(result, resVal);
retSize = (int)resVal.size() + 1;
}
@@ -666,12 +641,20 @@ int SPF_GetGraphFunctionPositions(void*& context, int winHandler, short *options
}
auto positions = buildLocationOfGraph(allFuncInfo, iters, coef, 0.9 * w, 0.9 * h, sendVisible ? &visible : NULL);
json pos_array= json::array();
for (auto& [fname, coords] : positions) {
json elem;
elem["functionName"] = fname;
elem["x"] = (double)coords.first;
elem["y"] = (double)coords.second;
pos_array.push_back(elem);
}
string resVal = "";
resVal = to_string(positions.size());
for (auto& elem : positions)
resVal += "|" + elem.first + "|" + to_string(elem.second.first) + "|" + to_string(elem.second.second);
json allPositions;
allPositions["allPositions"] = pos_array;
string resVal = allPositions.dump();
copyStringToShort(result, resVal);
retSize = (int)resVal.size() + 1;
}
@@ -697,61 +680,6 @@ int SPF_GetGraphFunctionPositions(void*& context, int winHandler, short *options
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 *ALGORITHMS_DONE[EMPTY_ALGO];
extern const char *passNames[EMPTY_PASS + 1];
@@ -838,15 +766,17 @@ int SPF_GetArrayDistribution(void*& context, int winHandler, short *options, sho
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
string resVal = "";
resVal += to_string(parallelRegions.size());
for (int i = 0; i < parallelRegions.size(); ++i)
resVal += parallelRegions[i]->toString();
json regions = json::array();
for (auto& reg : parallelRegions)
{
json currReg = reg->toJson();
regions.push_back(currReg);
}
//__spf_print(1, "==============\n");
//__spf_print(1, "%s\n", resVal.c_str());
//__spf_print(1, "==============\n");
json allRegions;
allRegions["allRegions"] = regions;
string resVal = allRegions.dump();
copyStringToShort(result, resVal);
retSize = (int)resVal.size() + 1;
}
@@ -1228,8 +1158,6 @@ int SPF_GetArrayLinks(void*& context, int winHandler, short *options, short *pro
{
runPassesForVisualizer(projName, { CALL_GRAPH2 } );
string resVal = "";
map<DIST::Array*, set<DIST::Array*>> linkedArrays;
for (auto& inMap : arrayLinksByFuncCalls)
{
@@ -1243,17 +1171,24 @@ int SPF_GetArrayLinks(void*& context, int winHandler, short *options, short *pro
linkedArrays[ref].insert(toAdd);
}
json allLinks = json::array();
for (auto& array : linkedArrays)
{
resVal += to_string(array.first->GetId()) + "|" + to_string(array.second.size()) + "|";
json currLink;
currLink["id"] = array.first->GetId();
json links = json::array();
for (auto& link : array.second)
resVal += to_string(link->GetId()) + "|";
links.push_back(link->GetId());
currLink["links"] = links;
allLinks.push_back(currLink);
}
if (resVal[resVal.size() - 1] == '|')
resVal.erase(resVal.size() - 1);
json links;
links["allLinks"] = allLinks;
string resVal = links.dump();
copyStringToShort(result, resVal);
retSize = (int)resVal.size() + 1;
}
@@ -1380,13 +1315,12 @@ int SPF_GetIntrinsics(void*& context, short *&result)
return (int)resVal.size() + 1;
}
extern map<string, set<string>> includeDependencies;
extern map<string, map<int, set<string>>> includeDependencies;
int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, short *projName, short *&result, short*& output, int*& outputSize,
short*& outputMessage, int*& outputMessageSize)
{
MessageManager::clearCache();
MessageManager::setWinHandler(winHandler);
string resVal = "";
setOptions(options);
int retSize = 0;
@@ -1394,23 +1328,31 @@ int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, s
{
runPassesForVisualizer(projName, { BUILD_INCLUDE_DEPENDENCIES });
int i = 0;
for (auto &deps : includeDependencies)
json inc_array = json::array();
for (const auto& deps : includeDependencies)
{
if (i != 0)
resVal += "@";
resVal += deps.first + "@";
int k = 0;
for (auto &incl : deps.second)
json includes;
includes["file"] = deps.first;
json array = json::array();
for (const auto& [line, incls] : deps.second)
{
if (k != 0)
resVal += "|";
resVal += incl;
++k;
for (auto& incl : incls)
{
json elem;
elem["line"] = line;
elem["dependencyFileName"] = incl;
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);
retSize = (int)resVal.size() + 1;
}
@@ -1446,15 +1388,7 @@ int SPF_SetFunctionsToInclude(void*& context, int winHandler, short *options, sh
{
runPassesForVisualizer(projName, { FIND_FUNC_TO_INCLUDE });
string resVal = "";
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]);
}
string resVal = convertToJson(allFuncInfo).dump();
copyStringToShort(result, resVal);
retSize = (int)resVal.size() + 1;
}
@@ -1492,14 +1426,17 @@ int SPF_GetAllDeclaratedArrays(void*& context, int winHandler, short *options, s
{
runPassesForVisualizer(projName, { GET_ALL_ARRAY_DECL });
string resVal = "";
for (auto f = declaredArrays.begin(); f != declaredArrays.end(); ++f)
json arrays = json::array();
for (const auto& [_, array] : declaredArrays)
{
if (f != declaredArrays.begin())
resVal += "@";
resVal += f->second.first->toString();
json jArray = array.first->toJson();
arrays.push_back(jArray);
}
json allArrays;
allArrays["allArrays"] = arrays;
string resVal = allArrays.dump();
copyStringToShort(result, resVal);
retSize = (int)resVal.size() + 1;
}
@@ -1540,19 +1477,33 @@ int SPF_GetFileLineInfo(void*& context, int winHandler, short *options, short *p
{
runPassesForVisualizer(projName, { FILE_LINE_INFO });
string resVal = "";
for (auto it = lineInfo.begin(); it != lineInfo.end(); ++it)
json metric_array = json::array();
for (const auto& fileInfo : lineInfo)
{
if (it != lineInfo.begin())
resVal += "@";
json fileMetric;
auto itD = dirsInfo.find(it->first);
if (itD == dirsInfo.end())
resVal += it->first + "@" + to_string(it->second) + "_0_0";
fileMetric["file"] = fileInfo.first;
fileMetric["linesCount"] = fileInfo.second;
auto it = dirsInfo.find(fileInfo.first);
if (it == dirsInfo.end())
{
fileMetric["numSPF"] = 0;
fileMetric["numDVM"] = 0;
}
else
resVal += it->first + "@" + to_string(it->second) + "_" + to_string(itD->second.first.size()) + "_" + to_string(itD->second.second.size());
{
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);
retSize = (int)resVal.size() + 1;
}
@@ -2251,38 +2202,43 @@ int SPF_InlineProcedures(void*& context, int winHandler, short* options, short*
}
extern map<string, set<string>> filesToInclude;
int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *filesToInclude,
extern map<string, map<int, set<string>>> filesToInclude;
int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *visFilesToInclude,
short *&output, int *&outputSize, short *&outputMessage, int *&outputMessageSize)
{
MessageManager::clearCache();
MessageManager::setWinHandler(winHandler);
if (filesToInclude == NULL)
if (visFilesToInclude == NULL)
return -2;
vector<string> splited;
//printf("%s\n", conv);
splitString(filesToInclude, '|', splited);
splitString(visFilesToInclude, '|', splited);
if (splited.size() == 0)
return -3;
::filesToInclude.clear();
for (int i = 0; i < splited.size(); ++i)
filesToInclude.clear();
unsigned i = 0;
while (i < splited.size())
{
string file = splited[i];
string file = splited[i++];
int num = 0;
if (sscanf(splited[i + 1].c_str(), "%d", &num) == -1)
return -3;
if (sscanf(splited[i++].c_str(), "%d", &num) == -1)
return -4;
__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]);
__spf_print(1, " include = %s\n", splited[k].c_str());
int line = 0;
if (sscanf(splited[k].c_str(), "%d", &line) == -1)
return -5;
filesToInclude[file][line].insert(splited[k + 1]);
__spf_print(1, " include = [%d %s]\n", line, splited[k + 1].c_str());
}
i += 1 + num;
i += 2 * num;
}
return simpleTransformPass(INSERT_INCLUDES, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
}
@@ -2309,18 +2265,30 @@ int SPF_GetGCovInfo(void*& context, int winHandler, short *options, short *projN
{
runPassesForVisualizer(projName, { GCOV_PARSER });
string resVal = "";
bool first = true;
for (auto &byFile : gCovInfo)
json gcov_array = json::array();
for (auto& byFile : gCovInfo)
{
if (!first)
resVal += "@";
resVal += byFile.first + "@";
for (auto &elem : byFile.second)
resVal += to_string(elem.first) + " " + to_string(elem.second.getExecutedCount()) + " ";
first = false;
json fileGCov;
fileGCov["file"] = byFile.first;
json info_array = json::array();
for (auto& elem : byFile.second)
{
json item;
item["line"] = elem.first;
item["execution"] = elem.second.getExecutedCount();
info_array.push_back(item);
}
fileGCov["lines"] = info_array;
gcov_array.push_back(fileGCov);
}
json allGCov;
allGCov["allGCov"] = gcov_array;
string resVal = allGCov.dump();
copyStringToShort(result, resVal);
retSize = (int)resVal.size();
}
@@ -2496,8 +2464,6 @@ const wstring Sapfor_RunAnalysis(const char* analysisName_c, const char* options
retCode = SPF_GetGraphFunctions(context, winHandler, optSh, projSh, result, output, outputSize, outputMessage, outputMessageSize);
else if (whichRun == "SPF_GetGraphFunctionPositions")
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")
retCode = SPF_GetArrayDistribution(context, winHandler, optSh, projSh, result, output, outputSize, outputMessage, outputMessageSize, 0);
else if (whichRun == "SPF_GetArrayDistributionOnlyAnalysis")