diff --git a/src/Predictor/PredictSchemeWithLibrary.cpp b/src/Predictor/PredictSchemeWithLibrary.cpp index cc9929b..ff39245 100644 --- a/src/Predictor/PredictSchemeWithLibrary.cpp +++ b/src/Predictor/PredictSchemeWithLibrary.cpp @@ -17,16 +17,16 @@ #include "../Utils/utils.h" using std::map; -using std::string; -using std::vector; using std::pair; +using std::string; using std::tuple; +using std::vector; -map createTemplateIdMapping(const vector ¶llelRegions) +map createTemplateIdMapping(const vector& parallelRegions) { size_t maxArrayId = 0; for (int z = 0; z < parallelRegions.size(); ++z) { - const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); + const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); for (const auto& distrRule : dataDirectives.distrRules) { if (distrRule.first && !distrRule.first->IsTemplate()) { @@ -44,7 +44,7 @@ map createTemplateIdMapping(const vector ¶l map templateIdMapping; size_t nextTemplateId = maxArrayId + 1; for (int z = 0; z < parallelRegions.size(); ++z) { - const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); + const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); for (const auto& distrRule : dataDirectives.distrRules) { if (distrRule.first && distrRule.first->IsTemplate()) { @@ -64,43 +64,29 @@ map createTemplateIdMapping(const vector ¶l } } } - + return templateIdMapping; } -// TODO: вычислять директивы разово заранее -double runLibpredictCalc(SgProject &project, - const vector& topology, - const string& clusterConfStr, - const vector ¶llelRegions, - map>& loopGraph, - map> &SPF_messages, - const map &templateIdMapping) +PrecomputedLibpredictParams precomputeLibpredictParams( + SgProject& project, + const vector& parallelRegions, + const map>& loopGraph, + const map& templateIdMapping) { - libpredict::RetInitGrid retInitGrid = libpredict::InitGrid(topology[0], topology[1], topology[2], topology[3]); - - if (retInitGrid != libpredict::INIT_GRID_SUCCESS) { - __spf_print(1, "ERROR: Failed to initialize libpredict grid with topology: %zu %zu %zu %zu, return code: %d\n", - topology[0], topology[1], topology[2], topology[3], (int)retInitGrid); - - std::wstring messageR, messageE; - __spf_printToLongBuf(messageE, L"Failed to initialize libpredict grid with topology: %zu %zu %zu %zu, return code: %d", - topology[0], topology[1], topology[2], topology[3], (int)retInitGrid); - __spf_printToLongBuf(messageR, R207); - getObjectForFileFromMap(clusterConfStr.c_str(), SPF_messages).push_back(Messages(ERROR, 1, messageR, messageE, 1064)); - return -1; - } + PrecomputedLibpredictParams result; // distribute and align from parallelRegions for (int z = 0; z < parallelRegions.size(); ++z) { - const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); - const vector ¤tVariant = parallelRegions[z]->GetCurrentVariant(); - const DIST::Arrays &allArrays = parallelRegions[z]->GetAllArrays(); + const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); + const vector& currentVariant = parallelRegions[z]->GetCurrentVariant(); + const DIST::Arrays& allArrays = parallelRegions[z]->GetAllArrays(); - auto &tmp = dataDirectives.distrRules; + auto& tmp = dataDirectives.distrRules; vector> currentVar; - for (int z1 = 0; z1 < currentVariant.size(); ++z1) + for (int z1 = 0; z1 < currentVariant.size(); ++z1) { currentVar.push_back(std::make_pair(tmp[z1].first, &tmp[z1].second[currentVariant[z1]])); + } // distribute for (const auto& distrRule : currentVar) { @@ -108,51 +94,40 @@ double runLibpredictCalc(SgProject &project, const DistrVariant* variant = distrRule.second; if (array && variant && !array->IsNotDistribute()) { + PrecomputedDistributeParams params; + size_t originalId = array->GetId(); - size_t arrayId = originalId; + params.arrayId = originalId; if (array->IsTemplate()) { auto it = templateIdMapping.find(originalId); if (it != templateIdMapping.end()) { - arrayId = it->second; + params.arrayId = it->second; } } - size_t elemSize = array->GetTypeSize(); + params.elemSize = array->GetTypeSize(); + params.array = array; - vector axisDistributions; const auto& arraySizes = array->GetSizes(); for (int dim = 0; dim < array->GetDimSize(); ++dim) { size_t dimSize = arraySizes[dim].second - arraySizes[dim].first + 1; if (dim < variant->distRule.size() && variant->distRule[dim] == dist::BLOCK) { - axisDistributions.emplace_back(dimSize, libpredict::TypeDistribute::BLOCK); + params.axisDistributions.emplace_back(dimSize, libpredict::TypeDistribute::BLOCK); } else { - axisDistributions.emplace_back(dimSize, libpredict::TypeDistribute::NONE); + params.axisDistributions.emplace_back(dimSize, libpredict::TypeDistribute::NONE); } } - vector> shadowEdges; const auto& shadowSpec = array->GetShadowSpec(); for (int dim = 0; dim < shadowSpec.size() && dim < array->GetDimSize(); ++dim) { if (dim < variant->distRule.size() && variant->distRule[dim] == dist::BLOCK) { - shadowEdges.emplace_back(shadowSpec[dim].first, shadowSpec[dim].second); + params.shadowEdges.emplace_back(shadowSpec[dim].first, shadowSpec[dim].second); } } - libpredict::RetDistribute retDistribute = libpredict::Distribute(arrayId, elemSize, axisDistributions, shadowEdges); - - if (retDistribute != libpredict::DISTRIBUTE_SUCCESS) { - __spf_print(1, "ERROR: Failed to distribute array '%s' (id=%zu) with libpredict, return code: %d\n", - array->GetShortName().c_str(), arrayId, (int)retDistribute); - - std::wstring messageR, messageE; - __spf_printToLongBuf(messageE, L"Failed to distribute array '%s' with libpredict, return code: %d", - to_wstring(array->GetShortName()).c_str(), (int)retDistribute); - __spf_printToLongBuf(messageR, R208); - getObjectForFileFromMap(array->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back( - Messages(ERROR, array->GetDeclInfo().begin()->second, messageR, messageE, 1065)); - } + result.distributeParams.push_back(params); } } @@ -162,27 +137,29 @@ double runLibpredictCalc(SgProject &project, DIST::Array* alignWithArray = alignRule.alignWith; if (alignArray && alignWithArray && !alignArray->IsNotDistribute()) { - size_t arrayId = alignArray->GetId(); + PrecomputedAlignParams params; + + params.arrayId = alignArray->GetId(); size_t originalDistributedArrayId = alignWithArray->GetId(); - size_t distributedArrayId = originalDistributedArrayId; + params.distributedArrayId = originalDistributedArrayId; if (alignWithArray->IsTemplate()) { auto it = templateIdMapping.find(originalDistributedArrayId); if (it != templateIdMapping.end()) { - distributedArrayId = it->second; + params.distributedArrayId = it->second; } } - size_t elemSize = alignArray->GetTypeSize(); + params.elemSize = alignArray->GetTypeSize(); + params.alignArray = alignArray; + params.alignWithArray = alignWithArray; const auto& arraySizes = alignArray->GetSizes(); - vector dimensions; for (int dim = 0; dim < alignArray->GetDimSize(); ++dim) { size_t dimSize = arraySizes[dim].second - arraySizes[dim].first + 1; - dimensions.push_back(dimSize); + params.dimensions.push_back(dimSize); } - vector distributionExpressions; for (int dim = 0; dim < alignWithArray->GetDimSize(); ++dim) { bool found = false; for (int i = 0; i < alignRule.alignRuleWith.size(); ++i) { @@ -190,51 +167,39 @@ double runLibpredictCalc(SgProject &project, if (ruleWith.first == dim) { const auto& rule = ruleWith.second; if (rule.first == 0) { - // Константа - distributionExpressions.emplace_back(rule.second); + // constant + params.distributionExpressions.emplace_back(rule.second); } else { - // Линейное выражение a * I + b - distributionExpressions.emplace_back(i, rule.first, rule.second); + // linear expression a * I + b + params.distributionExpressions.emplace_back(i, rule.first, rule.second); } found = true; break; } } if (!found) { - // Нет правила для этого измерения - distributionExpressions.emplace_back(); + // There is no rule for this measurement + params.distributionExpressions.emplace_back(); } } - vector> shadowEdges; const auto& shadowSpec = alignArray->GetShadowSpec(); for (int dim = 0; dim < shadowSpec.size() && dim < alignArray->GetDimSize(); ++dim) { - shadowEdges.emplace_back(shadowSpec[dim].first, shadowSpec[dim].second); + params.shadowEdges.emplace_back(shadowSpec[dim].first, shadowSpec[dim].second); } - libpredict::RetAlign retAlign = libpredict::Align(arrayId, distributedArrayId, elemSize, dimensions, distributionExpressions, shadowEdges); - - if (retAlign != libpredict::ALIGN_SUCCESS) { - __spf_print(1, "ERROR: Failed to align array '%s' (id=%zu) with array '%s' (id=%zu), return code: %d\n", - alignArray->GetShortName().c_str(), arrayId, - alignWithArray->GetShortName().c_str(), distributedArrayId, (int)retAlign); - - std::wstring messageR, messageE; - __spf_printToLongBuf(messageE, L"Failed to align array '%s' with array '%s' using libpredict, return code: %d", - to_wstring(alignArray->GetShortName()).c_str(), - to_wstring(alignWithArray->GetShortName()).c_str(), (int)retAlign); - __spf_printToLongBuf(messageR, R209); - getObjectForFileFromMap(alignArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back( - Messages(ERROR, alignArray->GetDeclInfo().begin()->second, messageR, messageE, 1066)); - } + result.alignParams.push_back(params); } } // shadow_renew map parallelDirs; for (int i = project.numberOfFiles() - 1; i >= 0; --i) { - SgFile *file = &(project.file(i)); - auto fountInfo = findAllDirectives(file, getObjectForFileFromMap(file->filename(), loopGraph), parallelRegions[z]->GetId()); + SgFile* file = &(project.file(i)); + auto fountInfo = findAllDirectives( + file, + getObjectForFileFromMap(file->filename(), const_cast>&>(loopGraph)), + parallelRegions[z]->GetId()); parallelDirs.insert(fountInfo.begin(), fountInfo.end()); } @@ -249,65 +214,135 @@ double runLibpredictCalc(SgProject &project, const vector>& bounds = shadowRenewItem.second; DIST::Array* shadowArray = allArrays.GetArrayByName(arrayName); - if (shadowArray == NULL) + if (shadowArray == NULL) { continue; + } if (shadowArray && !shadowArray->IsNotDistribute()) { - size_t arrayId = shadowArray->GetId(); + PrecomputedShadowRenewParams params; + + params.arrayId = shadowArray->GetId(); + params.shadowArray = shadowArray; - vector> shadow_renew; for (const auto& bound : bounds) { - shadow_renew.emplace_back(static_cast(bound.first), - static_cast(bound.second)); + params.shadow_renew.emplace_back(static_cast(bound.first), + static_cast(bound.second)); } - bool corner = directive->shadowRenewCorner[shadowIdx]; - size_t number_loop_iterations = loopPtr ? static_cast(loopPtr->countOfIters) : 1; + params.corner = directive->shadowRenewCorner[shadowIdx]; + params.number_loop_iterations = loopPtr ? static_cast(loopPtr->countOfIters) : 1; - libpredict::RetShadowRenew retShadowRenew = libpredict::ShadowRenew(arrayId, shadow_renew, corner, number_loop_iterations); - - if (retShadowRenew != libpredict::SHADOW_RENEW_SUCCESS) { - __spf_print(1, "ERROR: Failed to process shadow_renew for array '%s' (id=%zu), return code: %d\n", - shadowArray->GetShortName().c_str(), arrayId, (int)retShadowRenew); - - std::wstring messageR, messageE; - __spf_printToLongBuf(messageE, L"Failed to process shadow_renew for array '%s' with libpredict, return code: %d", - to_wstring(shadowArray->GetShortName()).c_str(), (int)retShadowRenew); - __spf_printToLongBuf(messageR, R210); - getObjectForFileFromMap(shadowArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back( - Messages(ERROR, shadowArray->GetDeclInfo().begin()->second, messageR, messageE, 1067)); - } + result.shadowRenewParams.push_back(params); } } } } } + return result; +} + +double runLibpredictCalc(const vector& topology, + const string& clusterConfStr, + const PrecomputedLibpredictParams& precomputedParams, + map>& SPF_messages) +{ + libpredict::RetInitGrid retInitGrid = libpredict::InitGrid(topology[0], topology[1], topology[2], topology[3]); + + if (retInitGrid != libpredict::INIT_GRID_SUCCESS) { + __spf_print(1, "ERROR: Failed to initialize libpredict grid with topology: %zu %zu %zu %zu, return code: %d\n", + topology[0], topology[1], topology[2], topology[3], (int)retInitGrid); + + std::wstring messageR, messageE; + __spf_printToLongBuf(messageE, L"Failed to initialize libpredict grid with topology: %zu %zu %zu %zu, return code: %d", + topology[0], topology[1], topology[2], topology[3], (int)retInitGrid); + __spf_printToLongBuf(messageR, R207); + getObjectForFileFromMap(clusterConfStr.c_str(), SPF_messages).push_back(Messages(ERROR, 1, messageR, messageE, 1064)); + return -1; + } + + // distribute + for (const auto& params : precomputedParams.distributeParams) { + libpredict::RetDistribute retDistribute = libpredict::Distribute( + params.arrayId, params.elemSize, params.axisDistributions, params.shadowEdges); + + if (retDistribute != libpredict::DISTRIBUTE_SUCCESS) { + __spf_print(1, "ERROR: Failed to distribute array '%s' (id=%zu) with libpredict, return code: %d\n", + params.array->GetShortName().c_str(), params.arrayId, (int)retDistribute); + + std::wstring messageR, messageE; + __spf_printToLongBuf(messageE, L"Failed to distribute array '%s' with libpredict, return code: %d", + to_wstring(params.array->GetShortName()).c_str(), (int)retDistribute); + __spf_printToLongBuf(messageR, R208); + getObjectForFileFromMap(params.array->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back(Messages(ERROR, params.array->GetDeclInfo().begin()->second, messageR, messageE, 1065)); + } + } + + // align + for (const auto& params : precomputedParams.alignParams) { + libpredict::RetAlign retAlign = libpredict::Align( + params.arrayId, params.distributedArrayId, params.elemSize, + params.dimensions, params.distributionExpressions, params.shadowEdges); + + if (retAlign != libpredict::ALIGN_SUCCESS) { + __spf_print(1, "ERROR: Failed to align array '%s' (id=%zu) with array '%s' (id=%zu), return code: %d\n", + params.alignArray->GetShortName().c_str(), params.arrayId, + params.alignWithArray->GetShortName().c_str(), params.distributedArrayId, (int)retAlign); + + std::wstring messageR, messageE; + __spf_printToLongBuf(messageE, L"Failed to align array '%s' with array '%s' using libpredict, return code: %d", + to_wstring(params.alignArray->GetShortName()).c_str(), + to_wstring(params.alignWithArray->GetShortName()).c_str(), (int)retAlign); + __spf_printToLongBuf(messageR, R209); + getObjectForFileFromMap(params.alignArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back(Messages(ERROR, params.alignArray->GetDeclInfo().begin()->second, messageR, messageE, 1066)); + } + } + + // shadow_renew + for (const auto& params : precomputedParams.shadowRenewParams) { + libpredict::RetShadowRenew retShadowRenew = libpredict::ShadowRenew( + params.arrayId, params.shadow_renew, params.corner, params.number_loop_iterations); + + if (retShadowRenew != libpredict::SHADOW_RENEW_SUCCESS) { + __spf_print(1, "ERROR: Failed to process shadow_renew for array '%s' (id=%zu), return code: %d\n", + params.shadowArray->GetShortName().c_str(), params.arrayId, (int)retShadowRenew); + + std::wstring messageR, messageE; + __spf_printToLongBuf(messageE, L"Failed to process shadow_renew for array '%s' with libpredict, return code: %d", + to_wstring(params.shadowArray->GetShortName()).c_str(), (int)retShadowRenew); + __spf_printToLongBuf(messageR, R210); + getObjectForFileFromMap(params.shadowArray->GetDeclInfo().begin()->first.c_str(), SPF_messages).push_back(Messages(ERROR, params.shadowArray->GetDeclInfo().begin()->second, messageR, messageE, 1067)); + } + } + return libpredict::GetTime(); } -void runPredictScheme(SgProject &project, - vector> &topologies, - const vector ¶llelRegions, +void runPredictScheme(SgProject& project, + vector>& topologies, + const vector& parallelRegions, map>& loopGraph, - map> &SPF_messages) + map>& SPF_messages) { // calculating maximum dimension of distribution int maxSizeDist = 0; for (int z = 0; z < parallelRegions.size(); ++z) { - const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir(); - const vector ¤tVariant = parallelRegions[z]->GetCurrentVariant(); + const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); + const vector& currentVariant = parallelRegions[z]->GetCurrentVariant(); - auto &tmp = dataDirectives.distrRules; + auto& tmp = dataDirectives.distrRules; vector currentVar; - for (int z1 = 0; z1 < currentVariant.size(); ++z1) + for (int z1 = 0; z1 < currentVariant.size(); ++z1) { currentVar.push_back(&tmp[z1].second[currentVariant[z1]]); + } for (auto var : currentVar) { int countBlock = 0; - for (int z = 0; z < var->distRule.size(); ++z) - if (var->distRule[z] == dist::BLOCK) + for (int z = 0; z < var->distRule.size(); ++z) { + if (var->distRule[z] == dist::BLOCK) { ++countBlock; + } + } maxSizeDist = std::max(maxSizeDist, countBlock); } } @@ -324,11 +359,16 @@ void runPredictScheme(SgProject &project, // creating template ID display to avoid conflicts map templateIdMapping = createTemplateIdMapping(parallelRegions); + // Precomputing parameters of directive functions from libpredict + PrecomputedLibpredictParams precomputedParams = precomputeLibpredictParams( + project, parallelRegions, loopGraph, templateIdMapping); + // iterating through topologies to find most optimal one topologies = vector>(); if (maxSizeDist) { - - if (maxSizeDist > 4) maxSizeDist = 4; + if (maxSizeDist > 4) { + maxSizeDist = 4; + } // Initialize cluster int procCount = 0; @@ -336,7 +376,7 @@ void runPredictScheme(SgProject &project, if (retInitCluster != libpredict::INIT_CLUSTER_SUCCESS) { __spf_print(1, "ERROR: Failed to initialize libpredict cluster with config: %s, return code: %d\n", clusterConfStr.c_str(), (int)retInitCluster); - + std::wstring messageR, messageE; __spf_printToLongBuf(messageE, L"Failed to initialize libpredict cluster with config: %s, return code: %d", to_wstring(clusterConfStr).c_str(), (int)retInitCluster); @@ -347,13 +387,19 @@ void runPredictScheme(SgProject &project, for (size_t n1 = 2; n1 <= procCount; ++n1) { for (size_t n2 = 1; n2 <= n1 && n1 * n2 <= procCount; ++n2) { - if (n2 != 1 && maxSizeDist < 2 || n2 == 1 && maxSizeDist == 2) continue; - + if (n2 != 1 && maxSizeDist < 2 || n2 == 1 && maxSizeDist == 2) { + continue; + } + for (size_t n3 = 1; n3 <= n2 && n1 * n2 * n3 <= procCount; ++n3) { - if (n3 != 1 && maxSizeDist < 3 || n3 == 1 && maxSizeDist == 3) continue; + if (n3 != 1 && maxSizeDist < 3 || n3 == 1 && maxSizeDist == 3) { + continue; + } for (size_t n4 = 1; n4 <= n3 && n1 * n2 * n3 * n4 <= procCount; ++n4) { - if (n4 != 1 && maxSizeDist < 4 || n4 == 1 && maxSizeDist == 4) continue; + if (n4 != 1 && maxSizeDist < 4 || n4 == 1 && maxSizeDist == 4) { + continue; + } topologies.push_back(vector{n1, n2, n3, n4}); } @@ -363,25 +409,28 @@ void runPredictScheme(SgProject &project, vector best; double bestTime = std::numeric_limits::max(); - for (auto &topology : topologies) { - double currTime = runLibpredictCalc(project, topology, clusterConfStr, parallelRegions, loopGraph, SPF_messages, templateIdMapping); + for (auto& topology : topologies) { + double currTime = runLibpredictCalc(topology, clusterConfStr, precomputedParams, SPF_messages); string outStr = ""; - for (const auto &elem : topology) + for (const auto& elem : topology) { outStr += std::to_string(elem) + " "; + } __spf_print(1, "topology %s has time %f\n", outStr.c_str(), currTime); - if (currTime == -1) + if (currTime == -1) { return; - + } + if (currTime < bestTime) { bestTime = currTime; best = topology; } } string outStr; - for (const auto &elem : best) + for (const auto& elem : best) { outStr += std::to_string(elem) + " "; + } __spf_print(1, "best topology %s with time %f\n", outStr.c_str(), bestTime); } else { diff --git a/src/Predictor/PredictSchemeWithLibrary.h b/src/Predictor/PredictSchemeWithLibrary.h index 4e8e84b..8d6ed87 100644 --- a/src/Predictor/PredictSchemeWithLibrary.h +++ b/src/Predictor/PredictSchemeWithLibrary.h @@ -4,17 +4,54 @@ #include #include "dvm.h" #include "graph_calls.h" +#include "../../projects/libpredictor/include/libpredict/predictor.h" -void runPredictScheme(SgProject &project, - std::vector> &topologies, - const std::vector ¶llelRegions, - std::map>& loopGraph, - std::map> &SPF_messages); +struct PrecomputedDistributeParams { + size_t arrayId; + size_t elemSize; + std::vector axisDistributions; + std::vector> shadowEdges; + DIST::Array* array; +}; -double runLibpredictCalc(SgProject &project, - const std::vector& topology, - const std::string& clusterConfStr, - const std::vector ¶llelRegions, - std::map>& loopGraph, - std::map> &SPF_messages, - const std::map &templateIdMapping); +struct PrecomputedAlignParams { + size_t arrayId; + size_t distributedArrayId; + size_t elemSize; + std::vector dimensions; + std::vector distributionExpressions; + std::vector> shadowEdges; + DIST::Array* alignArray; + DIST::Array* alignWithArray; +}; + +struct PrecomputedShadowRenewParams { + size_t arrayId; + std::vector> shadow_renew; + bool corner; + size_t number_loop_iterations; + DIST::Array* shadowArray; +}; + +struct PrecomputedLibpredictParams { + std::vector distributeParams; + std::vector alignParams; + std::vector shadowRenewParams; +}; + +PrecomputedLibpredictParams precomputeLibpredictParams( + SgProject& project, + const std::vector& parallelRegions, + const std::map>& loopGraph, + const std::map& templateIdMapping); + +void runPredictScheme(SgProject& project, + std::vector>& topologies, + const std::vector& parallelRegions, + std::map>& loopGraph, + std::map>& SPF_messages); + +double runLibpredictCalc(const std::vector& topology, + const std::string& clusterConfStr, + const PrecomputedLibpredictParams& precomputedParams, + std::map>& SPF_messages); diff --git a/src/VisualizerCalls/get_information.cpp b/src/VisualizerCalls/get_information.cpp index ae93433..71dc476 100644 --- a/src/VisualizerCalls/get_information.cpp +++ b/src/VisualizerCalls/get_information.cpp @@ -1,2621 +1,2621 @@ -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef __BOOST -#include -#include -#endif - -#include "errors.h" -#include "version.h" -#include "get_information.h" -#include "dvm.h" -#include "../Sapfor.h" -#include "graph_loops_func.h" -#include "graph_calls_func.h" -#include "utils.h" -#include "../Sapfor.h" -#include "../ParallelizationRegions/ParRegions.h" -#include "SendMessage.h" -#include "../Predictor/PredictScheme.h" -#include "../DynamicAnalysis/gcov_info.h" -#include "../DynamicAnalysis/gCov_parser_func.h" -#include "../Distribution/CreateDistributionDirs.h" -#include "../LoopAnalyzer/loop_analyzer.h" -#include "../DirectiveProcessing/insert_directive.h" -#include "../ProjectManipulation/PerfAnalyzer.h" -#include "Utils/json.hpp" - -#include "BuildGraph.h" - -#ifdef _WIN32 -#include -#else -#include -#define _sleep(x) usleep(x * 1000) -#endif - -using std::string; -using std::wstring; -using std::map; -using std::set; -using std::vector; -using std::queue; -using std::pair; -using std::tuple; -using std::to_string; -using std::make_pair; -using json = nlohmann::json; - -extern bool runAsClient; -extern const char* VISUALIZER_DATA_PATH; - -bool showDebug = false; -static const string interruptEx = "Interrupted by user"; - -static inline int strLen(const short* shString) -{ - int t = 0; - if (shString == NULL) - return 0; - - while (shString[t] != '\0') - t++; - return t; -} - -static char* ConvertShortToChar(const short* source, int& strL) -{ - char* dist = NULL; - if (source == NULL) - return dist; - - strL = strLen(source); - dist = new char[strL + 1]; - - for (int i = 0; i < strL; ++i) - dist[i] = (char)source[i]; - dist[strL] = '\0'; - - return dist; -} - -extern bool ignoreArrayDistributeState; -static void setOptions(const short* options, bool isBuildParallel = false, const set* turnOffOptions = NULL) -{ - if (!optionNames[STATIC_SHADOW_ANALYSIS]) - { - optionNames[STATIC_SHADOW_ANALYSIS] = "STATIC_SHADOW_ANALYSIS"; - optionNames[STATIC_PRIVATE_ANALYSIS] = "STATIC_PRIVATE_ANALYSIS"; - optionNames[FREE_FORM] = "FREE_FORM"; - optionNames[KEEP_DVM_DIRECTIVES] = "KEEP_DVM_DIRECTIVES"; - optionNames[KEEP_SPF_DIRECTIVES] = "KEEP_SPF_DIRECTIVES"; - optionNames[PARALLIZE_FREE_LOOPS] = "PARALLIZE_FREE_LOOPS"; - optionNames[MAX_SHADOW_WIDTH] = "MAX_SHADOW_WIDTH"; - optionNames[OUTPUT_UPPER] = "OUTPUT_UPPER"; - optionNames[TRANSLATE_MESSAGES] = "TRANSLATE_MESSAGES"; - optionNames[KEEP_LOOPS_CLOSE_NESTING] = "KEEP_LOOPS_CLOSE_NESTING"; - optionNames[KEEP_GCOV] = "KEEP_GCOV"; - optionNames[ANALYSIS_OPTIONS] = "ANALYSIS_OPTIONS"; - optionNames[DEBUG_PRINT_ON] = "DEBUG_PRINT_ON"; - optionNames[SHARED_MEMORY] = "SHARED_MEMORY"; - optionNames[IGNORE_IO_SAPFOR] = "IGNORE_IO_SAPFOR"; - optionNames[KEEP_SPF_DIRECTIVES_AMONG_TRANSFORMATIONS] = "KEEP_SPF_DIRECTIVES_AMONG_TRANSFORMATIONS"; - optionNames[PARSE_FOR_INLINE] = "PARSE_FOR_INLINE"; - optionNames[EMPTY_OPTION] = "EMPTY_OPTION"; - } - - int len; - char* conv = ConvertShortToChar(options, len); - string convS(conv); - delete []conv; - - vector splited; - vector intOptions; - splitString(convS, '|', splited); - - intOptions.resize(EMPTY_OPTION); - std::fill(intOptions.begin(), intOptions.end(), -1); - - for (int z = STATIC_SHADOW_ANALYSIS; z < EMPTY_OPTION; ++z) //TODO: extend - { - if (splited.size() == z) - break; - - __spf_print(1, " read value '%s' to '%s' option\n", splited[z].c_str(), optionNames[z]); - if (z != ANALYSIS_OPTIONS) - { - if (sscanf(splited[z].c_str(), "%d", &intOptions[z]) != 1) - { - __spf_print(1, " !wrong value!\n"); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - } - else - intOptions[z] = -1; - } - - staticShadowAnalysis = intOptions[STATIC_SHADOW_ANALYSIS]; - staticPrivateAnalysis = intOptions[STATIC_PRIVATE_ANALYSIS]; - out_free_form = intOptions[FREE_FORM]; - if (out_free_form == 1) - out_line_unlimit = 1; - - if (isBuildParallel) - keepSpfDirs = intOptions[KEEP_SPF_DIRECTIVES]; - else - keepSpfDirs = intOptions[KEEP_SPF_DIRECTIVES_AMONG_TRANSFORMATIONS]; - maxShadowWidth = intOptions[MAX_SHADOW_WIDTH]; - out_upper_case = intOptions[OUTPUT_UPPER]; - langOfMessages = intOptions[TRANSLATE_MESSAGES]; - removeNestedIntervals = (intOptions[KEEP_LOOPS_CLOSE_NESTING] == 1); - showDebug = (intOptions[DEBUG_PRINT_ON] == 1); - - sharedMemoryParallelization = (sharedMemoryParallelization != 1) ? intOptions[SHARED_MEMORY] : sharedMemoryParallelization; - parallizeFreeLoops = (sharedMemoryParallelization == 1) ? 0 : intOptions[PARALLIZE_FREE_LOOPS]; - ignoreIO = (sharedMemoryParallelization == 1) ? 1 : intOptions[IGNORE_IO_SAPFOR]; - keepDvmDirectives = (sharedMemoryParallelization == 1) ? 0 : intOptions[KEEP_DVM_DIRECTIVES]; - - parseForInlining = intOptions[PARSE_FOR_INLINE]; - - string optAnalisys = splited.size() > ANALYSIS_OPTIONS ? splited[ANALYSIS_OPTIONS] : ""; - - if (sharedMemoryParallelization == 1) - ignoreArrayDistributeState = true; - else - ignoreArrayDistributeState = false; - - if (!turnOffOptions) - return; - - for (auto& elem : *turnOffOptions) - { - if (elem == STATIC_SHADOW_ANALYSIS) - staticShadowAnalysis = 0; - else if (elem == STATIC_PRIVATE_ANALYSIS) - staticPrivateAnalysis = 0; - else if (elem == FREE_FORM) - { - out_free_form = 0; - out_line_unlimit = 0; - } - else if (elem == KEEP_DVM_DIRECTIVES) - keepDvmDirectives = 0; - else if (elem == KEEP_SPF_DIRECTIVES) - keepSpfDirs = 0; - else if (elem == PARALLIZE_FREE_LOOPS) - parallizeFreeLoops = 0; - //TODO: to add if needed - } -} - -static bool tryOpenProjectFile(const char *project) -{ - bool ret = true; - FILE *f = fopen(project, "rb"); - if (f == NULL) - ret = false; - else - fclose(f); - return ret; -} - -volatile int passDone = 0; -static volatile int rethrow = 0; -static void runPassesLoop(const vector &passesToRun, const char *prName, const char *folderNameChar) -{ - try - { - setPassValues(); - if (showDebug) - printf("SAPFOR: all passes num %zd\n", passesToRun.size()); - for (int i = 0; i < passesToRun.size(); ++i) - { - if (showDebug) - printf("SAPFOR: run pass %d -> %s\n", passesToRun[i], passNames[passesToRun[i]]); - __spf_print(1, "SAPFOR: run pass %d -> %s\n", passesToRun[i], passNames[passesToRun[i]]); - runPass(passesToRun[i], prName, folderNameChar, true); - } - } -#if __BOOST - catch (boost::thread_interrupted&) - { - if (showDebug) - printf("SAPFOR: thread was terminated\n"); - fflush(NULL); - return; - } -#endif - catch (std::exception& ex) - { - printf("SAPFOR: thread was terminated with exception: %s\n", ex.what()); - fflush(NULL); - if (interruptEx == ex.what()) - rethrow = 1; - else - rethrow = -1; - } - catch (int ex) - { - __spf_print(1, "catch code %d\n", ex); - rethrow = ex; - } - catch (...) - { - rethrow = -1; - } - - if (showDebug) - printf("SAPFOR: exit with pass == 1\n"); - passDone = 1; -} - -static void runPassesForVisualizer(const short *projName, const vector &passesToRun, const short *folderName = NULL) -{ - int strL = 0, strF = 0; - char *prName = ConvertShortToChar(projName, strL); - char *folderNameChar = ConvertShortToChar(folderName, strF); - - try - { - if (strL == 0) - { - prName = new char[16]; - sprintf(prName, "dvm.proj"); - } - - if (tryOpenProjectFile(prName) == false) - { - __spf_print(1, "Can not open project '%s'\n", prName); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - - passDone = 0; - rethrow = 0; - - std::thread thread { runPassesLoop, passesToRun, prName, folderNameChar }; - - int timeToWait = 10; - int steps = 0; - while (passDone == 0) - { - FILE* interrupt_old = fopen("INTERRUPT", "r"); - FILE* interrupt = fopen((string(VISUALIZER_DATA_PATH) + "/INTERRUPT").c_str(), "r"); - if (interrupt || interrupt_old) - { - if (showDebug) - printf("[SAPFOR]: file exists, start interruption\n"); - fflush(NULL); - - if (interrupt_old) - fclose(interrupt_old); - if (interrupt) - fclose(interrupt); - passDone = 2; - } - - if (showDebug) - { - if (runAsClient) - printf("[SAPFOR]: "); - printf("wait %d\n", timeToWait); - } - _sleep(timeToWait); - - if (steps > 4) - { - if (timeToWait < 1000) - timeToWait *= 2; - steps = 0; - } - else - steps++; - } - if (showDebug) - printf("[SAPFOR]: start wait thread join, pass == %d\n", passDone); - thread.join(); - if (showDebug) - printf("[SAPFOR]: end wait thread join\n"); - - if (passDone == 2) - rethrow = 1; - } - catch (...) - { - rethrow = -1; - } - - if (prName) - delete []prName; - if (folderNameChar) - delete []folderNameChar; - - if (rethrow == 1) - { - if (showDebug) - printf("SAPFOR: rethrow -99\n"); - fflush(NULL); - throw -99; - } - else if (rethrow != 0) - throw rethrow; -} - -int SPF_StatisticAnalyzer(void*& context, int winHandler, short* options, short* pppaOptions, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int tmp; - char* optionsStr = ConvertShortToChar(pppaOptions, tmp); - - int retSize = -1; - try - { - if (pppaAnalyzer(optionsStr) != 0) - retSize = 1; - else - retSize = 0; - } - catch (int ex) - { - try { __spf_print(1, "catch code %d\n", ex); } - catch (...) { } - - if (ex == -99) - return -99; - else - retSize = ex; - } - catch (...) - { - retSize = -1; - } - - convertBuffers(outputMessage, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retSize; -} - -int SPF_ParseFiles(void*& context, int winHandler, short *options, short* projName, string& output, string& outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { PARSE_FILES }); - retSize = 0; - } - catch (int ex) - { - try { __spf_print(1, "catch code %d\n", ex); } - catch (...) {} - if (ex == -99) - return -99; - else - retSize = ex; - } - catch (...) - { - retSize = -1; - } - - convertBuffers(outputMessage, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retSize; -} - -extern vector filesCompilationOrder; -int SPF_ParseFilesWithOrder(void*& context, int winHandler, short* options, short* projName, string& result, string& output, string& outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { PARSE_FILES }); - - json filesArray = json::array(); - - for (auto& file : filesCompilationOrder) - filesArray.push_back(file); - - json filesOrder; - filesOrder["allFiles"] = filesArray; - - result = filesOrder.dump(); - retSize = 0; - } - catch (int ex) - { - try { __spf_print(1, "catch code %d\n", ex); } - catch (...) {} - if (ex == -99) - return -99; - else - retSize = ex; - } - catch (...) - { - retSize = -1; - } - - convertBuffers(outputMessage, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retSize; -} - -extern map> loopGraph; // file -> Info -int SPF_GetGraphLoops(void*& context, int winHandler, short *options, short *projName, string& result, string& output, string& outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { LOOP_GRAPH } ); - - result = convertToJson(loopGraph).dump(); - retSize = result.size(); - } - 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, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - - MessageManager::setWinHandler(-1); - return retSize; -} - -extern map> allFuncInfo; // file -> Info -int SPF_GetGraphFunctions(void*& context, int winHandler, short *options, short *projName, string& result, string& output, string& outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { FILL_PAR_REGIONS_LINES } ); - - result = convertToJson(allFuncInfo).dump(); - retSize = result.size(); - } - 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, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - - MessageManager::setWinHandler(-1); - return retSize; -} - -int SPF_GetGraphFunctionPositions(void*& context, int winHandler, short *options, short *projName, string& result, string& output, string& outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { FILL_PAR_REGIONS_LINES } ); - - int len; - char* conv = ConvertShortToChar(options, len); - string convS(conv); - delete[]conv; - - vector splited; - splitString(convS, '|', splited); - int iters = 1000; - int coef = 100; - int w = 1920; - int h = 1080; - int opts[4]; - - bool sendVisible = false; - set visible; - if (splited.size() > EMPTY_OPTION + 3) - { - for (int z = 0; z < 4; ++z) - { - if (sscanf(splited[EMPTY_OPTION + z].c_str(), "%d", &opts[z]) != 1) - { - __spf_print(1, "!wrong value!\n"); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - } - iters = opts[0]; coef = opts[1]; w = opts[2]; h = opts[3]; - __spf_print(1, "set iters=>%d, coef=>%d, w=>%d, h=>%d\n", iters, coef, w, h); - - sendVisible = splited.size() >= (EMPTY_OPTION + 1) + 4; - if (sendVisible) - { - int viz; - if (sscanf(splited[EMPTY_OPTION + 4].c_str(), "%d", &viz) != 1) - { - __spf_print(1, "!wrong value!\n"); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - - for (int z = EMPTY_OPTION + 5; z < EMPTY_OPTION + 5 + viz; ++z) - visible.insert(splited[z]); - - if (viz != visible.size()) - { - __spf_print(1, "!num visible not equal!\n"); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - } - } - - 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); - } - - json allPositions; - allPositions["allPositions"] = pos_array; - - result = allPositions.dump(); - retSize = result.size(); - } - 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, output); - - 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]; - -int SPF_GetPassesState(void*& context, int *&passInfo) -{ - MessageManager::clearCache(); - passInfo = PASSES_DONE; - return EMPTY_PASS; -} - -int SPF_GetPassesStateStr(void*& context, string &passInfo) -{ - MessageManager::clearCache(); - passInfo = ""; - for (int i = 0; i < EMPTY_PASS; ++i) - { - if (showDebug) - printf("SAPFOR: pass %d is %d with name %s\n", 1, PASSES_DONE[i], passNames[i]); - if (PASSES_DONE[i] == 1) - { - passInfo += passNames[i] + string("|"); - } - } - - //erase last "|" - if (passInfo != "" && passInfo[passInfo.size() - 1] == '|') - passInfo.erase(passInfo.end() - 1); - - return passInfo.size(); -} - - -extern map, pair> declaredArrays; -static void printDeclArraysState() -{ - if (showDebug) - printf("SAPFOR: decl state: \n"); - int dist = 0, priv = 0, err = 0; - for (auto it = declaredArrays.begin(); it != declaredArrays.end(); ++it) - { - if (it->second.first->IsNotDistribute() == false) - //printf("array '%s' is DISTR\n", it->second.first->GetShortName().c_str()); - dist++; - else if (it->second.first->IsNotDistribute() == true) - //printf("array '%s' is PRIVATE\n", it->second.first->GetShortName().c_str()); - priv++; - else - //printf("array '%s' is ERROR\n", it->second.first->GetShortName().c_str()); - err++; - } - if (showDebug) - printf(" PRIV %d, DIST %d, ERR %d, ALL %d\n", priv, dist, err, dist + priv + err); -} - -extern vector parallelRegions; -int SPF_GetArrayDistribution(void*& context, int winHandler, short *options, short *projName, string& result, string& output, string& outputMessage, - int regime) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - printDeclArraysState(); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - if (regime == 0) - runPassesForVisualizer(projName, { CREATE_TEMPLATE_LINKS }); - else if (regime == 1) - { - if (sharedMemoryParallelization) - { - ignoreArrayDistributeState = true; - runPassesForVisualizer(projName, { LOOP_ANALYZER_NODIST }); - } - else - runPassesForVisualizer(projName, { LOOP_ANALYZER_DATA_DIST_S1 }); - } - else if (regime == 2) - runPassesForVisualizer(projName, { FILL_PAR_REGIONS }); - else - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - json regions = json::array(); - for (auto& reg : parallelRegions) - { - json currReg = reg->toJson(); - regions.push_back(currReg); - } - - json allRegions; - allRegions["allRegions"] = regions; - - result = allRegions.dump(); - retSize = result.size(); - } - catch (int ex) - { - if (ex == -99) - return -99; - else - retSize = -1; - } - catch (...) - { - retSize = -1; - } - - convertBuffers(outputMessage, output); - - if (showDebug) - printf("SAPFOR: return from DLL with code %d\n", retSize); - MessageManager::setWinHandler(-1); - return retSize; -} - -extern map> SPF_messages; -extern map> arrayLinksByFuncCalls; - -//toModify[0] = size, toModify[1] arrayAddr, all triplets to modify for each dims -//ex: toModify A[1*J + 1]: [0] = 4, [1] = x000A, [2] = 0, [3] = 1, [4] = 1 -int SPF_ModifyArrayDistribution(void*& context, int winHandler, short *options, short *projName, string &output, string &outputMessage, - int regId, int64_t *toModify) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - printDeclArraysState(); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = 0; - try - { - if (toModify == NULL || regId < 0) - throw (-22); - - ParallelRegion *reg = NULL; - for (int k = 0; k < parallelRegions.size(); ++k) - { - if (regId == parallelRegions[k]->GetId()) - { - reg = parallelRegions[k]; - break; - } - } - - if (reg == NULL) - throw (-23); - - map>> data; - auto arrays = reg->GetAllArrays().GetArrays(); - set realRefsArrays; - for (auto& elem : arrays) - { - if (elem->IsArray()) - { - set realRefs; - getRealArrayRefs(elem, elem, realRefs, arrayLinksByFuncCalls); - realRefsArrays.insert(realRefs.begin(), realRefs.end()); - } - } - - int countOfArray = realRefsArrays.size(); - - int z = 1; - int last = *toModify; - - set templates; - for ( ; z < last; ++z) - { - int64_t addr = toModify[z]; - auto it = arrays.find((DIST::Array*)addr); - if (it == arrays.end()) - throw (-24); - - DIST::Array* array = *it; - DIST::Array* templ = array->GetTemplateArray(regId); - if (!templ || !templ->IsTemplate()) - throw (-30); - templates.insert(templ); - - if (array->IsLoopArray()) - throw (-26); - if (array->IsTemplate()) - throw (-27); - - auto it2 = data.find(array); - if (it2 != data.end()) - throw (-25); - - it2 = data.insert(it2, make_pair(array, vector>())); - it2->second.resize(array->GetDimSize()); - std::fill(it2->second.begin(), it2->second.end(), make_pair(0, 0)); - - ++z; - int k = z; - for ( ; k < z + 3 * array->GetDimSize(); k += 3) - if (toModify[k] != -1) - it2->second[toModify[k]] = make_pair((int)toModify[k + 1], (int)toModify[k + 2]); - z = k - 1; - } - if (z != last) - throw (-28); - - DIST::GraphCSR &reducedG = reg->GetReducedGraphToModify(); - DIST::Arrays &allArrays = reg->GetAllArraysToModify(); - DataDirective &dataDirectives = reg->GetDataDirToModify(); - - if (countOfArray != data.size()) - throw (-29); - - // recalculate links - reducedG.cleanCacheLinks(); - dataDirectives.alignRules.clear(); - - map>> toDelete; - toDelete = data; - for (auto& elem : templates) - { - toDelete.insert(make_pair(elem, vector>())); - elem->SetDimSizesToMaxMin(true); - } - reducedG.RemoveAllEdgesFromGraph(toDelete, allArrays); - - // add new rules and modify reduced graph - for (auto& arrayP : data) - { - DIST::Array* array = arrayP.first; - auto links = array->GetLinksWithTemplate(regId); - auto templ = array->GetTemplateArray(regId); - if (!templ) - throw (-32); - - for (int z = 0; z < links.size(); ++z) - { - if (links[z] != -1) - { - array->AddLinkWithTemplate(z, links[z], templ, arrayP.second[z], regId); - int err = DIST::AddArrayAccess(reducedG, allArrays, array, templ, make_pair(z, links[z]), 1.0, make_pair(make_pair(1, 0), arrayP.second[z]), WW_link); - if (err != 0) - throw (-33); - } - else - { - if (arrayP.second[z].first != 0) - throw (-31); - } - } - } - - createAlignDirs(reducedG, allArrays, dataDirectives, reg->GetId(), arrayLinksByFuncCalls, SPF_messages); - - __spf_print(1, "*** NEW RULES FOR PARALLEL REGION '%s':\n", reg->GetName().c_str()); - auto result = dataDirectives.GenAlignsRules(); - - for (int i = 0; i < result.size(); ++i) - __spf_print(1, " %s\n", result[i].c_str()); - - // clear user directives from all loops - for (auto& byFile : loopGraph) - { - if (SgFile::switchToFile(byFile.first) == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - for (auto& loop : byFile.second) - loop->clearUserDirectives(); - } - - // clear other dirs - set varsToClear = { ACC_REGION_DIR, ACC_END_REGION_DIR, ACC_ACTUAL_DIR, ACC_GET_ACTUAL_DIR, - DVM_SHADOW_DIR, DVM_REALIGN_DIR, DVM_REDISTRIBUTE_DIR, DVM_INHERIT_DIR, DVM_DYNAMIC_DIR }; - removeStatementsFromAllproject(varsToClear); - } - catch (int ex) - { - if (ex == -99) - return -99; - else - retSize = -1; - } - catch (...) - { - retSize = -1; - } - - if (showDebug) - printf("SAPFOR: return from DLL with code %d\n", retSize); - MessageManager::setWinHandler(-1); - return retSize; -} - -extern map allPredictorStats; -extern map> intervals; -extern vector> topologies; - -int SPF_CreateParallelVariant(void*& context, int winHandler, short *options, short *projName, short *folderName, int64_t *variants, int *varLen, - string &output, string &outputMessage, string &predictorStats) -{ - MessageManager::clearCache(); - if (folderName == NULL) - MessageManager::setWinHandler(-1); - else - MessageManager::setWinHandler(winHandler); - - allPredictorStats.clear(); - clearGlobalMessagesBuffer(); - setOptions(options, true); - - int retSize = 0; - try - { - if (varLen == NULL || variants == NULL) - throw (-2); - if ((*varLen % 3) != 0) - throw (-5); - - int countOfDist = 0; - if (sharedMemoryParallelization == 0) - { - map>> varLens; - for (int i = 0, k = 0; i < *varLen; i += 3, ++k) - { - if (showDebug) - printf("SAPFOR: input pack %d: %lld %lld %lld\n", k, variants[i], variants[i + 1], variants[i + 2]); - varLens[variants[i + 2]].push_back(make_pair(variants[i], variants[i + 1])); - } - - if (varLens.size() != parallelRegions.size()) - throw (-6); - - for (int z = 0; z < parallelRegions.size(); ++z) - { - auto it = varLens.find(parallelRegions[z]->GetId()); - if (it == varLens.end()) - throw (-7); - - const vector>& currVars = it->second; - const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); - - vector currentVariant(dataDirectives.distrRules.size()); - if (currVars.size() != dataDirectives.distrRules.size()) - { - if (showDebug) - printf("SAPFOR: currV %d, dataDirectives.distrRules %d\n", (int)currVars.size(), (int)dataDirectives.distrRules.size()); - throw (-3); - } - - map varMap; - for (int i = 0; i < currVars.size(); ++i) - varMap[currVars[i].first] = (int)currVars[i].second; - - map templateIdx; - for (int i = 0; i < dataDirectives.distrRules.size(); ++i) - { - if (showDebug) - printf("SAPFOR: template address %lld with num %d\n", (int64_t)dataDirectives.distrRules[i].first, i); - templateIdx[(int64_t)dataDirectives.distrRules[i].first] = i; - } - - for (auto it = varMap.begin(); it != varMap.end(); ++it) - { - auto itF = templateIdx.find(it->first); - if (itF == templateIdx.end()) - throw (-4); - - if (showDebug) - printf("SAPFOR: found %lld address\n", it->first); - currentVariant[itF->second] = it->second; - - for (auto& elem : dataDirectives.distrRules[itF->second].second[it->second].distRule) - { - if (elem == BLOCK) - countOfDist++; - } - } - parallelRegions[z]->SetCurrentVariant(currentVariant); - } - } - if (showDebug) - printf("SAPFOR: set all info done\n"); - runPassesForVisualizer(projName, { INSERT_PARALLEL_DIRS }, folderName); - - PredictorStats summed; - for (auto &predFile : allPredictorStats) - { - summed.IntervalCount += predFile.second.IntervalCount; - summed.ParallelCount += predFile.second.ParallelCount; - summed.RedistributeCount += predFile.second.RedistributeCount; - summed.RemoteCount += predFile.second.RemoteCount; - summed.ParallelStat.AcrossCount += predFile.second.ParallelStat.AcrossCount; - summed.ParallelStat.ReductionCount += predFile.second.ParallelStat.ReductionCount; - summed.ParallelStat.RemoteCount += predFile.second.ParallelStat.RemoteCount; - summed.ParallelStat.ShadowCount += predFile.second.ParallelStat.ShadowCount; - - summed.TotalScoreComm += predFile.second.TotalScoreComm; - summed.TotalScoreDist += predFile.second.TotalScoreDist; - summed.TotalScorePar += predFile.second.TotalScorePar; - } - - predictorStats = summed.toJson().dump(); - __spf_print(1, " statistic to send: %s\n", predictorStats.c_str()); - retSize = predictorStats.size(); - } - catch (int ex) - { - try { __spf_print(1, "catch code %d\n", ex); } catch (...) { } - if (ex == -99) - return -99; - else - retSize = -1; - retSize = ex; - } - catch (...) - { - retSize = -1; - } - - convertBuffers(outputMessage, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retSize; -} - - -int SPF_GetArrayLinks(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { CALL_GRAPH2 } ); - - map> linkedArrays; - for (auto& inMap : arrayLinksByFuncCalls) - { - set refs; - getRealArrayRefs(inMap.first, inMap.first, refs, arrayLinksByFuncCalls); - - if (refs.size() > 1) - for (auto& ref : refs) - for (auto& toAdd : refs) - if (ref != toAdd) - linkedArrays[ref].insert(toAdd); - } - - json allLinks = json::array(); - for (auto& array : linkedArrays) - { - json currLink; - currLink["id"] = array.first->GetId(); - - json links = json::array(); - for (auto& link : array.second) - links.push_back(link->GetId()); - currLink["links"] = links; - - allLinks.push_back(currLink); - } - - json links; - links["allLinks"] = allLinks; - - result = links.dump(); - retSize = result.size(); - } - 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, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - - MessageManager::setWinHandler(-1); - return retSize; -} - -extern std::pair min_max_block; -int SPF_GetMaxMinBlockDistribution(void*& context, int winHandler, short *options, short *projName, string &result, string &output, - string &outputMessage) -{ - MessageManager::clearCache(); - //MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { GET_MIN_MAX_BLOCK_DIST }); - - result = to_string(min_max_block.first) + " " + to_string(min_max_block.second); - retSize = result.size(); - } - 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, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - - MessageManager::setWinHandler(-1); - return retSize; -} - -int SPF_GetVersionAndBuildDate(void*& context, string &result) -{ - MessageManager::clearCache(); - json info; - - info["version"] = VERSION_SPF; - info["build_date"] = __DATE__; - info["build_time"] = __TIME__; - - result = info.dump(); - return result.size(); -} - -int SPF_GetCurrentPID(void*& context, string &result) -{ - MessageManager::clearCache(); - result = to_string(GetPid()); - return result.size(); -} - -extern string openDvmStatistic(const char* path, bool& isOk); -int SPF_OpenDvmStatistic(void*& context, const short* path, string &result) -{ - MessageManager::clearCache(); - result = ""; - - int strL = -1; - char* pathCh = ConvertShortToChar(path, strL); - checkNull(pathCh, convertFileName(__FILE__).c_str(), __LINE__); - - bool ok = true; - result = openDvmStatistic(pathCh, ok); - if (!ok) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - return result.size(); -} - -extern set intrinsicF; -extern void initIntrinsicFunctionNames(); - -int SPF_GetIntrinsics(void*& context, string &result) -{ - MessageManager::clearCache(); - initIntrinsicFunctionNames(); - - result = ""; - - for (auto it = intrinsicF.begin(); it != intrinsicF.end(); ++it) - { - if (it != intrinsicF.begin()) - result += " " + *it; - else - result += *it; - } - return result.size(); -} - -extern map>> includeDependencies; -int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - - setOptions(options); - int retSize = 0; - try - { - runPassesForVisualizer(projName, { BUILD_INCLUDE_DEPENDENCIES }); - - json inc_array = json::array(); - for (const auto& deps : includeDependencies) - { - json includes; - includes["file"] = deps.first; - - json array = json::array(); - for (const auto& [line, incls] : deps.second) - { - for (auto& incl : incls) - { - json elem; - elem["line"] = line; - elem["dependencyFileName"] = incl; - array.push_back(elem); - } - } - includes["includes"] = array; - inc_array.push_back(includes); - } - - json allIncludes; - allIncludes["allIncludes"] = inc_array; - result = allIncludes.dump(); - retSize = result.size(); - } - 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, output); - - MessageManager::setWinHandler(-1); - return retSize; -} - -int SPF_SetFunctionsToInclude(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { FIND_FUNC_TO_INCLUDE }); - - result = convertToJson(allFuncInfo).dump(); - retSize = result.size(); - } - 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, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retSize; -} - -int SPF_GetAllDeclaratedArrays(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { GET_ALL_ARRAY_DECL }); - - json arrays = json::array(); - for (const auto& [_, array] : declaredArrays) - { - json jArray = array.first->toJson(); - arrays.push_back(jArray); - } - - json allArrays; - allArrays["allArrays"] = arrays; - result = allArrays.dump(); - retSize = result.size(); - } - 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, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retSize; -} - -extern map lineInfo; -extern map, set>> dirsInfo; -int SPF_GetFileLineInfo(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { FILE_LINE_INFO }); - - json metric_array = json::array(); - for (const auto& fileInfo : lineInfo) - { - json fileMetric; - - 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 - { - 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; - result = allMetrics.dump(); - retSize = result.size(); - } - 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, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retSize; -} - -extern map distrStateFromGUI; -int SPF_SetDistributionFlagToArray(void*& context, char *key, int flag) -{ - MessageManager::clearCache(); - - if (flag != DIST::DISTR && flag != DIST::NO_DISTR) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - string keyStr(key); - try - { - if (declaredArrays.size()) - { - for (auto& array : declaredArrays) - { - const auto key = array.second.first->GetName(); - if (key == keyStr) - { - __spf_print(1, "change flag for array '%s': %d -> %d\n", key.c_str(), array.second.first->IsNotDistribute(), flag); - - if (flag == DIST::DISTR) - array.second.first->SetDistributeFlag(DIST::DISTR); - else - array.second.first->SetDistributeFlag(DIST::NO_DISTR); - break; - } - } - } - else - distrStateFromGUI[keyStr] = flag; - } - catch (...) - { - return -1; - } - - return 0; -} - -int SPF_SetDistributionFlagToArrays(void*& context, const char* keys, const char* flags) -{ - MessageManager::clearCache(); - - if (!keys || !flags) - return 0; - - try - { - vector keysS; - vector flagsS; - - splitString(keys, '|', keysS); - splitString(flags, '|', flagsS); - - if (keysS.size() != flagsS.size()) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - map allArrays; - for (auto& array : declaredArrays) - allArrays[array.second.first->GetIndepUniqName()] = array.second.first; - - if (allArrays.size()) - { - for (int z = 0; z < keysS.size(); ++z) - { - auto it = allArrays.find(keysS[z]); - if (it == allArrays.end()) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - int flag = -1; - if (sscanf(flagsS[z].c_str(), "%d", &flag) != 1) - { - __spf_print(1, "!wrong value!\n"); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - - if (flag != DIST::DISTR && flag != DIST::NO_DISTR) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - __spf_print(1, "change flag for array '%s': %d -> %d\n", keysS[z].c_str(), it->second->IsNotDistribute(), flag); - - if (flag == DIST::DISTR) - it->second->SetDistributeFlag(DIST::DISTR); - else - it->second->SetDistributeFlag(DIST::NO_DISTR); - } - } - else - { - for (int z = 0; z < keysS.size(); ++z) - { - int flagI = -1; - if (sscanf(flagsS[z].c_str(), "%d", &flagI) == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - distrStateFromGUI[keysS[z]] = flagI; - } - } - } - catch (...) - { - return -1; - } - return 0; -} - -static int simpleTransformPass(const passes PASS_NAME, short *options, short *projName, short *folderName, - string &output, string &outputMessage, bool isBuildParallel = false) -{ - clearGlobalMessagesBuffer(); - setOptions(options, isBuildParallel); - - int retCode = 0; - try - { - PASSES_DONE[PASS_NAME] = 0; - runPassesForVisualizer(projName, { PASS_NAME }, folderName); - } - catch (int ex) - { - __spf_print(1, "catch code %d\n", ex); - if (ex == -99) - return -99; - else - retCode = -1; - } - catch (...) - { - retCode = -1; - } - - convertBuffers(outputMessage, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retCode; -} - - -int SPF_CorrectCodeStylePass(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(CORRECT_CODE_STYLE, options, projName, folderName, output, outputMessage); -} - -int SPF_DuplicateFunctionChains(void*& context, int winHandler, short *options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(DUPLICATE_FUNCTIONS, options, projName, folderName, output, outputMessage); -} - -int SPF_ResolveParallelRegionConflicts(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(RESOLVE_PAR_REGIONS, options, projName, folderName, output, outputMessage); -} - -int SPF_RemoveDistArraysFromIO(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(REMOVE_DIST_ARRAYS_FROM_IO, options, projName, folderName, output, outputMessage); - -} -int SPF_PrivateExpansion(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(PRIVATE_ARRAYS_EXPANSION, options, projName, folderName, output, outputMessage); -} -int SPF_PrivateShrinking(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(PRIVATE_ARRAYS_SHRINKING, options, projName, folderName, output, outputMessage); -} - -int SPF_PrivateRemoving(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(PRIVATE_REMOVING, options, projName, folderName, output, outputMessage); -} - -int SPF_LoopFission(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(LOOPS_SPLITTER, options, projName, folderName, output, outputMessage); -} - -int SPF_LoopUnion(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(LOOPS_COMBINER, options, projName, folderName, output, outputMessage); -} - -int SPF_LoopUnrolling(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(UNROLL_LOOPS, options, projName, folderName, output, outputMessage); -} - -int SPF_CreateIntervalsTree(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(INSERT_INTER_TREE, options, projName, folderName, output, outputMessage); -} - -int SPF_RemoveOmpDirectives(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(REMOVE_OMP_DIRS_TRANSFORM, options, projName, folderName, output, outputMessage); -} - -int SPF_RemoveDvmDirectives(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(REMOVE_DVM_DIRS, options, projName, folderName, output, outputMessage); -} - -int SPF_RemoveSpfDirectives(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(REMOVE_SPF_DIRS, options, projName, folderName, output, outputMessage); -} - -int SPF_RemoveDvmDirectivesToComments(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(REMOVE_DVM_DIRS_TO_COMMENTS, options, projName, folderName, output, outputMessage); -} - -int SPF_RemoveComments(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(REMOVE_COMMENTS, options, projName, folderName, output, outputMessage); -} - -int SPF_RemoveDvmIntervals(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(REMOVE_DVM_INTERVALS, options, projName, folderName, output, outputMessage); -} - -int SPF_CreateCheckpoints(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(CREATE_CHECKPOINTS, options, projName, folderName, output, outputMessage); -} - -int SPF_ConvertStructures(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(CONVERT_STRUCTURES_TO_SIMPLE, options, projName, folderName, output, outputMessage); -} - -int SPF_InitDeclsWithZero(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(SET_TO_ALL_DECL_INIT_ZERO, options, projName, folderName, output, outputMessage); -} - -int SPF_RemoveUnusedFunctions(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(REMOVE_UNUSED_FUNCTIONS, options, projName, folderName, output, outputMessage); -} - -int SPF_ExpressionSubstitution(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(SUBST_EXPR_RD_AND_UNPARSE, options, projName, folderName, output, outputMessage); -} - -int SPF_InsertDvmhRegions(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - ignoreArrayDistributeState = true; - return simpleTransformPass(INSERT_REGIONS, options, projName, folderName, output, outputMessage); -} - -int SPF_ResolveCommonBlockConflicts(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - ignoreArrayDistributeState = true; - return simpleTransformPass(FIX_COMMON_BLOCKS, options, projName, folderName, output, outputMessage); -} - -int SPF_SharedMemoryParallelization(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - ignoreArrayDistributeState = true; - sharedMemoryParallelization = 1; - return simpleTransformPass(INSERT_PARALLEL_DIRS_NODIST, options, projName, folderName, output, outputMessage, true); -} - -int SPF_InsertPrivateFromGUI(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(INSERT_NO_DISTR_FLAGS_FROM_GUI, options, projName, folderName, output, outputMessage); -} - -int SPF_RemoveDeadCode(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(REMOVE_DEAD_CODE_AND_UNPARSE, options, projName, folderName, output, outputMessage); -} - -int SPF_InsertImplicitNone(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(SET_IMPLICIT_NONE, options, projName, folderName, output, outputMessage); -} - -int SPF_RenameIncludes(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - return simpleTransformPass(RENAME_INLCUDES, options, projName, folderName, output, outputMessage); -} - -static inline void convertBackSlash(char *str, int strL) -{ - for (int z = 0; z < strL; ++z) - if (str[z] == '\\') - str[z] = '/'; -} - -//TODO: need to extend 'outFileName' to vector -static int inline runModificationPass(passes passName, short* projName, short* folderName, vector> &newFiles, const string outFileName) -{ - PASSES_DONE[passName] = 0; - runPassesForVisualizer(projName, { passName }, folderName); - - //fill data - // newFiles: <����� ������ ��� ���, ���������� �����> - string newFile; - - if (SgFile::switchToFile(outFileName.c_str()) == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - newFile = unparseProjectToString(current_file, EXPAND_EXTRACT_PAR_REGION); - newFiles.push_back(make_pair(outFileName, newFile)); - return newFiles.size(); -} - -extern tuple inData; -int SPF_ChangeSpfIntervals(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage, - short *fileNameToMod, int *toModifyLines, vector> &newFiles) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retCode = 0; - try - { - int strL; - char *file_c = ConvertShortToChar(fileNameToMod, strL); - convertBackSlash(file_c, strL); - - std::get<0>(inData) = file_c; - std::get<1>(inData) = toModifyLines[0]; - std::get<2>(inData) = toModifyLines[1]; - std::get<3>(inData) = toModifyLines[2]; - retCode = runModificationPass(EXPAND_EXTRACT_PAR_REGION, projName, folderName, newFiles, file_c); - } - catch (int ex) - { - __spf_print(1, "catch code %d\n", ex); - if (ex == -99) - return -99; - else - retCode = -1; - } - catch (...) - { - retCode = -1; - } - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retCode; -} - -extern vector> inDataProc; -int SPF_InlineProcedure(void*& context, int winHandler, short *options, short* projName, short* folderName, - short* name, short* file, int line, - string &output, string &outputMessage, vector>& newFiles) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retCode = 0; - try - { - int tmp; - char* name_c = ConvertShortToChar(name, tmp); - char* file_c = ConvertShortToChar(file, tmp); - convertBackSlash(file_c, tmp); - - inDataProc.push_back(std::make_tuple(name_c, file_c, line)); - retCode = runModificationPass(INLINE_PROCEDURES, projName, folderName, newFiles, file_c); - } - catch (int ex) - { - __spf_print(1, "catch code %d\n", ex); - if (ex == -99) - return -99; - else - retCode = -1; - } - catch (...) - { - retCode = -1; - } - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retCode; -} - -extern pair inOnlyForloopOnPlace; -int SPF_LoopUnionCurrent(void*& context, int winHandler, short* options, short* projName, short* folderName, - short* file, int line, - string &output, string &outputMessage, vector> &newFiles) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options, false, new set{ KEEP_DVM_DIRECTIVES }); - - int retCode = 0; - try - { - int tmp; - char* file_c = ConvertShortToChar(file, tmp); - if (!file_c) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - convertBackSlash(file_c, tmp); - - inOnlyForloopOnPlace = make_pair(file_c, line); - retCode = runModificationPass(LOOPS_COMBINER, projName, folderName, newFiles, file_c); - } - catch (int ex) - { - __spf_print(1, "catch code %d\n", ex); - if (ex == -99) - return -99; - else - retCode = -1; - } - catch (...) - { - retCode = -1; - } - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retCode; -} - - -extern map>> inDataChains; -extern set inDataChainsStart; -int SPF_InlineProcedures(void*& context, int winHandler, short* options, short* projName, short* folderName, - short* names, string &output, string &outputMessage, int type) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options, false, new set{ KEEP_DVM_DIRECTIVES }); - - int retCode = 0; - try - { - int tmp = 0; - char* names_c = ConvertShortToChar(names, tmp); - if (tmp != 0) - { - string allNames(names_c); - vector result; - splitString(allNames, '|', result); - - if (type == 0) // dot substitution - { - if (result.size() < 2) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - for (int z = 0; z < result.size(); ) - { - string procName = result[z++]; - int count = -1; - if (sscanf(result[z++].c_str(), "%d", &count) == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - if (result.size() < z + 2 * count) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - for (int k = z; k < z + 2 * count; k += 2) - { - int line = -1; - if (sscanf(result[k + 1].c_str(), "%d", &line) == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - inDataProc.push_back(make_tuple(procName, result[k], line)); - } - z += 2 * count; - - if (count == 0) - inDataProc.push_back(make_tuple(procName, procName, -1)); - } - - PASSES_DONE[INLINE_PROCEDURES] = 0; - runPassesForVisualizer(projName, { INLINE_PROCEDURES }, folderName); - - inDataProc.clear(); - } - else if (type == 1) // hierarchical substitution - { - int numOfChain = -1; - int z = 0; - - if (sscanf(result[z++].c_str(), "%d", &numOfChain) == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - for (int k = 0; k < numOfChain; ++k) - { - int numOfCalls = -1; - if (sscanf(result[z++].c_str(), "%d", &numOfCalls) == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - string last = ""; - for (int p = 0; p < numOfCalls; ++p) - { - string funcName = result[z++]; - string fileName = result[z++]; - int line = -1; - if (sscanf(result[z++].c_str(), "%d", &line) == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - int needInline = -1; - if (sscanf(result[z++].c_str(), "%d", &needInline) == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - if (last != "" && needInline == 1) - inDataChains[last].insert(make_pair(funcName, line)); - - if (last == "" && needInline == 1) - inDataChainsStart.insert(funcName); - - if (needInline == 1) - last = funcName; - else - last = ""; - } - } - - PASSES_DONE[INLINE_PROCEDURES] = 0; - runPassesForVisualizer(projName, { INLINE_PROCEDURES }, folderName); - - inDataChains.clear(); - } - else - retCode = -1; - } - } - catch (int ex) - { - __spf_print(1, "catch code %d\n", ex); - if (ex == -99) - return -99; - else - retCode = -1; - } - catch (...) - { - retCode = -1; - } - - convertBuffers(outputMessage, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retCode; -} - - -extern map>> filesToInclude; -int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *visFilesToInclude, - string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - - if (visFilesToInclude == NULL) - return -2; - - vector splited; - //printf("%s\n", conv); - splitString(visFilesToInclude, '|', splited); - - if (splited.size() == 0) - return -3; - - filesToInclude.clear(); - unsigned i = 0; - while (i < splited.size()) - { - string file = splited[i++]; - int num = 0; - if (sscanf(splited[i++].c_str(), "%d", &num) == -1) - return -4; - - __spf_print(1, "file = %s:\n", file.c_str()); - for (int k = i; k < i + 2 * num; k += 2) - { - 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 += 2 * num; - } - return simpleTransformPass(INSERT_INCLUDES, options, projName, folderName, output, outputMessage); -} - -int SPF_LoopEndDoConverterPass(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - - return simpleTransformPass(CONVERT_TO_ENDDO, options, projName, folderName, output, outputMessage); -} - -extern map> gCovInfo; -int SPF_GetGCovInfo(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) -{ - MessageManager::clearCache(); - MessageManager::setWinHandler(winHandler); - clearGlobalMessagesBuffer(); - setOptions(options); - - int retSize = -1; - try - { - runPassesForVisualizer(projName, { GCOV_PARSER }); - - json gcov_array = json::array(); - for (auto& byFile : gCovInfo) - { - 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; - result = allGCov.dump(); - retSize = result.size(); - } - 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, output); - - if (showDebug) - printf("SAPFOR: return from DLL\n"); - MessageManager::setWinHandler(-1); - return retSize; - -} - -extern void deleteAllAllocatedData(bool enable); -extern set allocated; - -void SPF_deleteAllAllocatedData(void*& context) -{ - MessageManager::clearCache(); - - for (auto& elem : allocated) - delete []elem; - allocated.clear(); - - - deleteAllAllocatedData(true); -} - -void createNeededException() -{ - if (passDone == 2) - throw std::runtime_error(interruptEx); -} - -static void* context = NULL; -static short* toShort(const char* str) -{ - int len = str != NULL ? strlen(str) : 0; - short* arr = new short[len + 1]; - for (int z = 0; z < len; ++z) - arr[z] = str[z]; - arr[len] = '\0'; - return arr; -} - -template -static STR toString(const short* array, int size) -{ - if (size == 0) - return STR(); - - STR str; - for (int z = 0; z < size; ++z) - str += array[z]; - return str; -} - -static wstring toWstring(const int* array, int size) -{ - if (size == 0) - return L""; - - wstring str = L""; - for (int z = 0; z < size; ++z) - { - if (z != 0) - str += L"|"; - str += std::to_wstring(array[z]); - } - return str; -} - -static void codeInfo(wstring& total, const wstring& toAdd) -{ - total += std::to_wstring(toAdd.size()) + L" " + toAdd; -} - -static wstring finishJniCall(int retCode, const string& result, const string& output, const string& outputMessage, - const string *predictorStats = nullptr, const vector>* newFiles = nullptr) -{ - json results; - results["errorCode"] = retCode; - results["result"] = result; - results["output"] = output; - results["outputMessage"] = outputMessage; - results["predictorStats"] = predictorStats ? *predictorStats : ""; - - json filesToModify = json::array(); - if (newFiles) - { - for (auto& [name, text] : *newFiles) - { - json newFile; - newFile["name"] = name; - newFile["text"] = text; - - filesToModify.push_back(newFile); - } - } - results["files"] = filesToModify; - - string resVal = results.dump(); - short* resValS; - copyStringToShort(resValS, resVal); - - wstring codedResult = toString(resValS, resVal.size()); - return codedResult; -} - -static wstring finishJniCall(const int size, const int* sizes, const short* newFilesNames, const short* newFiles) -{ - wstring codedResult = L""; - - codeInfo(codedResult, toWstring(sizes, (sizes) ? (size + 1) : 0)); - codeInfo(codedResult, toString(newFilesNames, (newFilesNames) ? strLen(newFilesNames) : 0)); - codeInfo(codedResult, toString(newFiles, (newFiles) ? strLen(newFiles) : 0)); - - return codedResult; -} - -static void fillInfo(const vector& data, int64_t*& arr1, int& arr2) -{ - if (data.size() < 4) - return; - int idx = 0; - arr2 = std::stoi(data[idx++]) * 3; - arr1 = new int64_t[arr2]; - for (int z = 0; z < arr2; ++z, ++idx) - arr1[z] = std::stoll(data[idx]); - - if (data.size() != idx) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); -} - -static void fillInfo(const string& data, int*& arr) -{ - vector splited; - splitString(data, '|', splited); - - int idx = 0; - int count = splited.size(); - arr = new int[count]; - for (int z = 0; z < count; ++z, ++idx) - arr[z] = std::stoi(splited[idx]); -} - -static void fillInfo(const string& data, int64_t*& arr) -{ - vector splited; - splitString(data, '|', splited); - - int idx = 0; - int count = splited.size(); - arr = new int64_t[count]; - for (int z = 0; z < count; ++z, ++idx) - arr[z] = std::stoll(splited[idx]); -} - -const wstring Sapfor_RunAnalysis(const char* analysisName_c, const char* options_c, const char* projName_c, int winHandler) -{ - const string whichRun = analysisName_c; - int retCode = 0; - - string result, output, outputMessage; - - short* projSh = toShort(projName_c); - short* optSh = toShort(options_c); - - try - { - if (whichRun == "SPF_GetGraphLoops") - retCode = SPF_GetGraphLoops(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_GetGraphFunctions") - retCode = SPF_GetGraphFunctions(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_GetGraphFunctionPositions") - retCode = SPF_GetGraphFunctionPositions(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_GetArrayDistribution") - retCode = SPF_GetArrayDistribution(context, winHandler, optSh, projSh, result, output, outputMessage, 0); - else if (whichRun == "SPF_GetArrayDistributionOnlyAnalysis") - retCode = SPF_GetArrayDistribution(context, winHandler, optSh, projSh, result, output, outputMessage, 1); - else if (whichRun == "SPF_GetArrayDistributionOnlyRegions") - retCode = SPF_GetArrayDistribution(context, winHandler, optSh, projSh, result, output, outputMessage, 2); - else if (whichRun == "SPF_SetFunctionsToInclude") - retCode = SPF_SetFunctionsToInclude(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_GetAllDeclaratedArrays") - retCode = SPF_GetAllDeclaratedArrays(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_GetFileLineInfo") - retCode = SPF_GetFileLineInfo(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_GetIncludeDependencies") - retCode = SPF_GetIncludeDependencies(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_GetGCovInfo") - retCode = SPF_GetGCovInfo(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_ParseFiles") - retCode = SPF_ParseFiles(context, winHandler, optSh, projSh, output, outputMessage); - else if (whichRun == "SPF_ParseFilesWithOrder") - retCode = SPF_ParseFilesWithOrder(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_StatisticAnalyzer") - retCode = SPF_StatisticAnalyzer(context, winHandler, optSh, projSh, output, outputMessage); - else if (whichRun == "SPF_GetPassesStateStr") - retCode = SPF_GetPassesStateStr(context, result); - else if (whichRun == "SPF_GetVersionAndBuildDate") - retCode = SPF_GetVersionAndBuildDate(context, result); - else if (whichRun == "SPF_GetCurrentPID") - retCode = SPF_GetCurrentPID(context, result); - else if (whichRun == "SPF_GetIntrinsics") - retCode = SPF_GetIntrinsics(context, result); - else if (whichRun == "SPF_deleteAllAllocatedData") - SPF_deleteAllAllocatedData(context); - else if (whichRun == "SPF_GetArrayLinks") - retCode = SPF_GetArrayLinks(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_GetMaxMinBlockDistribution") - retCode = SPF_GetMaxMinBlockDistribution(context, winHandler, optSh, projSh, result, output, outputMessage); - else if (whichRun == "SPF_�hangeDirectory") // russian C - { - if (options_c == NULL) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - if (chdir(options_c) != 0) - { - __spf_print(1, "can not change directory to '%s'\n", options_c); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - } - else if (whichRun == "SPF_ChangeDirectory") - { - if (options_c == NULL) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - if (chdir(options_c) != 0) - { - __spf_print(1, "can not change directory to '%s'\n", options_c); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - } - else if (whichRun == "SPF_OpenDvmStatistic") - retCode = SPF_OpenDvmStatistic(context, projSh, result); - else - { - if (showDebug) - printf("SAPFOR: unknown function call, given '%s' name\n", whichRun.c_str()); - retCode = -1001; - } - } - catch (...) - { - printf("SAPFOR: wrong exit from main DLL block for JAVA\n"); - convertBuffers(outputMessage, output); - retCode = -1004; - } - - delete[]projSh; - delete[]optSh; - - fflush(NULL); - const wstring codedResult = finishJniCall(retCode, result, output, outputMessage); - return codedResult; -} - -const wstring Sapfor_RunTransformation(const char* transformName_c, const char* options_c, const char* projName_c, - const char* folder_c, const char* addOpt_c, int winHandler) -{ - const string whichRun = transformName_c; - int retCode = 0; - - string result, output, outputMessage, predStats; - - short* projSh = toShort(projName_c); - short* optSh = toShort(options_c); - short* fold = toShort(folder_c); if (string("") == folder_c) fold = NULL; - short* addOpt = toShort(addOpt_c); - - if (whichRun == "SPF_CorrectCodeStylePass") - retCode = SPF_CorrectCodeStylePass(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RemoveOmpDirectives") - retCode = SPF_RemoveOmpDirectives(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RemoveDvmDirectives") - retCode = SPF_RemoveDvmDirectives(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RemoveSpfDirectives") - retCode = SPF_RemoveSpfDirectives(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RemoveDvmDirectivesToComments") - retCode = SPF_RemoveDvmDirectivesToComments(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RemoveComments") - retCode = SPF_RemoveComments(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_InsertIncludesPass") - retCode = SPF_InsertIncludesPass(context, winHandler, optSh, projSh, fold, (char*)addOpt_c, output, outputMessage); - else if (whichRun == "SPF_ResolveParallelRegionConflicts") - retCode = SPF_ResolveParallelRegionConflicts(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RemoveDistArraysFromIO") - retCode = SPF_RemoveDistArraysFromIO(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_LoopEndDoConverterPass") - retCode = SPF_LoopEndDoConverterPass(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_LoopFission") - retCode = SPF_LoopFission(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_LoopUnion") - retCode = SPF_LoopUnion(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_LoopUnrolling") - retCode = SPF_LoopUnrolling(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_PrivateExpansion") - retCode = SPF_PrivateExpansion(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_PrivateShrinking") - retCode = SPF_PrivateShrinking(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_PrivateRemoving") - retCode = SPF_PrivateRemoving(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_CreateIntervalsTree") - retCode = SPF_CreateIntervalsTree(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RemoveDvmIntervals") - retCode = SPF_RemoveDvmIntervals(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_DuplicateFunctionChains") - retCode = SPF_DuplicateFunctionChains(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_InlineProcedures") - retCode = SPF_InlineProcedures(context, winHandler, optSh, projSh, fold, addOpt, output, outputMessage, 0); - else if (whichRun == "SPF_InlineProceduresH") - retCode = SPF_InlineProcedures(context, winHandler, optSh, projSh, fold, addOpt, output, outputMessage, 1); - else if (whichRun == "SPF_CreateCheckpoints") - retCode = SPF_CreateCheckpoints(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_ConvertStructures") - retCode = SPF_ConvertStructures(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_InitDeclsWithZero") - retCode = SPF_InitDeclsWithZero(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RemoveUnusedFunctions") - retCode = SPF_RemoveUnusedFunctions(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_ExpressionSubstitution") - retCode = SPF_ExpressionSubstitution(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_InsertDvmhRegions") - retCode = SPF_InsertDvmhRegions(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_ResolveCommonBlockConflicts") - retCode = SPF_ResolveCommonBlockConflicts(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_SharedMemoryParallelization") - retCode = SPF_SharedMemoryParallelization(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_InsertPrivateFromGUI") - retCode = SPF_InsertPrivateFromGUI(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RemoveDeadCode") - retCode = SPF_RemoveDeadCode(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_InsertImplicitNone") - retCode = SPF_InsertImplicitNone(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_RenameIncludes") - retCode = SPF_RenameIncludes(context, winHandler, optSh, projSh, fold, output, outputMessage); - else if (whichRun == "SPF_CreateParallelVariant") - { - vector splited; - string orig(addOpt_c); - splitString(orig, '|', splited); - - int64_t* variants = NULL; - int varLen = -1; - - fillInfo(splited, variants, varLen); - retCode = SPF_CreateParallelVariant(context, winHandler, optSh, projSh, fold, variants, &varLen, output, outputMessage, predStats); - - if (retCode > 0) - delete[]variants; - } - else - { - if (showDebug) - printf("SAPFOR: unknown function call, given '%s' name\n", whichRun.c_str()); - retCode = -1002; - } - - delete[]projSh; - delete[]optSh; - delete[]fold; - delete[]addOpt; - - fflush(NULL); - const wstring codedResult = finishJniCall(retCode, result, output, outputMessage, &predStats, nullptr); - return codedResult; -} - -const wstring Sapfor_RunModification(const char* modifyName_c, const char* options_c, const char* projName_c, - const char* folder_c, const char* addOpt1_c, const char* addOpt2_c, - int winHandler) -{ - const string whichRun = modifyName_c; - int retCode = 0; - - string result, output, outputMessage; - vector> newFiles; - - short* projSh = toShort(projName_c); - short* optSh = toShort(options_c); - short* fold = toShort(folder_c); - if (string("") == folder_c) - { - string tmp = "---modification---"; - - delete[]fold; - fold = new short[tmp.size() + 1]; - for (int z = 0; z < tmp.size(); ++z) - fold[z] = tmp[z]; - fold[tmp.size()] = '\0'; - } - - if (whichRun == "SPF_ModifyArrayDistribution") - { - int regId = atoi(addOpt1_c); - int64_t* modify = NULL; - fillInfo(addOpt2_c, modify); - - retCode = SPF_ModifyArrayDistribution(context, winHandler, optSh, projSh, output, outputMessage, regId, modify); - delete[]modify; - } - else if (whichRun == "SPF_InlineProcedure") - { - vector splitS; - splitString(addOpt1_c, '|', splitS); - - if (splitS.size() == 2) - { - vector tmpPar = { toShort(splitS[0].c_str()), toShort(splitS[1].c_str()) }; - int line = std::stoi(addOpt2_c); - retCode = SPF_InlineProcedure(context, winHandler, optSh, projSh, fold, tmpPar[0], tmpPar[1], line, output, outputMessage, newFiles); - - delete[] tmpPar[0]; - delete[] tmpPar[1]; - } - else - retCode = -1; - } - else if (whichRun == "SPF_LoopUnionCurrent") - { - short* file = toShort(addOpt1_c); - int line = std::stoi(addOpt2_c); - retCode = SPF_LoopUnionCurrent(context, winHandler, optSh, projSh, fold, file, line, output, outputMessage, newFiles); - delete[]file; - } - else if (whichRun == "SPF_ChangeSpfIntervals") - { - short* fileNameToMod = toShort(addOpt1_c); - int* toModifyLines = NULL; - fillInfo(addOpt2_c, toModifyLines); - retCode = SPF_ChangeSpfIntervals(context, winHandler, optSh, projSh, fold, output, outputMessage, fileNameToMod, toModifyLines, newFiles); - delete[]fileNameToMod; - delete[]toModifyLines; - } - else if (whichRun == "SPF_SetDistributionFlagToArray") - retCode = SPF_SetDistributionFlagToArray(context, (char*)addOpt1_c, atoi(addOpt2_c)); - else if (whichRun == "SPF_SetDistributionFlagToArrays") - retCode = SPF_SetDistributionFlagToArrays(context, addOpt1_c, addOpt2_c); - else - { - if (showDebug) - printf("SAPFOR: unknown function call, given '%s' name\n", whichRun.c_str()); - retCode = -1003; - } - - delete[]projSh; - delete[]optSh; - delete[]fold; - - fflush(NULL); - convertBuffers(outputMessage, output); - const wstring codedResult = finishJniCall(retCode, result, output, outputMessage, nullptr, &newFiles); - - //wprintf(L"%s\n", codedResult.c_str()); - return codedResult; -} +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef __BOOST +#include +#include +#endif + +#include "errors.h" +#include "version.h" +#include "get_information.h" +#include "dvm.h" +#include "../Sapfor.h" +#include "graph_loops_func.h" +#include "graph_calls_func.h" +#include "utils.h" +#include "../Sapfor.h" +#include "../ParallelizationRegions/ParRegions.h" +#include "SendMessage.h" +#include "../Predictor/PredictScheme.h" +#include "../DynamicAnalysis/gcov_info.h" +#include "../DynamicAnalysis/gCov_parser_func.h" +#include "../Distribution/CreateDistributionDirs.h" +#include "../LoopAnalyzer/loop_analyzer.h" +#include "../DirectiveProcessing/insert_directive.h" +#include "../ProjectManipulation/PerfAnalyzer.h" +#include "Utils/json.hpp" + +#include "BuildGraph.h" + +#ifdef _WIN32 +#include +#else +#include +#define _sleep(x) usleep(x * 1000) +#endif + +using std::string; +using std::wstring; +using std::map; +using std::set; +using std::vector; +using std::queue; +using std::pair; +using std::tuple; +using std::to_string; +using std::make_pair; +using json = nlohmann::json; + +extern bool runAsClient; +extern const char* VISUALIZER_DATA_PATH; + +bool showDebug = false; +static const string interruptEx = "Interrupted by user"; + +static inline int strLen(const short* shString) +{ + int t = 0; + if (shString == NULL) + return 0; + + while (shString[t] != '\0') + t++; + return t; +} + +static char* ConvertShortToChar(const short* source, int& strL) +{ + char* dist = NULL; + if (source == NULL) + return dist; + + strL = strLen(source); + dist = new char[strL + 1]; + + for (int i = 0; i < strL; ++i) + dist[i] = (char)source[i]; + dist[strL] = '\0'; + + return dist; +} + +extern bool ignoreArrayDistributeState; +static void setOptions(const short* options, bool isBuildParallel = false, const set* turnOffOptions = NULL) +{ + if (!optionNames[STATIC_SHADOW_ANALYSIS]) + { + optionNames[STATIC_SHADOW_ANALYSIS] = "STATIC_SHADOW_ANALYSIS"; + optionNames[STATIC_PRIVATE_ANALYSIS] = "STATIC_PRIVATE_ANALYSIS"; + optionNames[FREE_FORM] = "FREE_FORM"; + optionNames[KEEP_DVM_DIRECTIVES] = "KEEP_DVM_DIRECTIVES"; + optionNames[KEEP_SPF_DIRECTIVES] = "KEEP_SPF_DIRECTIVES"; + optionNames[PARALLIZE_FREE_LOOPS] = "PARALLIZE_FREE_LOOPS"; + optionNames[MAX_SHADOW_WIDTH] = "MAX_SHADOW_WIDTH"; + optionNames[OUTPUT_UPPER] = "OUTPUT_UPPER"; + optionNames[TRANSLATE_MESSAGES] = "TRANSLATE_MESSAGES"; + optionNames[KEEP_LOOPS_CLOSE_NESTING] = "KEEP_LOOPS_CLOSE_NESTING"; + optionNames[KEEP_GCOV] = "KEEP_GCOV"; + optionNames[ANALYSIS_OPTIONS] = "ANALYSIS_OPTIONS"; + optionNames[DEBUG_PRINT_ON] = "DEBUG_PRINT_ON"; + optionNames[SHARED_MEMORY] = "SHARED_MEMORY"; + optionNames[IGNORE_IO_SAPFOR] = "IGNORE_IO_SAPFOR"; + optionNames[KEEP_SPF_DIRECTIVES_AMONG_TRANSFORMATIONS] = "KEEP_SPF_DIRECTIVES_AMONG_TRANSFORMATIONS"; + optionNames[PARSE_FOR_INLINE] = "PARSE_FOR_INLINE"; + optionNames[EMPTY_OPTION] = "EMPTY_OPTION"; + } + + int len; + char* conv = ConvertShortToChar(options, len); + string convS(conv); + delete []conv; + + vector splited; + vector intOptions; + splitString(convS, '|', splited); + + intOptions.resize(EMPTY_OPTION); + std::fill(intOptions.begin(), intOptions.end(), -1); + + for (int z = STATIC_SHADOW_ANALYSIS; z < EMPTY_OPTION; ++z) //TODO: extend + { + if (splited.size() == z) + break; + + __spf_print(1, " read value '%s' to '%s' option\n", splited[z].c_str(), optionNames[z]); + if (z != ANALYSIS_OPTIONS) + { + if (sscanf(splited[z].c_str(), "%d", &intOptions[z]) != 1) + { + __spf_print(1, " !wrong value!\n"); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + } + else + intOptions[z] = -1; + } + + staticShadowAnalysis = intOptions[STATIC_SHADOW_ANALYSIS]; + staticPrivateAnalysis = intOptions[STATIC_PRIVATE_ANALYSIS]; + out_free_form = intOptions[FREE_FORM]; + if (out_free_form == 1) + out_line_unlimit = 1; + + if (isBuildParallel) + keepSpfDirs = intOptions[KEEP_SPF_DIRECTIVES]; + else + keepSpfDirs = intOptions[KEEP_SPF_DIRECTIVES_AMONG_TRANSFORMATIONS]; + maxShadowWidth = intOptions[MAX_SHADOW_WIDTH]; + out_upper_case = intOptions[OUTPUT_UPPER]; + langOfMessages = intOptions[TRANSLATE_MESSAGES]; + removeNestedIntervals = (intOptions[KEEP_LOOPS_CLOSE_NESTING] == 1); + showDebug = (intOptions[DEBUG_PRINT_ON] == 1); + + sharedMemoryParallelization = (sharedMemoryParallelization != 1) ? intOptions[SHARED_MEMORY] : sharedMemoryParallelization; + parallizeFreeLoops = (sharedMemoryParallelization == 1) ? 0 : intOptions[PARALLIZE_FREE_LOOPS]; + ignoreIO = (sharedMemoryParallelization == 1) ? 1 : intOptions[IGNORE_IO_SAPFOR]; + keepDvmDirectives = (sharedMemoryParallelization == 1) ? 0 : intOptions[KEEP_DVM_DIRECTIVES]; + + parseForInlining = intOptions[PARSE_FOR_INLINE]; + + string optAnalisys = splited.size() > ANALYSIS_OPTIONS ? splited[ANALYSIS_OPTIONS] : ""; + + if (sharedMemoryParallelization == 1) + ignoreArrayDistributeState = true; + else + ignoreArrayDistributeState = false; + + if (!turnOffOptions) + return; + + for (auto& elem : *turnOffOptions) + { + if (elem == STATIC_SHADOW_ANALYSIS) + staticShadowAnalysis = 0; + else if (elem == STATIC_PRIVATE_ANALYSIS) + staticPrivateAnalysis = 0; + else if (elem == FREE_FORM) + { + out_free_form = 0; + out_line_unlimit = 0; + } + else if (elem == KEEP_DVM_DIRECTIVES) + keepDvmDirectives = 0; + else if (elem == KEEP_SPF_DIRECTIVES) + keepSpfDirs = 0; + else if (elem == PARALLIZE_FREE_LOOPS) + parallizeFreeLoops = 0; + //TODO: to add if needed + } +} + +static bool tryOpenProjectFile(const char *project) +{ + bool ret = true; + FILE *f = fopen(project, "rb"); + if (f == NULL) + ret = false; + else + fclose(f); + return ret; +} + +volatile int passDone = 0; +static volatile int rethrow = 0; +static void runPassesLoop(const vector &passesToRun, const char *prName, const char *folderNameChar) +{ + try + { + setPassValues(); + if (showDebug) + printf("SAPFOR: all passes num %zd\n", passesToRun.size()); + for (int i = 0; i < passesToRun.size(); ++i) + { + if (showDebug) + printf("SAPFOR: run pass %d -> %s\n", passesToRun[i], passNames[passesToRun[i]]); + __spf_print(1, "SAPFOR: run pass %d -> %s\n", passesToRun[i], passNames[passesToRun[i]]); + runPass(passesToRun[i], prName, folderNameChar, true); + } + } +#if __BOOST + catch (boost::thread_interrupted&) + { + if (showDebug) + printf("SAPFOR: thread was terminated\n"); + fflush(NULL); + return; + } +#endif + catch (std::exception& ex) + { + printf("SAPFOR: thread was terminated with exception: %s\n", ex.what()); + fflush(NULL); + if (interruptEx == ex.what()) + rethrow = 1; + else + rethrow = -1; + } + catch (int ex) + { + __spf_print(1, "catch code %d\n", ex); + rethrow = ex; + } + catch (...) + { + rethrow = -1; + } + + if (showDebug) + printf("SAPFOR: exit with pass == 1\n"); + passDone = 1; +} + +static void runPassesForVisualizer(const short *projName, const vector &passesToRun, const short *folderName = NULL) +{ + int strL = 0, strF = 0; + char *prName = ConvertShortToChar(projName, strL); + char *folderNameChar = ConvertShortToChar(folderName, strF); + + try + { + if (strL == 0) + { + prName = new char[16]; + sprintf(prName, "dvm.proj"); + } + + if (tryOpenProjectFile(prName) == false) + { + __spf_print(1, "Can not open project '%s'\n", prName); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + + passDone = 0; + rethrow = 0; + + std::thread thread { runPassesLoop, passesToRun, prName, folderNameChar }; + + int timeToWait = 10; + int steps = 0; + while (passDone == 0) + { + FILE* interrupt_old = fopen("INTERRUPT", "r"); + FILE* interrupt = fopen((string(VISUALIZER_DATA_PATH) + "/INTERRUPT").c_str(), "r"); + if (interrupt || interrupt_old) + { + if (showDebug) + printf("[SAPFOR]: file exists, start interruption\n"); + fflush(NULL); + + if (interrupt_old) + fclose(interrupt_old); + if (interrupt) + fclose(interrupt); + passDone = 2; + } + + if (showDebug) + { + if (runAsClient) + printf("[SAPFOR]: "); + printf("wait %d\n", timeToWait); + } + _sleep(timeToWait); + + if (steps > 4) + { + if (timeToWait < 1000) + timeToWait *= 2; + steps = 0; + } + else + steps++; + } + if (showDebug) + printf("[SAPFOR]: start wait thread join, pass == %d\n", passDone); + thread.join(); + if (showDebug) + printf("[SAPFOR]: end wait thread join\n"); + + if (passDone == 2) + rethrow = 1; + } + catch (...) + { + rethrow = -1; + } + + if (prName) + delete []prName; + if (folderNameChar) + delete []folderNameChar; + + if (rethrow == 1) + { + if (showDebug) + printf("SAPFOR: rethrow -99\n"); + fflush(NULL); + throw -99; + } + else if (rethrow != 0) + throw rethrow; +} + +int SPF_StatisticAnalyzer(void*& context, int winHandler, short* options, short* pppaOptions, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int tmp; + char* optionsStr = ConvertShortToChar(pppaOptions, tmp); + + int retSize = -1; + try + { + if (pppaAnalyzer(optionsStr) != 0) + retSize = 1; + else + retSize = 0; + } + catch (int ex) + { + try { __spf_print(1, "catch code %d\n", ex); } + catch (...) { } + + if (ex == -99) + return -99; + else + retSize = ex; + } + catch (...) + { + retSize = -1; + } + + convertBuffers(outputMessage, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retSize; +} + +int SPF_ParseFiles(void*& context, int winHandler, short *options, short* projName, string& output, string& outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { PARSE_FILES }); + retSize = 0; + } + catch (int ex) + { + try { __spf_print(1, "catch code %d\n", ex); } + catch (...) {} + if (ex == -99) + return -99; + else + retSize = ex; + } + catch (...) + { + retSize = -1; + } + + convertBuffers(outputMessage, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retSize; +} + +extern vector filesCompilationOrder; +int SPF_ParseFilesWithOrder(void*& context, int winHandler, short* options, short* projName, string& result, string& output, string& outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { PARSE_FILES }); + + json filesArray = json::array(); + + for (auto& file : filesCompilationOrder) + filesArray.push_back(file); + + json filesOrder; + filesOrder["allFiles"] = filesArray; + + result = filesOrder.dump(); + retSize = 0; + } + catch (int ex) + { + try { __spf_print(1, "catch code %d\n", ex); } + catch (...) {} + if (ex == -99) + return -99; + else + retSize = ex; + } + catch (...) + { + retSize = -1; + } + + convertBuffers(outputMessage, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retSize; +} + +extern map> loopGraph; // file -> Info +int SPF_GetGraphLoops(void*& context, int winHandler, short *options, short *projName, string& result, string& output, string& outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { LOOP_GRAPH } ); + + result = convertToJson(loopGraph).dump(); + retSize = result.size(); + } + 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, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + + MessageManager::setWinHandler(-1); + return retSize; +} + +extern map> allFuncInfo; // file -> Info +int SPF_GetGraphFunctions(void*& context, int winHandler, short *options, short *projName, string& result, string& output, string& outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { FILL_PAR_REGIONS_LINES } ); + + result = convertToJson(allFuncInfo).dump(); + retSize = result.size(); + } + 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, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + + MessageManager::setWinHandler(-1); + return retSize; +} + +int SPF_GetGraphFunctionPositions(void*& context, int winHandler, short *options, short *projName, string& result, string& output, string& outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { FILL_PAR_REGIONS_LINES } ); + + int len; + char* conv = ConvertShortToChar(options, len); + string convS(conv); + delete[]conv; + + vector splited; + splitString(convS, '|', splited); + int iters = 1000; + int coef = 100; + int w = 1920; + int h = 1080; + int opts[4]; + + bool sendVisible = false; + set visible; + if (splited.size() > EMPTY_OPTION + 3) + { + for (int z = 0; z < 4; ++z) + { + if (sscanf(splited[EMPTY_OPTION + z].c_str(), "%d", &opts[z]) != 1) + { + __spf_print(1, "!wrong value!\n"); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + } + iters = opts[0]; coef = opts[1]; w = opts[2]; h = opts[3]; + __spf_print(1, "set iters=>%d, coef=>%d, w=>%d, h=>%d\n", iters, coef, w, h); + + sendVisible = splited.size() >= (EMPTY_OPTION + 1) + 4; + if (sendVisible) + { + int viz; + if (sscanf(splited[EMPTY_OPTION + 4].c_str(), "%d", &viz) != 1) + { + __spf_print(1, "!wrong value!\n"); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + + for (int z = EMPTY_OPTION + 5; z < EMPTY_OPTION + 5 + viz; ++z) + visible.insert(splited[z]); + + if (viz != visible.size()) + { + __spf_print(1, "!num visible not equal!\n"); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + } + } + + 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); + } + + json allPositions; + allPositions["allPositions"] = pos_array; + + result = allPositions.dump(); + retSize = result.size(); + } + 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, output); + + 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]; + +int SPF_GetPassesState(void*& context, int *&passInfo) +{ + MessageManager::clearCache(); + passInfo = PASSES_DONE; + return EMPTY_PASS; +} + +int SPF_GetPassesStateStr(void*& context, string &passInfo) +{ + MessageManager::clearCache(); + passInfo = ""; + for (int i = 0; i < EMPTY_PASS; ++i) + { + if (showDebug) + printf("SAPFOR: pass %d is %d with name %s\n", 1, PASSES_DONE[i], passNames[i]); + if (PASSES_DONE[i] == 1) + { + passInfo += passNames[i] + string("|"); + } + } + + //erase last "|" + if (passInfo != "" && passInfo[passInfo.size() - 1] == '|') + passInfo.erase(passInfo.end() - 1); + + return passInfo.size(); +} + + +extern map, pair> declaredArrays; +static void printDeclArraysState() +{ + if (showDebug) + printf("SAPFOR: decl state: \n"); + int dist = 0, priv = 0, err = 0; + for (auto it = declaredArrays.begin(); it != declaredArrays.end(); ++it) + { + if (it->second.first->IsNotDistribute() == false) + //printf("array '%s' is DISTR\n", it->second.first->GetShortName().c_str()); + dist++; + else if (it->second.first->IsNotDistribute() == true) + //printf("array '%s' is PRIVATE\n", it->second.first->GetShortName().c_str()); + priv++; + else + //printf("array '%s' is ERROR\n", it->second.first->GetShortName().c_str()); + err++; + } + if (showDebug) + printf(" PRIV %d, DIST %d, ERR %d, ALL %d\n", priv, dist, err, dist + priv + err); +} + +extern vector parallelRegions; +int SPF_GetArrayDistribution(void*& context, int winHandler, short *options, short *projName, string& result, string& output, string& outputMessage, + int regime) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + printDeclArraysState(); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + if (regime == 0) + runPassesForVisualizer(projName, { CREATE_TEMPLATE_LINKS }); + else if (regime == 1) + { + if (sharedMemoryParallelization) + { + ignoreArrayDistributeState = true; + runPassesForVisualizer(projName, { LOOP_ANALYZER_NODIST }); + } + else + runPassesForVisualizer(projName, { LOOP_ANALYZER_DATA_DIST_S1 }); + } + else if (regime == 2) + runPassesForVisualizer(projName, { FILL_PAR_REGIONS }); + else + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + json regions = json::array(); + for (auto& reg : parallelRegions) + { + json currReg = reg->toJson(); + regions.push_back(currReg); + } + + json allRegions; + allRegions["allRegions"] = regions; + + result = allRegions.dump(); + retSize = result.size(); + } + catch (int ex) + { + if (ex == -99) + return -99; + else + retSize = -1; + } + catch (...) + { + retSize = -1; + } + + convertBuffers(outputMessage, output); + + if (showDebug) + printf("SAPFOR: return from DLL with code %d\n", retSize); + MessageManager::setWinHandler(-1); + return retSize; +} + +extern map> SPF_messages; +extern map> arrayLinksByFuncCalls; + +//toModify[0] = size, toModify[1] arrayAddr, all triplets to modify for each dims +//ex: toModify A[1*J + 1]: [0] = 4, [1] = x000A, [2] = 0, [3] = 1, [4] = 1 +int SPF_ModifyArrayDistribution(void*& context, int winHandler, short *options, short *projName, string &output, string &outputMessage, + int regId, int64_t *toModify) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + printDeclArraysState(); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = 0; + try + { + if (toModify == NULL || regId < 0) + throw (-22); + + ParallelRegion *reg = NULL; + for (int k = 0; k < parallelRegions.size(); ++k) + { + if (regId == parallelRegions[k]->GetId()) + { + reg = parallelRegions[k]; + break; + } + } + + if (reg == NULL) + throw (-23); + + map>> data; + auto arrays = reg->GetAllArrays().GetArrays(); + set realRefsArrays; + for (auto& elem : arrays) + { + if (elem->IsArray()) + { + set realRefs; + getRealArrayRefs(elem, elem, realRefs, arrayLinksByFuncCalls); + realRefsArrays.insert(realRefs.begin(), realRefs.end()); + } + } + + int countOfArray = realRefsArrays.size(); + + int z = 1; + int last = *toModify; + + set templates; + for ( ; z < last; ++z) + { + int64_t addr = toModify[z]; + auto it = arrays.find((DIST::Array*)addr); + if (it == arrays.end()) + throw (-24); + + DIST::Array* array = *it; + DIST::Array* templ = array->GetTemplateArray(regId); + if (!templ || !templ->IsTemplate()) + throw (-30); + templates.insert(templ); + + if (array->IsLoopArray()) + throw (-26); + if (array->IsTemplate()) + throw (-27); + + auto it2 = data.find(array); + if (it2 != data.end()) + throw (-25); + + it2 = data.insert(it2, make_pair(array, vector>())); + it2->second.resize(array->GetDimSize()); + std::fill(it2->second.begin(), it2->second.end(), make_pair(0, 0)); + + ++z; + int k = z; + for ( ; k < z + 3 * array->GetDimSize(); k += 3) + if (toModify[k] != -1) + it2->second[toModify[k]] = make_pair((int)toModify[k + 1], (int)toModify[k + 2]); + z = k - 1; + } + if (z != last) + throw (-28); + + DIST::GraphCSR &reducedG = reg->GetReducedGraphToModify(); + DIST::Arrays &allArrays = reg->GetAllArraysToModify(); + DataDirective &dataDirectives = reg->GetDataDirToModify(); + + if (countOfArray != data.size()) + throw (-29); + + // recalculate links + reducedG.cleanCacheLinks(); + dataDirectives.alignRules.clear(); + + map>> toDelete; + toDelete = data; + for (auto& elem : templates) + { + toDelete.insert(make_pair(elem, vector>())); + elem->SetDimSizesToMaxMin(true); + } + reducedG.RemoveAllEdgesFromGraph(toDelete, allArrays); + + // add new rules and modify reduced graph + for (auto& arrayP : data) + { + DIST::Array* array = arrayP.first; + auto links = array->GetLinksWithTemplate(regId); + auto templ = array->GetTemplateArray(regId); + if (!templ) + throw (-32); + + for (int z = 0; z < links.size(); ++z) + { + if (links[z] != -1) + { + array->AddLinkWithTemplate(z, links[z], templ, arrayP.second[z], regId); + int err = DIST::AddArrayAccess(reducedG, allArrays, array, templ, make_pair(z, links[z]), 1.0, make_pair(make_pair(1, 0), arrayP.second[z]), WW_link); + if (err != 0) + throw (-33); + } + else + { + if (arrayP.second[z].first != 0) + throw (-31); + } + } + } + + createAlignDirs(reducedG, allArrays, dataDirectives, reg->GetId(), arrayLinksByFuncCalls, SPF_messages); + + __spf_print(1, "*** NEW RULES FOR PARALLEL REGION '%s':\n", reg->GetName().c_str()); + auto result = dataDirectives.GenAlignsRules(); + + for (int i = 0; i < result.size(); ++i) + __spf_print(1, " %s\n", result[i].c_str()); + + // clear user directives from all loops + for (auto& byFile : loopGraph) + { + if (SgFile::switchToFile(byFile.first) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + for (auto& loop : byFile.second) + loop->clearUserDirectives(); + } + + // clear other dirs + set varsToClear = { ACC_REGION_DIR, ACC_END_REGION_DIR, ACC_ACTUAL_DIR, ACC_GET_ACTUAL_DIR, + DVM_SHADOW_DIR, DVM_REALIGN_DIR, DVM_REDISTRIBUTE_DIR, DVM_INHERIT_DIR, DVM_DYNAMIC_DIR }; + removeStatementsFromAllproject(varsToClear); + } + catch (int ex) + { + if (ex == -99) + return -99; + else + retSize = -1; + } + catch (...) + { + retSize = -1; + } + + if (showDebug) + printf("SAPFOR: return from DLL with code %d\n", retSize); + MessageManager::setWinHandler(-1); + return retSize; +} + +extern map allPredictorStats; +extern map> intervals; +extern vector> topologies; + +int SPF_CreateParallelVariant(void*& context, int winHandler, short *options, short *projName, short *folderName, int64_t *variants, int *varLen, + string &output, string &outputMessage, string &predictorStats) +{ + MessageManager::clearCache(); + if (folderName == NULL) + MessageManager::setWinHandler(-1); + else + MessageManager::setWinHandler(winHandler); + + allPredictorStats.clear(); + clearGlobalMessagesBuffer(); + setOptions(options, true); + + int retSize = 0; + try + { + if (varLen == NULL || variants == NULL) + throw (-2); + if ((*varLen % 3) != 0) + throw (-5); + + int countOfDist = 0; + if (sharedMemoryParallelization == 0) + { + map>> varLens; + for (int i = 0, k = 0; i < *varLen; i += 3, ++k) + { + if (showDebug) + printf("SAPFOR: input pack %d: %lld %lld %lld\n", k, variants[i], variants[i + 1], variants[i + 2]); + varLens[variants[i + 2]].push_back(make_pair(variants[i], variants[i + 1])); + } + + if (varLens.size() != parallelRegions.size()) + throw (-6); + + for (int z = 0; z < parallelRegions.size(); ++z) + { + auto it = varLens.find(parallelRegions[z]->GetId()); + if (it == varLens.end()) + throw (-7); + + const vector>& currVars = it->second; + const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir(); + + vector currentVariant(dataDirectives.distrRules.size()); + if (currVars.size() != dataDirectives.distrRules.size()) + { + if (showDebug) + printf("SAPFOR: currV %d, dataDirectives.distrRules %d\n", (int)currVars.size(), (int)dataDirectives.distrRules.size()); + throw (-3); + } + + map varMap; + for (int i = 0; i < currVars.size(); ++i) + varMap[currVars[i].first] = (int)currVars[i].second; + + map templateIdx; + for (int i = 0; i < dataDirectives.distrRules.size(); ++i) + { + if (showDebug) + printf("SAPFOR: template address %lld with num %d\n", (int64_t)dataDirectives.distrRules[i].first, i); + templateIdx[(int64_t)dataDirectives.distrRules[i].first] = i; + } + + for (auto it = varMap.begin(); it != varMap.end(); ++it) + { + auto itF = templateIdx.find(it->first); + if (itF == templateIdx.end()) + throw (-4); + + if (showDebug) + printf("SAPFOR: found %lld address\n", it->first); + currentVariant[itF->second] = it->second; + + for (auto& elem : dataDirectives.distrRules[itF->second].second[it->second].distRule) + { + if (elem == BLOCK) + countOfDist++; + } + } + parallelRegions[z]->SetCurrentVariant(currentVariant); + } + } + if (showDebug) + printf("SAPFOR: set all info done\n"); + runPassesForVisualizer(projName, { INSERT_PARALLEL_DIRS }, folderName); + + PredictorStats summed; + for (auto &predFile : allPredictorStats) + { + summed.IntervalCount += predFile.second.IntervalCount; + summed.ParallelCount += predFile.second.ParallelCount; + summed.RedistributeCount += predFile.second.RedistributeCount; + summed.RemoteCount += predFile.second.RemoteCount; + summed.ParallelStat.AcrossCount += predFile.second.ParallelStat.AcrossCount; + summed.ParallelStat.ReductionCount += predFile.second.ParallelStat.ReductionCount; + summed.ParallelStat.RemoteCount += predFile.second.ParallelStat.RemoteCount; + summed.ParallelStat.ShadowCount += predFile.second.ParallelStat.ShadowCount; + + summed.TotalScoreComm += predFile.second.TotalScoreComm; + summed.TotalScoreDist += predFile.second.TotalScoreDist; + summed.TotalScorePar += predFile.second.TotalScorePar; + } + + predictorStats = summed.toJson().dump(); + __spf_print(1, " statistic to send: %s\n", predictorStats.c_str()); + retSize = predictorStats.size(); + } + catch (int ex) + { + try { __spf_print(1, "catch code %d\n", ex); } catch (...) { } + if (ex == -99) + return -99; + else + retSize = -1; + retSize = ex; + } + catch (...) + { + retSize = -1; + } + + convertBuffers(outputMessage, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retSize; +} + + +int SPF_GetArrayLinks(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { CALL_GRAPH2 } ); + + map> linkedArrays; + for (auto& inMap : arrayLinksByFuncCalls) + { + set refs; + getRealArrayRefs(inMap.first, inMap.first, refs, arrayLinksByFuncCalls); + + if (refs.size() > 1) + for (auto& ref : refs) + for (auto& toAdd : refs) + if (ref != toAdd) + linkedArrays[ref].insert(toAdd); + } + + json allLinks = json::array(); + for (auto& array : linkedArrays) + { + json currLink; + currLink["id"] = array.first->GetId(); + + json links = json::array(); + for (auto& link : array.second) + links.push_back(link->GetId()); + currLink["links"] = links; + + allLinks.push_back(currLink); + } + + json links; + links["allLinks"] = allLinks; + + result = links.dump(); + retSize = result.size(); + } + 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, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + + MessageManager::setWinHandler(-1); + return retSize; +} + +extern std::pair min_max_block; +int SPF_GetMaxMinBlockDistribution(void*& context, int winHandler, short *options, short *projName, string &result, string &output, + string &outputMessage) +{ + MessageManager::clearCache(); + //MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { GET_MIN_MAX_BLOCK_DIST }); + + result = to_string(min_max_block.first) + " " + to_string(min_max_block.second); + retSize = result.size(); + } + 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, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + + MessageManager::setWinHandler(-1); + return retSize; +} + +int SPF_GetVersionAndBuildDate(void*& context, string &result) +{ + MessageManager::clearCache(); + json info; + + info["version"] = VERSION_SPF; + info["build_date"] = __DATE__; + info["build_time"] = __TIME__; + + result = info.dump(); + return result.size(); +} + +int SPF_GetCurrentPID(void*& context, string &result) +{ + MessageManager::clearCache(); + result = to_string(GetPid()); + return result.size(); +} + +extern string openDvmStatistic(const char* path, bool& isOk); +int SPF_OpenDvmStatistic(void*& context, const short* path, string &result) +{ + MessageManager::clearCache(); + result = ""; + + int strL = -1; + char* pathCh = ConvertShortToChar(path, strL); + checkNull(pathCh, convertFileName(__FILE__).c_str(), __LINE__); + + bool ok = true; + result = openDvmStatistic(pathCh, ok); + if (!ok) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + return result.size(); +} + +extern set intrinsicF; +extern void initIntrinsicFunctionNames(); + +int SPF_GetIntrinsics(void*& context, string &result) +{ + MessageManager::clearCache(); + initIntrinsicFunctionNames(); + + result = ""; + + for (auto it = intrinsicF.begin(); it != intrinsicF.end(); ++it) + { + if (it != intrinsicF.begin()) + result += " " + *it; + else + result += *it; + } + return result.size(); +} + +extern map>> includeDependencies; +int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + + setOptions(options); + int retSize = 0; + try + { + runPassesForVisualizer(projName, { BUILD_INCLUDE_DEPENDENCIES }); + + json inc_array = json::array(); + for (const auto& deps : includeDependencies) + { + json includes; + includes["file"] = deps.first; + + json array = json::array(); + for (const auto& [line, incls] : deps.second) + { + for (auto& incl : incls) + { + json elem; + elem["line"] = line; + elem["dependencyFileName"] = incl; + array.push_back(elem); + } + } + includes["includes"] = array; + inc_array.push_back(includes); + } + + json allIncludes; + allIncludes["allIncludes"] = inc_array; + result = allIncludes.dump(); + retSize = result.size(); + } + 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, output); + + MessageManager::setWinHandler(-1); + return retSize; +} + +int SPF_SetFunctionsToInclude(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { FIND_FUNC_TO_INCLUDE }); + + result = convertToJson(allFuncInfo).dump(); + retSize = result.size(); + } + 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, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retSize; +} + +int SPF_GetAllDeclaratedArrays(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { GET_ALL_ARRAY_DECL }); + + json arrays = json::array(); + for (const auto& [_, array] : declaredArrays) + { + json jArray = array.first->toJson(); + arrays.push_back(jArray); + } + + json allArrays; + allArrays["allArrays"] = arrays; + result = allArrays.dump(); + retSize = result.size(); + } + 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, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retSize; +} + +extern map lineInfo; +extern map, set>> dirsInfo; +int SPF_GetFileLineInfo(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { FILE_LINE_INFO }); + + json metric_array = json::array(); + for (const auto& fileInfo : lineInfo) + { + json fileMetric; + + 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 + { + 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; + result = allMetrics.dump(); + retSize = result.size(); + } + 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, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retSize; +} + +extern map distrStateFromGUI; +int SPF_SetDistributionFlagToArray(void*& context, char *key, int flag) +{ + MessageManager::clearCache(); + + if (flag != DIST::DISTR && flag != DIST::NO_DISTR) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + string keyStr(key); + try + { + if (declaredArrays.size()) + { + for (auto& array : declaredArrays) + { + const auto key = array.second.first->GetName(); + if (key == keyStr) + { + __spf_print(1, "change flag for array '%s': %d -> %d\n", key.c_str(), array.second.first->IsNotDistribute(), flag); + + if (flag == DIST::DISTR) + array.second.first->SetDistributeFlag(DIST::DISTR); + else + array.second.first->SetDistributeFlag(DIST::NO_DISTR); + break; + } + } + } + else + distrStateFromGUI[keyStr] = flag; + } + catch (...) + { + return -1; + } + + return 0; +} + +int SPF_SetDistributionFlagToArrays(void*& context, const char* keys, const char* flags) +{ + MessageManager::clearCache(); + + if (!keys || !flags) + return 0; + + try + { + vector keysS; + vector flagsS; + + splitString(keys, '|', keysS); + splitString(flags, '|', flagsS); + + if (keysS.size() != flagsS.size()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + map allArrays; + for (auto& array : declaredArrays) + allArrays[array.second.first->GetIndepUniqName()] = array.second.first; + + if (allArrays.size()) + { + for (int z = 0; z < keysS.size(); ++z) + { + auto it = allArrays.find(keysS[z]); + if (it == allArrays.end()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + int flag = -1; + if (sscanf(flagsS[z].c_str(), "%d", &flag) != 1) + { + __spf_print(1, "!wrong value!\n"); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + + if (flag != DIST::DISTR && flag != DIST::NO_DISTR) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + __spf_print(1, "change flag for array '%s': %d -> %d\n", keysS[z].c_str(), it->second->IsNotDistribute(), flag); + + if (flag == DIST::DISTR) + it->second->SetDistributeFlag(DIST::DISTR); + else + it->second->SetDistributeFlag(DIST::NO_DISTR); + } + } + else + { + for (int z = 0; z < keysS.size(); ++z) + { + int flagI = -1; + if (sscanf(flagsS[z].c_str(), "%d", &flagI) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + distrStateFromGUI[keysS[z]] = flagI; + } + } + } + catch (...) + { + return -1; + } + return 0; +} + +static int simpleTransformPass(const passes PASS_NAME, short *options, short *projName, short *folderName, + string &output, string &outputMessage, bool isBuildParallel = false) +{ + clearGlobalMessagesBuffer(); + setOptions(options, isBuildParallel); + + int retCode = 0; + try + { + PASSES_DONE[PASS_NAME] = 0; + runPassesForVisualizer(projName, { PASS_NAME }, folderName); + } + catch (int ex) + { + __spf_print(1, "catch code %d\n", ex); + if (ex == -99) + return -99; + else + retCode = -1; + } + catch (...) + { + retCode = -1; + } + + convertBuffers(outputMessage, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retCode; +} + + +int SPF_CorrectCodeStylePass(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(CORRECT_CODE_STYLE, options, projName, folderName, output, outputMessage); +} + +int SPF_DuplicateFunctionChains(void*& context, int winHandler, short *options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(DUPLICATE_FUNCTIONS, options, projName, folderName, output, outputMessage); +} + +int SPF_ResolveParallelRegionConflicts(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(RESOLVE_PAR_REGIONS, options, projName, folderName, output, outputMessage); +} + +int SPF_RemoveDistArraysFromIO(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(REMOVE_DIST_ARRAYS_FROM_IO, options, projName, folderName, output, outputMessage); + +} +int SPF_PrivateExpansion(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(PRIVATE_ARRAYS_EXPANSION, options, projName, folderName, output, outputMessage); +} +int SPF_PrivateShrinking(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(PRIVATE_ARRAYS_SHRINKING, options, projName, folderName, output, outputMessage); +} + +int SPF_PrivateRemoving(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(PRIVATE_REMOVING, options, projName, folderName, output, outputMessage); +} + +int SPF_LoopFission(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(LOOPS_SPLITTER, options, projName, folderName, output, outputMessage); +} + +int SPF_LoopUnion(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(LOOPS_COMBINER, options, projName, folderName, output, outputMessage); +} + +int SPF_LoopUnrolling(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(UNROLL_LOOPS, options, projName, folderName, output, outputMessage); +} + +int SPF_CreateIntervalsTree(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(INSERT_INTER_TREE, options, projName, folderName, output, outputMessage); +} + +int SPF_RemoveOmpDirectives(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(REMOVE_OMP_DIRS_TRANSFORM, options, projName, folderName, output, outputMessage); +} + +int SPF_RemoveDvmDirectives(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(REMOVE_DVM_DIRS, options, projName, folderName, output, outputMessage); +} + +int SPF_RemoveSpfDirectives(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(REMOVE_SPF_DIRS, options, projName, folderName, output, outputMessage); +} + +int SPF_RemoveDvmDirectivesToComments(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(REMOVE_DVM_DIRS_TO_COMMENTS, options, projName, folderName, output, outputMessage); +} + +int SPF_RemoveComments(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(REMOVE_COMMENTS, options, projName, folderName, output, outputMessage); +} + +int SPF_RemoveDvmIntervals(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(REMOVE_DVM_INTERVALS, options, projName, folderName, output, outputMessage); +} + +int SPF_CreateCheckpoints(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(CREATE_CHECKPOINTS, options, projName, folderName, output, outputMessage); +} + +int SPF_ConvertStructures(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(CONVERT_STRUCTURES_TO_SIMPLE, options, projName, folderName, output, outputMessage); +} + +int SPF_InitDeclsWithZero(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(SET_TO_ALL_DECL_INIT_ZERO, options, projName, folderName, output, outputMessage); +} + +int SPF_RemoveUnusedFunctions(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(REMOVE_UNUSED_FUNCTIONS, options, projName, folderName, output, outputMessage); +} + +int SPF_ExpressionSubstitution(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(SUBST_EXPR_RD_AND_UNPARSE, options, projName, folderName, output, outputMessage); +} + +int SPF_InsertDvmhRegions(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + ignoreArrayDistributeState = true; + return simpleTransformPass(INSERT_REGIONS, options, projName, folderName, output, outputMessage); +} + +int SPF_ResolveCommonBlockConflicts(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + ignoreArrayDistributeState = true; + return simpleTransformPass(FIX_COMMON_BLOCKS, options, projName, folderName, output, outputMessage); +} + +int SPF_SharedMemoryParallelization(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + ignoreArrayDistributeState = true; + sharedMemoryParallelization = 1; + return simpleTransformPass(INSERT_PARALLEL_DIRS_NODIST, options, projName, folderName, output, outputMessage, true); +} + +int SPF_InsertPrivateFromGUI(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(INSERT_NO_DISTR_FLAGS_FROM_GUI, options, projName, folderName, output, outputMessage); +} + +int SPF_RemoveDeadCode(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(REMOVE_DEAD_CODE_AND_UNPARSE, options, projName, folderName, output, outputMessage); +} + +int SPF_InsertImplicitNone(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(SET_IMPLICIT_NONE, options, projName, folderName, output, outputMessage); +} + +int SPF_RenameIncludes(void*& context, int winHandler, short* options, short* projName, short* folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(RENAME_INLCUDES, options, projName, folderName, output, outputMessage); +} + +static inline void convertBackSlash(char *str, int strL) +{ + for (int z = 0; z < strL; ++z) + if (str[z] == '\\') + str[z] = '/'; +} + +//TODO: need to extend 'outFileName' to vector +static int inline runModificationPass(passes passName, short* projName, short* folderName, vector> &newFiles, const string outFileName) +{ + PASSES_DONE[passName] = 0; + runPassesForVisualizer(projName, { passName }, folderName); + + //fill data + // newFiles: <����� ������ ��� ���, ���������� �����> + string newFile; + + if (SgFile::switchToFile(outFileName.c_str()) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + newFile = unparseProjectToString(current_file, EXPAND_EXTRACT_PAR_REGION); + newFiles.push_back(make_pair(outFileName, newFile)); + return newFiles.size(); +} + +extern tuple inData; +int SPF_ChangeSpfIntervals(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage, + short *fileNameToMod, int *toModifyLines, vector> &newFiles) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retCode = 0; + try + { + int strL; + char *file_c = ConvertShortToChar(fileNameToMod, strL); + convertBackSlash(file_c, strL); + + std::get<0>(inData) = file_c; + std::get<1>(inData) = toModifyLines[0]; + std::get<2>(inData) = toModifyLines[1]; + std::get<3>(inData) = toModifyLines[2]; + retCode = runModificationPass(EXPAND_EXTRACT_PAR_REGION, projName, folderName, newFiles, file_c); + } + catch (int ex) + { + __spf_print(1, "catch code %d\n", ex); + if (ex == -99) + return -99; + else + retCode = -1; + } + catch (...) + { + retCode = -1; + } + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retCode; +} + +extern vector> inDataProc; +int SPF_InlineProcedure(void*& context, int winHandler, short *options, short* projName, short* folderName, + short* name, short* file, int line, + string &output, string &outputMessage, vector>& newFiles) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retCode = 0; + try + { + int tmp; + char* name_c = ConvertShortToChar(name, tmp); + char* file_c = ConvertShortToChar(file, tmp); + convertBackSlash(file_c, tmp); + + inDataProc.push_back(std::make_tuple(name_c, file_c, line)); + retCode = runModificationPass(INLINE_PROCEDURES, projName, folderName, newFiles, file_c); + } + catch (int ex) + { + __spf_print(1, "catch code %d\n", ex); + if (ex == -99) + return -99; + else + retCode = -1; + } + catch (...) + { + retCode = -1; + } + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retCode; +} + +extern pair inOnlyForloopOnPlace; +int SPF_LoopUnionCurrent(void*& context, int winHandler, short* options, short* projName, short* folderName, + short* file, int line, + string &output, string &outputMessage, vector> &newFiles) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options, false, new set{ KEEP_DVM_DIRECTIVES }); + + int retCode = 0; + try + { + int tmp; + char* file_c = ConvertShortToChar(file, tmp); + if (!file_c) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + convertBackSlash(file_c, tmp); + + inOnlyForloopOnPlace = make_pair(file_c, line); + retCode = runModificationPass(LOOPS_COMBINER, projName, folderName, newFiles, file_c); + } + catch (int ex) + { + __spf_print(1, "catch code %d\n", ex); + if (ex == -99) + return -99; + else + retCode = -1; + } + catch (...) + { + retCode = -1; + } + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retCode; +} + + +extern map>> inDataChains; +extern set inDataChainsStart; +int SPF_InlineProcedures(void*& context, int winHandler, short* options, short* projName, short* folderName, + short* names, string &output, string &outputMessage, int type) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options, false, new set{ KEEP_DVM_DIRECTIVES }); + + int retCode = 0; + try + { + int tmp = 0; + char* names_c = ConvertShortToChar(names, tmp); + if (tmp != 0) + { + string allNames(names_c); + vector result; + splitString(allNames, '|', result); + + if (type == 0) // dot substitution + { + if (result.size() < 2) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + for (int z = 0; z < result.size(); ) + { + string procName = result[z++]; + int count = -1; + if (sscanf(result[z++].c_str(), "%d", &count) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + if (result.size() < z + 2 * count) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + for (int k = z; k < z + 2 * count; k += 2) + { + int line = -1; + if (sscanf(result[k + 1].c_str(), "%d", &line) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + inDataProc.push_back(make_tuple(procName, result[k], line)); + } + z += 2 * count; + + if (count == 0) + inDataProc.push_back(make_tuple(procName, procName, -1)); + } + + PASSES_DONE[INLINE_PROCEDURES] = 0; + runPassesForVisualizer(projName, { INLINE_PROCEDURES }, folderName); + + inDataProc.clear(); + } + else if (type == 1) // hierarchical substitution + { + int numOfChain = -1; + int z = 0; + + if (sscanf(result[z++].c_str(), "%d", &numOfChain) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + for (int k = 0; k < numOfChain; ++k) + { + int numOfCalls = -1; + if (sscanf(result[z++].c_str(), "%d", &numOfCalls) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + string last = ""; + for (int p = 0; p < numOfCalls; ++p) + { + string funcName = result[z++]; + string fileName = result[z++]; + int line = -1; + if (sscanf(result[z++].c_str(), "%d", &line) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + int needInline = -1; + if (sscanf(result[z++].c_str(), "%d", &needInline) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + if (last != "" && needInline == 1) + inDataChains[last].insert(make_pair(funcName, line)); + + if (last == "" && needInline == 1) + inDataChainsStart.insert(funcName); + + if (needInline == 1) + last = funcName; + else + last = ""; + } + } + + PASSES_DONE[INLINE_PROCEDURES] = 0; + runPassesForVisualizer(projName, { INLINE_PROCEDURES }, folderName); + + inDataChains.clear(); + } + else + retCode = -1; + } + } + catch (int ex) + { + __spf_print(1, "catch code %d\n", ex); + if (ex == -99) + return -99; + else + retCode = -1; + } + catch (...) + { + retCode = -1; + } + + convertBuffers(outputMessage, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retCode; +} + + +extern map>> filesToInclude; +int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *visFilesToInclude, + string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + + if (visFilesToInclude == NULL) + return -2; + + vector splited; + //printf("%s\n", conv); + splitString(visFilesToInclude, '|', splited); + + if (splited.size() == 0) + return -3; + + filesToInclude.clear(); + unsigned i = 0; + while (i < splited.size()) + { + string file = splited[i++]; + int num = 0; + if (sscanf(splited[i++].c_str(), "%d", &num) == -1) + return -4; + + __spf_print(1, "file = %s:\n", file.c_str()); + for (int k = i; k < i + 2 * num; k += 2) + { + 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 += 2 * num; + } + return simpleTransformPass(INSERT_INCLUDES, options, projName, folderName, output, outputMessage); +} + +int SPF_LoopEndDoConverterPass(void*& context, int winHandler, short *options, short *projName, short *folderName, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + + return simpleTransformPass(CONVERT_TO_ENDDO, options, projName, folderName, output, outputMessage); +} + +extern map> gCovInfo; +int SPF_GetGCovInfo(void*& context, int winHandler, short *options, short *projName, string &result, string &output, string &outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + clearGlobalMessagesBuffer(); + setOptions(options); + + int retSize = -1; + try + { + runPassesForVisualizer(projName, { GCOV_PARSER }); + + json gcov_array = json::array(); + for (auto& byFile : gCovInfo) + { + 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; + result = allGCov.dump(); + retSize = result.size(); + } + 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, output); + + if (showDebug) + printf("SAPFOR: return from DLL\n"); + MessageManager::setWinHandler(-1); + return retSize; + +} + +extern void deleteAllAllocatedData(bool enable); +extern set allocated; + +void SPF_deleteAllAllocatedData(void*& context) +{ + MessageManager::clearCache(); + + for (auto& elem : allocated) + delete []elem; + allocated.clear(); + + + deleteAllAllocatedData(true); +} + +void createNeededException() +{ + if (passDone == 2) + throw std::runtime_error(interruptEx); +} + +static void* context = NULL; +static short* toShort(const char* str) +{ + int len = str != NULL ? strlen(str) : 0; + short* arr = new short[len + 1]; + for (int z = 0; z < len; ++z) + arr[z] = str[z]; + arr[len] = '\0'; + return arr; +} + +template +static STR toString(const short* array, int size) +{ + if (size == 0) + return STR(); + + STR str; + for (int z = 0; z < size; ++z) + str += array[z]; + return str; +} + +static wstring toWstring(const int* array, int size) +{ + if (size == 0) + return L""; + + wstring str = L""; + for (int z = 0; z < size; ++z) + { + if (z != 0) + str += L"|"; + str += std::to_wstring(array[z]); + } + return str; +} + +static void codeInfo(wstring& total, const wstring& toAdd) +{ + total += std::to_wstring(toAdd.size()) + L" " + toAdd; +} + +static wstring finishJniCall(int retCode, const string& result, const string& output, const string& outputMessage, + const string *predictorStats = nullptr, const vector>* newFiles = nullptr) +{ + json results; + results["errorCode"] = retCode; + results["result"] = result; + results["output"] = output; + results["outputMessage"] = outputMessage; + results["predictorStats"] = predictorStats ? *predictorStats : ""; + + json filesToModify = json::array(); + if (newFiles) + { + for (auto& [name, text] : *newFiles) + { + json newFile; + newFile["name"] = name; + newFile["text"] = text; + + filesToModify.push_back(newFile); + } + } + results["files"] = filesToModify; + + string resVal = results.dump(); + short* resValS; + copyStringToShort(resValS, resVal); + + wstring codedResult = toString(resValS, resVal.size()); + return codedResult; +} + +static wstring finishJniCall(const int size, const int* sizes, const short* newFilesNames, const short* newFiles) +{ + wstring codedResult = L""; + + codeInfo(codedResult, toWstring(sizes, (sizes) ? (size + 1) : 0)); + codeInfo(codedResult, toString(newFilesNames, (newFilesNames) ? strLen(newFilesNames) : 0)); + codeInfo(codedResult, toString(newFiles, (newFiles) ? strLen(newFiles) : 0)); + + return codedResult; +} + +static void fillInfo(const vector& data, int64_t*& arr1, int& arr2) +{ + if (data.size() < 4) + return; + int idx = 0; + arr2 = std::stoi(data[idx++]) * 3; + arr1 = new int64_t[arr2]; + for (int z = 0; z < arr2; ++z, ++idx) + arr1[z] = std::stoll(data[idx]); + + if (data.size() != idx) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); +} + +static void fillInfo(const string& data, int*& arr) +{ + vector splited; + splitString(data, '|', splited); + + int idx = 0; + int count = splited.size(); + arr = new int[count]; + for (int z = 0; z < count; ++z, ++idx) + arr[z] = std::stoi(splited[idx]); +} + +static void fillInfo(const string& data, int64_t*& arr) +{ + vector splited; + splitString(data, '|', splited); + + int idx = 0; + int count = splited.size(); + arr = new int64_t[count]; + for (int z = 0; z < count; ++z, ++idx) + arr[z] = std::stoll(splited[idx]); +} + +const wstring Sapfor_RunAnalysis(const char* analysisName_c, const char* options_c, const char* projName_c, int winHandler) +{ + const string whichRun = analysisName_c; + int retCode = 0; + + string result, output, outputMessage; + + short* projSh = toShort(projName_c); + short* optSh = toShort(options_c); + + try + { + if (whichRun == "SPF_GetGraphLoops") + retCode = SPF_GetGraphLoops(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_GetGraphFunctions") + retCode = SPF_GetGraphFunctions(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_GetGraphFunctionPositions") + retCode = SPF_GetGraphFunctionPositions(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_GetArrayDistribution") + retCode = SPF_GetArrayDistribution(context, winHandler, optSh, projSh, result, output, outputMessage, 0); + else if (whichRun == "SPF_GetArrayDistributionOnlyAnalysis") + retCode = SPF_GetArrayDistribution(context, winHandler, optSh, projSh, result, output, outputMessage, 1); + else if (whichRun == "SPF_GetArrayDistributionOnlyRegions") + retCode = SPF_GetArrayDistribution(context, winHandler, optSh, projSh, result, output, outputMessage, 2); + else if (whichRun == "SPF_SetFunctionsToInclude") + retCode = SPF_SetFunctionsToInclude(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_GetAllDeclaratedArrays") + retCode = SPF_GetAllDeclaratedArrays(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_GetFileLineInfo") + retCode = SPF_GetFileLineInfo(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_GetIncludeDependencies") + retCode = SPF_GetIncludeDependencies(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_GetGCovInfo") + retCode = SPF_GetGCovInfo(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_ParseFiles") + retCode = SPF_ParseFiles(context, winHandler, optSh, projSh, output, outputMessage); + else if (whichRun == "SPF_ParseFilesWithOrder") + retCode = SPF_ParseFilesWithOrder(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_StatisticAnalyzer") + retCode = SPF_StatisticAnalyzer(context, winHandler, optSh, projSh, output, outputMessage); + else if (whichRun == "SPF_GetPassesStateStr") + retCode = SPF_GetPassesStateStr(context, result); + else if (whichRun == "SPF_GetVersionAndBuildDate") + retCode = SPF_GetVersionAndBuildDate(context, result); + else if (whichRun == "SPF_GetCurrentPID") + retCode = SPF_GetCurrentPID(context, result); + else if (whichRun == "SPF_GetIntrinsics") + retCode = SPF_GetIntrinsics(context, result); + else if (whichRun == "SPF_deleteAllAllocatedData") + SPF_deleteAllAllocatedData(context); + else if (whichRun == "SPF_GetArrayLinks") + retCode = SPF_GetArrayLinks(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_GetMaxMinBlockDistribution") + retCode = SPF_GetMaxMinBlockDistribution(context, winHandler, optSh, projSh, result, output, outputMessage); + else if (whichRun == "SPF_�hangeDirectory") // russian C + { + if (options_c == NULL) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + if (chdir(options_c) != 0) + { + __spf_print(1, "can not change directory to '%s'\n", options_c); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + } + else if (whichRun == "SPF_ChangeDirectory") + { + if (options_c == NULL) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + if (chdir(options_c) != 0) + { + __spf_print(1, "can not change directory to '%s'\n", options_c); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + } + else if (whichRun == "SPF_OpenDvmStatistic") + retCode = SPF_OpenDvmStatistic(context, projSh, result); + else + { + if (showDebug) + printf("SAPFOR: unknown function call, given '%s' name\n", whichRun.c_str()); + retCode = -1001; + } + } + catch (...) + { + printf("SAPFOR: wrong exit from main DLL block for JAVA\n"); + convertBuffers(outputMessage, output); + retCode = -1004; + } + + delete[]projSh; + delete[]optSh; + + fflush(NULL); + const wstring codedResult = finishJniCall(retCode, result, output, outputMessage); + return codedResult; +} + +const wstring Sapfor_RunTransformation(const char* transformName_c, const char* options_c, const char* projName_c, + const char* folder_c, const char* addOpt_c, int winHandler) +{ + const string whichRun = transformName_c; + int retCode = 0; + + string result, output, outputMessage, predStats; + + short* projSh = toShort(projName_c); + short* optSh = toShort(options_c); + short* fold = toShort(folder_c); if (string("") == folder_c) fold = NULL; + short* addOpt = toShort(addOpt_c); + + if (whichRun == "SPF_CorrectCodeStylePass") + retCode = SPF_CorrectCodeStylePass(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RemoveOmpDirectives") + retCode = SPF_RemoveOmpDirectives(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RemoveDvmDirectives") + retCode = SPF_RemoveDvmDirectives(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RemoveSpfDirectives") + retCode = SPF_RemoveSpfDirectives(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RemoveDvmDirectivesToComments") + retCode = SPF_RemoveDvmDirectivesToComments(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RemoveComments") + retCode = SPF_RemoveComments(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_InsertIncludesPass") + retCode = SPF_InsertIncludesPass(context, winHandler, optSh, projSh, fold, (char*)addOpt_c, output, outputMessage); + else if (whichRun == "SPF_ResolveParallelRegionConflicts") + retCode = SPF_ResolveParallelRegionConflicts(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RemoveDistArraysFromIO") + retCode = SPF_RemoveDistArraysFromIO(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_LoopEndDoConverterPass") + retCode = SPF_LoopEndDoConverterPass(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_LoopFission") + retCode = SPF_LoopFission(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_LoopUnion") + retCode = SPF_LoopUnion(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_LoopUnrolling") + retCode = SPF_LoopUnrolling(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_PrivateExpansion") + retCode = SPF_PrivateExpansion(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_PrivateShrinking") + retCode = SPF_PrivateShrinking(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_PrivateRemoving") + retCode = SPF_PrivateRemoving(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_CreateIntervalsTree") + retCode = SPF_CreateIntervalsTree(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RemoveDvmIntervals") + retCode = SPF_RemoveDvmIntervals(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_DuplicateFunctionChains") + retCode = SPF_DuplicateFunctionChains(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_InlineProcedures") + retCode = SPF_InlineProcedures(context, winHandler, optSh, projSh, fold, addOpt, output, outputMessage, 0); + else if (whichRun == "SPF_InlineProceduresH") + retCode = SPF_InlineProcedures(context, winHandler, optSh, projSh, fold, addOpt, output, outputMessage, 1); + else if (whichRun == "SPF_CreateCheckpoints") + retCode = SPF_CreateCheckpoints(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_ConvertStructures") + retCode = SPF_ConvertStructures(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_InitDeclsWithZero") + retCode = SPF_InitDeclsWithZero(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RemoveUnusedFunctions") + retCode = SPF_RemoveUnusedFunctions(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_ExpressionSubstitution") + retCode = SPF_ExpressionSubstitution(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_InsertDvmhRegions") + retCode = SPF_InsertDvmhRegions(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_ResolveCommonBlockConflicts") + retCode = SPF_ResolveCommonBlockConflicts(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_SharedMemoryParallelization") + retCode = SPF_SharedMemoryParallelization(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_InsertPrivateFromGUI") + retCode = SPF_InsertPrivateFromGUI(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RemoveDeadCode") + retCode = SPF_RemoveDeadCode(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_InsertImplicitNone") + retCode = SPF_InsertImplicitNone(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_RenameIncludes") + retCode = SPF_RenameIncludes(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_CreateParallelVariant") + { + vector splited; + string orig(addOpt_c); + splitString(orig, '|', splited); + + int64_t* variants = NULL; + int varLen = -1; + + fillInfo(splited, variants, varLen); + retCode = SPF_CreateParallelVariant(context, winHandler, optSh, projSh, fold, variants, &varLen, output, outputMessage, predStats); + + if (retCode > 0) + delete[]variants; + } + else + { + if (showDebug) + printf("SAPFOR: unknown function call, given '%s' name\n", whichRun.c_str()); + retCode = -1002; + } + + delete[]projSh; + delete[]optSh; + delete[]fold; + delete[]addOpt; + + fflush(NULL); + const wstring codedResult = finishJniCall(retCode, result, output, outputMessage, &predStats, nullptr); + return codedResult; +} + +const wstring Sapfor_RunModification(const char* modifyName_c, const char* options_c, const char* projName_c, + const char* folder_c, const char* addOpt1_c, const char* addOpt2_c, + int winHandler) +{ + const string whichRun = modifyName_c; + int retCode = 0; + + string result, output, outputMessage; + vector> newFiles; + + short* projSh = toShort(projName_c); + short* optSh = toShort(options_c); + short* fold = toShort(folder_c); + if (string("") == folder_c) + { + string tmp = "---modification---"; + + delete[]fold; + fold = new short[tmp.size() + 1]; + for (int z = 0; z < tmp.size(); ++z) + fold[z] = tmp[z]; + fold[tmp.size()] = '\0'; + } + + if (whichRun == "SPF_ModifyArrayDistribution") + { + int regId = atoi(addOpt1_c); + int64_t* modify = NULL; + fillInfo(addOpt2_c, modify); + + retCode = SPF_ModifyArrayDistribution(context, winHandler, optSh, projSh, output, outputMessage, regId, modify); + delete[]modify; + } + else if (whichRun == "SPF_InlineProcedure") + { + vector splitS; + splitString(addOpt1_c, '|', splitS); + + if (splitS.size() == 2) + { + vector tmpPar = { toShort(splitS[0].c_str()), toShort(splitS[1].c_str()) }; + int line = std::stoi(addOpt2_c); + retCode = SPF_InlineProcedure(context, winHandler, optSh, projSh, fold, tmpPar[0], tmpPar[1], line, output, outputMessage, newFiles); + + delete[] tmpPar[0]; + delete[] tmpPar[1]; + } + else + retCode = -1; + } + else if (whichRun == "SPF_LoopUnionCurrent") + { + short* file = toShort(addOpt1_c); + int line = std::stoi(addOpt2_c); + retCode = SPF_LoopUnionCurrent(context, winHandler, optSh, projSh, fold, file, line, output, outputMessage, newFiles); + delete[]file; + } + else if (whichRun == "SPF_ChangeSpfIntervals") + { + short* fileNameToMod = toShort(addOpt1_c); + int* toModifyLines = NULL; + fillInfo(addOpt2_c, toModifyLines); + retCode = SPF_ChangeSpfIntervals(context, winHandler, optSh, projSh, fold, output, outputMessage, fileNameToMod, toModifyLines, newFiles); + delete[]fileNameToMod; + delete[]toModifyLines; + } + else if (whichRun == "SPF_SetDistributionFlagToArray") + retCode = SPF_SetDistributionFlagToArray(context, (char*)addOpt1_c, atoi(addOpt2_c)); + else if (whichRun == "SPF_SetDistributionFlagToArrays") + retCode = SPF_SetDistributionFlagToArrays(context, addOpt1_c, addOpt2_c); + else + { + if (showDebug) + printf("SAPFOR: unknown function call, given '%s' name\n", whichRun.c_str()); + retCode = -1003; + } + + delete[]projSh; + delete[]optSh; + delete[]fold; + + fflush(NULL); + convertBuffers(outputMessage, output); + const wstring codedResult = finishJniCall(retCode, result, output, outputMessage, nullptr, &newFiles); + + //wprintf(L"%s\n", codedResult.c_str()); + return codedResult; +}