16 Commits

Author SHA1 Message Date
fd18e95fa2 Clean up 2025-05-01 18:55:11 +03:00
1b7e25c909 Add SPF directive insertion 2025-05-01 18:55:11 +03:00
f8de920442 Extend interprocedural analysis 2025-05-01 18:55:11 +03:00
400b1e8e92 unparse after 2025-05-01 18:55:11 +03:00
acb4099fc4 Add Dominator tree builder and interprocedural analysis 2025-05-01 18:55:11 +03:00
4afedfceac trivial case for local variables only 2025-05-01 18:55:11 +03:00
ALEXks
4b7c3d89b0 fixed getInterfaceBlock 2025-04-30 16:52:37 +03:00
ALEXks
e7990bda0a fixed SPF_InsertIncludesPass unpacking 2025-04-30 09:14:22 +03:00
ALEXks
a49f10cb5b added predictor library to Sapfor 2025-04-25 14:30:43 +03:00
636f2b0af1 added predictor library to submodule 2025-04-23 18:02:18 +03:00
ALEXks
640e34816f Merge branch 'master' of http://192.168.0.176:30008/Alexander_KS/SAPFOR 2025-04-23 14:25:05 +03:00
ALEXks
b88eccaad4 added json for line info 2025-04-23 14:25:01 +03:00
ALEXks
7b0cb828a7 fixed predictor 2025-04-22 18:08:28 +03:00
ALEXks
06980ee344 fixed dumping statistics 2025-04-20 21:34:31 +03:00
ALEXks
cde49042ae added pass dependency for RENAME_INLCUDES 2025-04-16 16:18:32 +03:00
ALEXks
dae0afef45 moved SPF_GetIncludeDependencies to json 2025-04-16 14:58:46 +03:00
16 changed files with 755 additions and 97 deletions

3
.gitmodules vendored
View File

@@ -1,3 +1,6 @@
[submodule "projects/dvm"] [submodule "projects/dvm"]
path = projects/dvm path = projects/dvm
url = https://dvmguest:dvmguest@dvm.keldysh.ru/dvm-system/dvm url = https://dvmguest:dvmguest@dvm.keldysh.ru/dvm-system/dvm
[submodule "projects/libpredictor"]
path = projects/libpredictor
url = https://dvmguest:dvmguest@dvm.keldysh.ru/sapfor/dvm-perfm

View File

@@ -13,16 +13,18 @@ add_definitions("-D YYDEBUG")
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(fdvm_include projects/dvm/fdvmh/include/fdvmh/) set(fdvm_include projects/dvm/fdvmh/include/fdvmh/)
set(fdvm_sources projects/dvm/fdvmh/tools/fdvmh/) set(fdvm_sources projects/dvm/fdvmh/tools/fdvmh/)
set(sage_include_1 projects/dvm/fdvmh/include/sage/lib/) set(sage_include_1 projects/dvm/fdvmh/include/sage/lib/)
set(sage_include_2 projects/dvm/fdvmh/include/sage/h/) set(sage_include_2 projects/dvm/fdvmh/include/sage/h/)
set(libdb_sources projects/dvm/fdvmh/lib/sage/db/) set(libdb_sources projects/dvm/fdvmh/lib/sage/db/)
set(sage_sources projects/dvm/fdvmh/lib/sage/sage/) set(sage_sources projects/dvm/fdvmh/lib/sage/sage/)
set(sagepp_sources projects/dvm/fdvmh/lib/sage/sage++/) set(sagepp_sources projects/dvm/fdvmh/lib/sage/sage++/)
set(parser_sources projects/dvm/fdvmh/tools/parser/) set(parser_sources projects/dvm/fdvmh/tools/parser/)
set(pppa_sources projects/dvm/pppa/src/) set(pppa_sources projects/dvm/pppa/src/)
set(zlib_sources projects/dvm/third-party/Zlib/) set(zlib_sources projects/dvm/third-party/Zlib/)
set(libpred_sources projects/libpredictor/src/)
set(libpred_include projects/libpredictor/include/)
include_directories(src) include_directories(src)
#Sage lib includes #Sage lib includes
@@ -33,6 +35,8 @@ include_directories(${sage_include_2})
include_directories(${zlib_sources}/include) include_directories(${zlib_sources}/include)
#PPPA includes #PPPA includes
include_directories(${pppa_sources}) include_directories(${pppa_sources})
#Libpredictor includes
include_directories(${libpred_include})
set(PR_PARAM src/ProjectParameters/projectParameters.cpp set(PR_PARAM src/ProjectParameters/projectParameters.cpp
src/ProjectParameters/projectParameters.h) src/ProjectParameters/projectParameters.h)
@@ -312,6 +316,15 @@ set(MAIN src/Sapfor.cpp
set(PREDICTOR src/Predictor/PredictScheme.cpp set(PREDICTOR src/Predictor/PredictScheme.cpp
src/Predictor/PredictScheme.h) src/Predictor/PredictScheme.h)
set(LIBPREDICTOR ${libpred_sources}/cluster.cpp
${libpred_sources}/predictor.cpp
${libpred_sources}/transfer.cpp
${libpred_sources}/utils.cpp
${libpred_include}/libpredict/predictor.h
${libpred_include}/internal/cluster.h
${libpred_include}/internal/transfer.h
${libpred_include}/internal/utils.h)
set(PROJ_MAN src/ProjectManipulation/ParseFiles.cpp set(PROJ_MAN src/ProjectManipulation/ParseFiles.cpp
src/ProjectManipulation/ParseFiles.h src/ProjectManipulation/ParseFiles.h
@@ -401,6 +414,7 @@ set(SOURCE_EXE
${VS_CALLS} ${VS_CALLS}
${MAIN} ${MAIN}
${PREDICTOR} ${PREDICTOR}
${LIBPREDICTOR}
${PARSER} ${PARSER}
${PPPA} ${PPPA}
${ZLIB} ${ZLIB}
@@ -455,7 +469,8 @@ source_group (VisualizerCalls FILES ${VS_CALLS})
source_group (VisualizerCalls\\GraphLayout FILES ${GR_LAYOUT}) source_group (VisualizerCalls\\GraphLayout FILES ${GR_LAYOUT})
source_group (_SapforMain FILES ${MAIN}) source_group (_SapforMain FILES ${MAIN})
source_group (Predictor FILES ${PREDICTOR}) source_group (Predictor\\Analyzer FILES ${PREDICTOR})
source_group (Predictor\\Library FILES ${LIBPREDICTOR})
source_group (Parser FILES ${PARSER}) source_group (Parser FILES ${PARSER})
source_group (PPPA\\PPPA FILES ${PPPA}) source_group (PPPA\\PPPA FILES ${PPPA})
source_group (PPPA\\ZLib FILES ${ZLIB}) source_group (PPPA\\ZLib FILES ${ZLIB})

1
projects/libpredictor Submodule

Submodule projects/libpredictor added at d0772cdb57

View File

@@ -24,7 +24,7 @@ namespace SAPFOR
std::vector<BasicBlock*> next; std::vector<BasicBlock*> next;
std::vector<BasicBlock*> prev; std::vector<BasicBlock*> prev;
BasicBlock* idom{};
//reaching definition //reaching definition
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out; std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
@@ -42,6 +42,7 @@ namespace SAPFOR
void addInstruction(IR_Block* item); void addInstruction(IR_Block* item);
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); } void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
void addNext(BasicBlock* next_) { next.push_back(next_); } void addNext(BasicBlock* next_) { next.push_back(next_); }
void setIdom(BasicBlock* idom_) { idom = idom_; }
int removePrev(BasicBlock* removed); int removePrev(BasicBlock* removed);
int removeNext(BasicBlock* removed); int removeNext(BasicBlock* removed);
@@ -69,7 +70,8 @@ namespace SAPFOR
const std::vector<IR_Block*>& getInstructions() const { return instructions; } const std::vector<IR_Block*>& getInstructions() const { return instructions; }
const std::vector<BasicBlock*>& getNext() const { return next; } const std::vector<BasicBlock*>& getNext() const { return next; }
const std::vector<BasicBlock*>& getPrev() const { return prev; } const std::vector<BasicBlock*>& getPrev() const { return prev; }
BasicBlock* getIdom() const { return idom; }
/* /*
* FOR LIVE ANALYSIS * FOR LIVE ANALYSIS
*/ */
@@ -146,4 +148,4 @@ static inline void deleteCFG(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*
byFunc.second.clear(); byFunc.second.clear();
} }
cfg.clear(); cfg.clear();
} }

View File

@@ -834,19 +834,21 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
auto copy = duplicateProcedure(func, NULL, false, false, false, true); auto copy = duplicateProcedure(func, NULL, false, false, false, true);
const set<string> idents(pars.identificators.begin(), pars.identificators.end()); const set<string> idents(pars.identificators.begin(), pars.identificators.end());
bool need = (func->symbol()->identifier() == string("bl182"));
//remove all exec //remove all exec
SgStatement* st = copy->lexNext(); SgStatement* st = copy->lexNext();
SgStatement* last = copy->lastNodeOfStmt(); SgStatement* last = copy->lastNodeOfStmt();
vector<SgStatement*> toExtract; vector<SgStatement*> toExtract;
while (st != last) while (st != last)
{ {
if (isDVM_stat(st) || isSPF_stat(st)) if (isDVM_stat(st) || isSPF_stat(st))
{ {
if (st->variant() != ACC_ROUTINE_DIR) if (st->variant() != ACC_ROUTINE_DIR)
{ {
SgStatement* next = st->lexNext(); toExtract.push_back(st);
st->extractStmt(); st = st->lexNext();
st = next;
} }
else else
st = st->lexNext(); st = st->lexNext();
@@ -868,6 +870,7 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
while (st != last) while (st != last)
{ {
const int var = st->variant(); const int var = st->variant();
if (var == VAR_DECL if (var == VAR_DECL
|| var == VAR_DECL_90 || var == VAR_DECL_90
|| var == DIM_STAT || var == DIM_STAT
@@ -877,9 +880,8 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
bool empty = filterFromList(st, idents); bool empty = filterFromList(st, idents);
if (empty) if (empty)
{ {
SgStatement* next = st->lexNext();
toExtract.push_back(st); toExtract.push_back(st);
st = next; st = st->lexNext();
continue; continue;
} }
} }

View File

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

View File

@@ -0,0 +1,111 @@
#pragma once
#include "vector"
#include "map"
#include "../CFGraph/CFGraph.h"
#include <unordered_map>
using namespace std;
namespace SAPFOR {
class DominatorFinder {
private:
BasicBlock* entry;
std::vector<BasicBlock*> vertices;
std::unordered_map<BasicBlock*, int> dfs_num;
std::vector<int> parent, semi, vertex, ancestor, label;
std::vector<std::vector<int>> bucket;
int n;
void DFS(BasicBlock* v, int parent_num) {
dfs_num[v] = n;
vertex[n] = n;
semi[n] = n;
label[n] = n;
ancestor[n] = -1;
parent[n] = parent_num;
vertices[n++] = v;
for (const auto& w : v->getNext()) {
if (dfs_num[w] == -1) {
DFS(w, dfs_num[v]);
}
}
}
void Compress(int v) {
if (ancestor[ancestor[v]] != -1) {
Compress(ancestor[v]);
if (semi[label[ancestor[v]]] < semi[label[v]])
label[v] = label[ancestor[v]];
ancestor[v] = ancestor[ancestor[v]];
}
}
int Eval(int v) {
if (ancestor[v] == -1) return v;
Compress(v);
return label[v];
}
void Link(int v, int w) {
ancestor[w] = v;
}
public:
DominatorFinder(std::vector<BasicBlock*>& blocks) {
if (blocks.empty()) return;
entry = blocks[0];
n = 0;
for (auto block : blocks) dfs_num[block] = -1;
int max_size = blocks.size();
vertices.resize(max_size);
parent.assign(max_size, -1);
semi.assign(max_size, -1);
vertex.assign(max_size, -1);
ancestor.assign(max_size, -1);
label.assign(max_size, -1);
bucket.resize(max_size);
DFS(entry, -1);
for (int i = n - 1; i > 0; --i) {
int w = vertex[i];
for (BasicBlock* v : vertices[w]->getPrev()) {
int u = Eval(dfs_num[v]);
if (semi[u] < semi[w])
semi[w] = semi[u];
}
bucket[vertex[semi[w]]].push_back(w);
Link(parent[w], w);
for (int v : bucket[parent[w]])
{
int u = Eval(v);
if (semi[u] < semi[v])
vertices[v]->setIdom(vertices[u]);
else
vertices[v]->setIdom(vertices[parent[w]]);
}
bucket[parent[w]].clear();
}
for (int i = 1; i < n; ++i) {
int w = vertex[i];
if (vertices[w]->getIdom() != vertices[vertex[semi[w]]])
vertices[w]->setIdom(vertices[w]->getIdom()->getIdom());
}
entry->setIdom(nullptr);
}
};
void buildDominatorTreeLT(std::vector<BasicBlock*>& blocks) {
DominatorFinder finder(blocks);
}
}

View File

@@ -1,33 +1,413 @@
#include "../Utils/leak_detector.h"
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <cstring>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
#include <set> #include <set>
#include <string>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <tuple> #include <tuple>
#include "../Utils/SgUtils.h"
#include "../CFGraph/CFGraph.h"
#include "CFGraph/IR.h"
#include "Distribution/Array.h"
#include "dvm.h" #include "dvm.h"
#include "../Utils/errors.h" #include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "../GraphCall/graph_calls.h" #include "../GraphCall/graph_calls.h"
#include "../GraphCall/graph_calls_func.h" #include "../GraphCall/graph_calls_func.h"
#include "libSage++.h"
#include "projectParameters.h" #include "projectParameters.h"
#include "domTree.h"
using namespace std; using namespace std;
map< pair<string, int>, set<string>> tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> stmtToIR(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt)
findParameters(const map<string, vector<DefUseList>> &defUseByFunctions,
const map<string, CommonBlock*> &commonBlocks,
const map<string, vector<FuncInfo*>> &allFuncInfo)
{ {
map< pair<string, int>, set<string>> foundParameters; SgStatement* cur = stmt;
cur->switchToFile();
while (cur->variant() != PROC_HEDR && cur->variant() != PROG_HEDR && cur->variant() != FUNC_HEDR)
return foundParameters; cur = cur->controlParent();
}
string funcName = ((SgProcHedrStmt*)cur)->nameWithContains();
int stmtID = stmt->id();
for (const auto& [func, bblocks] : CFGraph)
{
if (func->funcName != funcName)
continue;
for (auto basicBlock : bblocks)
for (auto ins : basicBlock->getInstructions())
if (stmtID == ins->getInstruction()->getOperator()->id())
return make_tuple(func, ins->getInstruction(), basicBlock);
}
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return { NULL, NULL, NULL };
}
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> IRByNumber(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, int num)
{
if (num < 0)
return { NULL, NULL, NULL };
for (const auto& [func, bblocks] : CFGraph)
for (auto byBB : bblocks)
if (byBB->getInstructions().front()->getNumber() <= num && byBB->getInstructions().back()->getNumber() >= num)
return make_tuple(func, getInstructionByNumber(byBB->getInstructions(), num), byBB);
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return { NULL, NULL, NULL};
}
template<typename Iterator>
void processArgument(set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* arg,
Iterator instr,
Iterator first_instr)
{
if (arg == NULL)
return;
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
extract_vars_from_reg(worklist, arg, instr, first_instr);
else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
{
worklist.insert(arg);
}
}
template<typename Iterator>
void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* reg,
Iterator instr,
Iterator first_instr)
{
for (; instr >= first_instr; instr--)
{
if ((*instr)->getInstruction()->getResult() == reg)
{
processArgument(worklist, (*instr)->getInstruction()->getArg1(), instr, first_instr);
processArgument(worklist, (*instr)->getInstruction()->getArg2(), instr, first_instr);
return;
}
}
}
void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& where_to_add,
set<SAPFOR::Argument*>& worklist,
SAPFOR::Instruction* instr,
SAPFOR::BasicBlock* bblock,
FuncInfo* cur_func,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
{
while (bblock)
{
auto first_instr = bblock->getInstructions().begin();
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
return i->getInstruction() == instr;
});
for (; cur_instr >= bblock->getInstructions().begin(); cur_instr--)
{
auto instr = (*cur_instr)->getInstruction();
auto result_arg = instr->getResult();
auto arg1 = instr->getArg1();
auto arg2 = instr->getArg2();
if (worklist.count(result_arg))
{
processArgument(worklist, arg1, cur_instr, first_instr);
processArgument(worklist, arg2, cur_instr, first_instr);
worklist.erase(result_arg);
}
if (instr->getOperation() == SAPFOR::CFG_OP::PARAM && worklist.count(arg1))
{
// skip to F_CALL
auto f_call_instr = cur_instr;
while ((*f_call_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL)
f_call_instr++;
if ((*f_call_instr)->getInstruction()->getArg1()->getValue() == "_READ")
{
auto stmt_before = (*f_call_instr)->getInstruction()->getOperator();
auto filename = stmt_before->fileName();
auto line = stmt_before->lineNumber();
auto var_name = arg1->getValue().substr(arg1->getValue().find('%') + 1);
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg1->getValue().c_str(), line, filename);
auto toAdd = make_tuple(stmt_before, var_name, MODE::AFTER);
where_to_add.insert(toAdd);
worklist.erase(arg1);
}
}
}
const auto& RD = bblock->getRD_In();
map<SAPFOR::BasicBlock*, SAPFOR::Instruction*> group_by_block;
for (auto& arg : worklist)
{
if (RD.count(arg))
{
if (RD.at(arg).size() == 1 && *RD.at(arg).begin() == SAPFOR::CFG_VAL::UNINIT)
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
else if (RD.at(arg).size() > 1)
{
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
auto filename = stmt_after->fileName();
auto line = stmt_after->lineNumber();
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
where_to_add.insert(toAdd);
worklist.erase(arg);
}
else
{
auto instr_num = *RD.at(arg).begin();
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
if (cur_func == func && (group_by_block[bblock] == NULL || group_by_block[bblock]->getNumber() < instr_num))
group_by_block[bblock] = instr;
}
}
}
while (bblock && group_by_block.find(bblock) == group_by_block.end())
bblock = bblock->getIdom();
if (bblock)
instr = group_by_block[bblock];
}
// other variables are from global scope
const auto& RD = fullIR.at(cur_func).front()->getRD_In();
for (auto& arg : worklist)
{
if (arg->isMemGlobal())
{
set<int> found_rd;
if (RD.count(arg))
found_rd = RD.at(arg);
if (found_rd.size() == 0)
{
auto call_instr = call_sites[cur_func].size() ? call_sites[cur_func].front() : NULL;
while (call_instr && found_rd.size() == 0)
{
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
if (call_bblock->getRD_Out().count(arg))
found_rd = call_bblock->getRD_Out().at(arg);
call_instr = call_sites[call_func].size() ? call_sites[call_func].front() : NULL;
}
}
if (found_rd.size() == 1 && *found_rd.begin() == SAPFOR::CFG_VAL::UNINIT)
{
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
} else if (found_rd.size() > 1)
{
auto first_instr = fullIR.at(cur_func).front()->getInstructions().begin();
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
auto filename = stmt_after->fileName();
auto line = stmt_after->lineNumber();
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
where_to_add.insert(toAdd);
}
else
{
auto instr_num = *found_rd.begin();
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
set<SAPFOR::Argument*> new_worklist = {arg};
lookup_for_vars(where_to_add, new_worklist, instr, bblock, func, fullIR);
}
}
}
for (const auto& call_instr : call_sites[cur_func])
{
set<SAPFOR::Argument*> new_worklist;
auto params_num = cur_func->funcParams.countOfPars;
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
auto first_instr = call_bblock->getInstructions().begin();
auto cur_instr = std::find_if(first_instr, call_bblock->getInstructions().end(), [call_instr](SAPFOR::IR_Block* i) {
return i->getInstruction() == call_instr;
});
for (auto& arg : worklist)
{
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
{
auto param_num= stoi(arg->getValue().substr(arg->getValue().find('%', arg->getValue().find('%') + 1) + 1));
auto param_instr = (cur_instr - (params_num - param_num));
auto param_arg = (*param_instr)->getInstruction()->getArg1();
processArgument(new_worklist, param_arg, param_instr, first_instr);
}
}
lookup_for_vars(where_to_add, new_worklist, call_instr, call_bblock, call_func, fullIR);
}
}
void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add,
SgStatement* alloc_statement,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
{
auto [func, instr, bblock] = stmtToIR(fullIR, alloc_statement);
auto first_instr = bblock->getInstructions().begin();
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
return i->getInstruction() == instr;
});
auto alloc_instr = cur_instr;
// skip to F_CALL _ALLOC n
while ((*alloc_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL ||
(*alloc_instr)->getInstruction()->getArg1()->getValue() != "_ALLOC")
alloc_instr++;
auto arrays_num = stoi((*alloc_instr)->getInstruction()->getArg2()->getValue());
set<SAPFOR::Argument*> worklist;
for (int i = 0; i < arrays_num; i++)
{
auto param_instr = --alloc_instr;
auto param_reg = (*param_instr)->getInstruction()->getArg1();
while ((*param_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::LOAD ||
(*param_instr)->getInstruction()->getResult() != param_reg)
param_instr--;
auto dimensions_num = stoi((*param_instr)->getInstruction()->getArg2()->getValue());
for (int j = 0; j < dimensions_num; j++)
{
auto ref_instr = --param_instr;
if ((*ref_instr)->getInstruction()->getOperation() == SAPFOR::CFG_OP::RANGE)
{
vector<SAPFOR::Argument*> range_args = {(*ref_instr)->getInstruction()->getArg1(),
(*ref_instr)->getInstruction()->getArg2(),
(*ref_instr)->getInstruction()->getResult()};
for (auto& arg : range_args)
processArgument(worklist, arg, ref_instr, first_instr);
} else
{
auto arg = (*ref_instr)->getInstruction()->getArg1();
processArgument(worklist, arg, ref_instr, first_instr);
}
}
}
lookup_for_vars(where_to_add,worklist, instr, bblock, func, fullIR);
}
void handle_single_loop(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add,
SgStatement* loop_stmt,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
{
auto [func, instr, bblock] = stmtToIR(fullIR, loop_stmt);
auto cur_instr = bblock->getInstructions().end() - 1;
set<SAPFOR::Argument*> worklist;
extract_vars_from_reg(worklist, (*cur_instr)->getInstruction()->getResult(), cur_instr, bblock->getInstructions().begin());
lookup_for_vars(where_to_add, worklist, (*cur_instr)->getInstruction(), bblock, func, fullIR);
}
void
findParameters(ResultSet& foundParameters,
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
{
set<tuple<SgStatement*, string, MODE>> where_to_add;
map<string, FuncInfo*> name_to_func;
for (const auto& [func, _] : fullIR)
name_to_func[func->funcName] = func;
for (auto& [func, bblocks] : fullIR)
{
for (const auto& block : bblocks)
for (const auto& ir_block : block->getInstructions())
{
auto instr = ir_block->getInstruction();
if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
{
auto func_name = instr->getArg1()->getValue();
auto func_info = name_to_func.find(func_name);
if (func_info != name_to_func.end())
call_sites[func_info->second].push_back(instr);
}
}
SAPFOR::buildDominatorTreeLT(bblocks);
}
std::set<SgStatement*> alloc_statements;
for (const auto& [func, bblocks] : fullIR)
for (const auto& block : bblocks)
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
{
auto op = (*instr)->getInstruction()->getOperator();
if (op && op->variant() == ALLOCATE_STMT) {
alloc_statements.insert(op);
}
}
set<SgStatement*> for_statements;
// Find all FOR statements in the program
for (const auto& [func, bblocks] : fullIR)
for (const auto& block : bblocks)
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
{
auto op = (*instr)->getInstruction()->getOperator();
if (op && op->variant() == FOR_NODE)
for_statements.insert(op);
}
for (const auto& alloc_statement : alloc_statements)
handle_single_allocate(where_to_add, alloc_statement, fullIR);
for (const auto& stmt : for_statements)
handle_single_loop(where_to_add, stmt, fullIR);
for (const auto& [stmt_before, var_name, mode] : where_to_add)
{
stmt_before->switchToFile();
SgVariableSymb* var_symb = new SgVariableSymb(var_name.c_str());
SgVarRefExp* var = new SgVarRefExp(var_symb);
SgValueExp* zero = new SgValueExp(1337);
SgExprListExp* ex = new SgExprListExp();
auto assgn_op = new SgExpression(ASSGN_OP, var, zero);
ex->setLhs(assgn_op);
SgExpression* parameter_op = new SgExpression(SPF_PARAMETER_OP, ex);
auto dir_list = new SgExprListExp();
dir_list->setLhs(parameter_op);
SgStatement* toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, dir_list, NULL, NULL);
toAdd->setlineNumber(stmt_before->lineNumber());
toAdd->setLocalLineNumber(stmt_before->lineNumber());
toAdd->setFileId(stmt_before->getFileId());
toAdd->setProject(stmt_before->getProject());
if (mode == MODE::AFTER)
stmt_before->insertStmtAfter(*toAdd, *stmt_before->controlParent());
else
stmt_before->insertStmtBefore(*toAdd, *stmt_before->controlParent());
foundParameters.insert(make_tuple(stmt_before->fileName(), stmt_before->lineNumber(), var_name));
}
}

View File

@@ -1,3 +1,42 @@
#pragma once #pragma once
std::map< std::pair<std::string, int>, std::set<std::string>> findParameters(const std::map<std::string, std::vector<DefUseList>> &defUseByFunctions, const std::map<std::string, CommonBlock*> &commonBlocks, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo); #include "libSage++.h"
#include <map>
#include <string>
#include <set>
#include <vector>
using ResultSet = std::set<std::tuple<std::string, int, std::string>>;
enum class MODE
{
BEFORE,
AFTER
};
static std::map<FuncInfo*, std::vector<SAPFOR::Instruction*>> call_sites;
template<typename Iterator>
void extract_vars_from_reg(std::set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* reg,
Iterator instr,
Iterator first_instr);
template<typename Iterator>
void processArgument(std::set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* arg,
Iterator instr,
Iterator first_instr);
void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& where_to_add,
std::set<SAPFOR::Argument*>& worklist,
SAPFOR::Instruction* instr,
SAPFOR::BasicBlock* bblock,
FuncInfo* cur_func,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR);
void
findParameters(ResultSet& foundParameters,
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);

View File

@@ -331,7 +331,7 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile, unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile,
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, false, true); moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, false, true);
auto itI = filesToInclude.find(file_name); auto itI = filesToInclude.find(file_name);
for (auto& incl : itI->second) for (auto& [_, incl] : itI->second)
if (allIncludeFiles.find(incl) != allIncludeFiles.end()) if (allIncludeFiles.find(incl) != allIncludeFiles.end())
allIncludeFiles.erase(incl); allIncludeFiles.erase(incl);
} }
@@ -827,20 +827,27 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{ {
auto fileIt = includeDependencies.find(file_name); auto fileIt = includeDependencies.find(file_name);
if (fileIt == includeDependencies.end()) if (fileIt == includeDependencies.end())
fileIt = includeDependencies.insert(fileIt, make_pair(file_name, set<string>())); fileIt = includeDependencies.insert(fileIt, make_pair(file_name, vector<pair<int, string>>()));
set<string> modFiles; set<string> modFiles;
for (auto& elem : moduleDecls) for (auto& elem : moduleDecls)
modFiles.insert(elem.second); modFiles.insert(elem.second);
for (SgStatement *first = file->firstStatement(); first; first = first->lexNext()) SgStatement* lastFromFile = NULL;
for (SgStatement *st = file->firstStatement(); st; st = st->lexNext())
{ {
if (strcmp(file_name, first->fileName())) if (st->variant() == MODULE_STMT && modFiles.find(st->fileName()) != modFiles.end())
st = st->lastNodeOfStmt();
else
{ {
if (first->variant() == MODULE_STMT && modFiles.find(first->fileName()) != modFiles.end()) if (strcmp(file_name, st->fileName()))
first = first->lastNodeOfStmt(); {
if (lastFromFile == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
fileIt->second.push_back(make_pair(lastFromFile->lineNumber(), st->fileName()));
}
else else
fileIt->second.insert(first->fileName()); lastFromFile = st;
} }
} }
@@ -1596,9 +1603,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
set<string> includedToThisFile; set<string> includedToThisFile;
if (itDep != includeDependencies.end()) if (itDep != includeDependencies.end())
{ {
for (auto &inclDep : itDep->second) for (auto& [_, incl] : itDep->second)
{ {
auto comm = commentsToInclude.find(inclDep); auto comm = commentsToInclude.find(incl);
if (comm != commentsToInclude.end()) if (comm != commentsToInclude.end())
for (auto &allComm : comm->second) for (auto &allComm : comm->second)
includedToThisFile.insert(allComm.second.begin(), allComm.second.end()); includedToThisFile.insert(allComm.second.begin(), allComm.second.end());
@@ -1881,7 +1888,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == RENAME_SYMBOLS) else if (curr_regime == RENAME_SYMBOLS)
runRenameSymbols(&project, commonBlocks); runRenameSymbols(&project, commonBlocks);
else if (curr_regime == FIND_PARAMETERS) else if (curr_regime == FIND_PARAMETERS)
parametersOfProject = findParameters(defUseByFunctions, commonBlocks, allFuncInfo); {
findParameters(parametersOfProject, fullIR, declaredArrays);
}
else if (curr_regime == BUILD_IR) else if (curr_regime == BUILD_IR)
{ {
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0)); auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
@@ -2360,6 +2369,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case LOOPS_COMBINER: case LOOPS_COMBINER:
case FIX_COMMON_BLOCKS: case FIX_COMMON_BLOCKS:
case TEST_PASS: case TEST_PASS:
case FIND_PARAMETERS:
case SET_IMPLICIT_NONE: case SET_IMPLICIT_NONE:
runAnalysis(*project, curr_regime, false); runAnalysis(*project, curr_regime, false);
case SUBST_EXPR_RD_AND_UNPARSE: case SUBST_EXPR_RD_AND_UNPARSE:

View File

@@ -85,7 +85,7 @@ std::map<std::string, std::map<int, std::set<std::string>>> commentsToInclude;
// //
//for INSERT_INCLUDES //for INSERT_INCLUDES
std::map<std::string, std::set<std::string>> filesToInclude; // file -> includes std::map<std::string, std::vector<std::pair<int, std::string>>> filesToInclude; // file -> includes [nearest line, include]
// //
//for PASSES DEPENDENSIES //for PASSES DEPENDENSIES
@@ -96,7 +96,7 @@ std::set<passes> passesIgnoreStateDone;
//for files info //for files info
std::map<std::string, int> lineInfo; // file -> lines count std::map<std::string, int> lineInfo; // file -> lines count
std::map<std::string, std::pair<std::set<int>, std::set<int>>> dirsInfo; // file -> dirs <lines SPF, lines DVM> count std::map<std::string, std::pair<std::set<int>, std::set<int>>> dirsInfo; // file -> dirs <lines SPF, lines DVM> count
std::map<std::string, std::set<std::string>> includeDependencies; // file -> includes std::map<std::string, std::vector<std::pair<int, std::string>>> includeDependencies; // file -> includes [nearest line, include]
std::vector<std::string> filesCompilationOrder; // order of files for unite to one file std::vector<std::string> filesCompilationOrder; // order of files for unite to one file
std::map<std::string, std::map<SgStatement*, std::vector<SgStatement*>>> exctactedModuleStats; // file -> hided excluded modules std::map<std::string, std::map<SgStatement*, std::vector<SgStatement*>>> exctactedModuleStats; // file -> hided excluded modules
// //
@@ -168,7 +168,7 @@ std::map<int, UserFiles> filesInfo; // information about open,close,write and re
// //
//for FIND_PARAMETERS //for FIND_PARAMETERS
std::map< std::pair<std::string, int>, std::set<std::string>> parametersOfProject; // [file, line] -> set[vars] std::set<std::tuple<std::string, int, std::string>> parametersOfProject; // [file, line, varname]
// //
//for GET_MIN_MAX_BLOCK_DIST //for GET_MIN_MAX_BLOCK_DIST

View File

@@ -309,6 +309,8 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
Pass(REMOVE_OMP_DIRS) <= Pass(REMOVE_OMP_DIRS_TRANSFORM); Pass(REMOVE_OMP_DIRS) <= Pass(REMOVE_OMP_DIRS_TRANSFORM);
Pass(VERIFY_INCLUDES) <= Pass(RENAME_INLCUDES);
list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(REMOVE_DEAD_CODE); list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(REMOVE_DEAD_CODE);
list({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE); list({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_SPF "2406" #define VERSION_SPF "2414"

View File

@@ -1308,13 +1308,12 @@ int SPF_GetIntrinsics(void*& context, short *&result)
return (int)resVal.size() + 1; return (int)resVal.size() + 1;
} }
extern map<string, set<string>> includeDependencies; extern map<string, vector<pair<int, string>>> includeDependencies;
int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, short *projName, short *&result, short*& output, int*& outputSize, int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, short *projName, short *&result, short*& output, int*& outputSize,
short*& outputMessage, int*& outputMessageSize) short*& outputMessage, int*& outputMessageSize)
{ {
MessageManager::clearCache(); MessageManager::clearCache();
MessageManager::setWinHandler(winHandler); MessageManager::setWinHandler(winHandler);
string resVal = "";
setOptions(options); setOptions(options);
int retSize = 0; int retSize = 0;
@@ -1322,23 +1321,28 @@ int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, s
{ {
runPassesForVisualizer(projName, { BUILD_INCLUDE_DEPENDENCIES }); runPassesForVisualizer(projName, { BUILD_INCLUDE_DEPENDENCIES });
int i = 0; json inc_array = json::array();
for (auto &deps : includeDependencies) for (const auto& deps : includeDependencies)
{ {
if (i != 0) json includes;
resVal += "@"; includes["file"] = deps.first;
resVal += deps.first + "@";
int k = 0; json array = json::array();
for (auto &incl : deps.second) for (const auto& [line, incl] : deps.second)
{ {
if (k != 0) json elem;
resVal += "|"; elem["line"] = line;
resVal += incl; elem["dependencyFileName"] = incl;
++k; array.push_back(elem);
} }
++i; includes["includes"] = array;
inc_array.push_back(includes);
} }
json allIncludes;
allIncludes["allIncludes"] = inc_array;
string resVal = allIncludes.dump();
copyStringToShort(result, resVal); copyStringToShort(result, resVal);
retSize = (int)resVal.size() + 1; retSize = (int)resVal.size() + 1;
} }
@@ -1460,19 +1464,33 @@ int SPF_GetFileLineInfo(void*& context, int winHandler, short *options, short *p
{ {
runPassesForVisualizer(projName, { FILE_LINE_INFO }); runPassesForVisualizer(projName, { FILE_LINE_INFO });
string resVal = ""; json metric_array = json::array();
for (auto it = lineInfo.begin(); it != lineInfo.end(); ++it) for (const auto& fileInfo : lineInfo)
{ {
if (it != lineInfo.begin()) json fileMetric;
resVal += "@";
auto itD = dirsInfo.find(it->first); fileMetric["file"] = fileInfo.first;
if (itD == dirsInfo.end()) fileMetric["linesCount"] = fileInfo.second;
resVal += it->first + "@" + to_string(it->second) + "_0_0";
auto it = dirsInfo.find(fileInfo.first);
if (it == dirsInfo.end())
{
fileMetric["numSPF"] = 0;
fileMetric["numDVM"] = 0;
}
else else
resVal += it->first + "@" + to_string(it->second) + "_" + to_string(itD->second.first.size()) + "_" + to_string(itD->second.second.size()); {
fileMetric["numSPF"] = (int)it->second.first.size();
fileMetric["numDVM"] = (int)it->second.second.size();
}
metric_array.push_back(fileMetric);
} }
json allMetrics;
allMetrics["allMetrics"] = metric_array;
string resVal = allMetrics.dump();
copyStringToShort(result, resVal); copyStringToShort(result, resVal);
retSize = (int)resVal.size() + 1; retSize = (int)resVal.size() + 1;
} }
@@ -2171,38 +2189,44 @@ int SPF_InlineProcedures(void*& context, int winHandler, short* options, short*
} }
extern map<string, set<string>> filesToInclude; extern map<string, vector<pair<int, string>>> filesToInclude;
int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *filesToInclude, int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *visFilesToInclude,
short *&output, int *&outputSize, short *&outputMessage, int *&outputMessageSize) short *&output, int *&outputSize, short *&outputMessage, int *&outputMessageSize)
{ {
MessageManager::clearCache(); MessageManager::clearCache();
MessageManager::setWinHandler(winHandler); MessageManager::setWinHandler(winHandler);
if (filesToInclude == NULL) if (visFilesToInclude == NULL)
return -2; return -2;
vector<string> splited; vector<string> splited;
//printf("%s\n", conv); //printf("%s\n", conv);
splitString(filesToInclude, '|', splited); splitString(visFilesToInclude, '|', splited);
if (splited.size() == 0) if (splited.size() == 0)
return -3; return -3;
::filesToInclude.clear(); filesToInclude.clear();
for (int i = 0; i < splited.size(); ++i) unsigned i = 0;
while (i < splited.size())
{ {
string file = splited[i]; string file = splited[i++];
int num = 0; int num = 0;
if (sscanf(splited[i + 1].c_str(), "%d", &num) == -1) if (sscanf(splited[i++].c_str(), "%d", &num) == -1)
return -3; return -4;
__spf_print(1, "file = %s:\n", file.c_str()); __spf_print(1, "file = %s:\n", file.c_str());
for (int k = i + 2; k < i + 2 + num; ++k) for (int k = i; k < i + 2 * num; k += 2)
{ {
::filesToInclude[file].insert(splited[k]); int line = 0;
__spf_print(1, " include = %s\n", splited[k].c_str()); if (sscanf(splited[k].c_str(), "%d", &line) == -1)
return -5;
auto pair = make_pair(line, splited[k + 1]);
filesToInclude[file].push_back(pair);
__spf_print(1, " include = [%d %s]\n", pair.first, pair.second.c_str());
} }
i += 1 + num; i += 2 * num;
} }
return simpleTransformPass(INSERT_INCLUDES, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize); return simpleTransformPass(INSERT_INCLUDES, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
} }

View File

@@ -0,0 +1,52 @@
program dynamic_array_maximum_3d
implicit none
integer :: n1, n2, n3, n4 , k, i, j, l, a
integer :: sum3
real :: max_element
real, allocatable :: array(:,:,:), array2(:,:,:), array3(:,:,:)
write(*, *) "Enter 3 integers"
read(*, *) n, m, k
m = 100
if (1 .eq. 1) then
a = 3
else if (2 .eq. 1) then
a = 4
endif
m = m + 1
k = m * 1000 + n * 10
allocate(array(n, m + n, k + m + n), &
&array2(k, m + n, k), &
&array3(k, m, k + n))
call random_seed()
do i = 1, n1
do j = 1, m * n1
do l = 1, k * m * n1
call random_number(array(i,j,l))
array(i,j,l) = int(array(i,j,l) * 100)
end do
end do
end do
max_element = array(1,1,1)
do i = 1, n1
do j = 1, m
do l = 1, k
max_element = MAX(array(i,j,l), max_element)
end do
end do
end do
deallocate(array, array2, array3)
write(*, *) max_element
end program dynamic_array_maximum_3d
! function sum3(x, y, z)
! implicit none
! integer :: x, y, z
! integer :: sum3
! sum3 = x + y + z
! end function sum3