From 2d84aaff1f8287756cefa97c5663b33698306a2e Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 25 Mar 2025 15:18:49 +0300 Subject: [PATCH 01/20] New pass --- CMakeLists.txt | 6 +++++- src/Sapfor.cpp | 5 +++++ src/Sapfor.h | 3 +++ src/SwapOperators/swapOperators.cpp | 14 ++++++++++++++ src/SwapOperators/swapOperators.h | 6 ++++++ src/Utils/PassManager.h | 2 ++ 6 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/SwapOperators/swapOperators.cpp create mode 100644 src/SwapOperators/swapOperators.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 580342b..9d124f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,6 +208,8 @@ set(TR_INLINER src/Transformations/FunctionInlining/inliner.cpp src/Transformations/FunctionInlining/inliner.h) set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp src/Transformations/RenameSymbols/rename_symbols.h) +SET(SWAP_OPERATORS src/SwapOperators/swapOperators.cpp + src/SwapOperators/swapOperators.h) set(TRANSFORMS ${TR_DEAD_CODE} @@ -438,7 +440,8 @@ set(SOURCE_EXE ${ZLIB} ${GR_LAYOUT} ${PR_PARAM} - ${PROJ_MAN}) + ${PROJ_MAN} + ${SWAP_OPERATORS}) add_executable(Sapfor_F ${SOURCE_EXE}) source_group (CFGraph FILES ${CFG}) @@ -483,6 +486,7 @@ source_group (Utils FILES ${UTILS}) source_group (VerificationCode FILES ${VERIF}) source_group (ProjectParameters FILES ${PR_PARAM}) source_group (ProjectManipulation FILES ${PROJ_MAN}) +source_group (SwapOperators FILES ${SWAP_OPERATORS}) source_group (VisualizerCalls FILES ${VS_CALLS}) source_group (VisualizerCalls\\GraphLayout FILES ${GR_LAYOUT}) diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index d37f078..ddebbc1 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -90,6 +90,7 @@ #include "Transformations/DeadCodeRemoving/dead_code.h" #include "Transformations/RenameSymbols/rename_symbols.h" #include "Transformations/FunctionInlining/inliner.h" +#include "SwapOperators/swapOperators.h" #include "ProjectParameters/projectParameters.h" @@ -941,6 +942,10 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne internalExit = err; } } + else if (curr_regime == SWAP_OPERATORS) + { + runSwapOperators(loopGraph, fullIR); + } else if (curr_regime == PRIVATE_REMOVING_ANALYSIS) { auto itFound = loopGraph.find(file->filename()); diff --git a/src/Sapfor.h b/src/Sapfor.h index 7f21c22..7c2b74c 100644 --- a/src/Sapfor.h +++ b/src/Sapfor.h @@ -122,6 +122,8 @@ enum passes { CREATE_INTER_TREE, INSERT_INTER_TREE, + SWAP_OPERATORS, + SHADOW_GROUPING, INLINE_PROCEDURES, FILL_PARALLEL_REG_IR, @@ -321,6 +323,7 @@ static void setPassValues() passNames[CHECK_PAR_REG_DIR] = "CHECK_PAR_REG_DIR"; passNames[CREATE_INTER_TREE] = "CREATE_INTER_TREE"; passNames[INSERT_INTER_TREE] = "INSERT_INTER_TREE"; + passNames[SWAP_OPERATORS] = "SWAP_OPERATORS"; passNames[CREATE_PARALLEL_REGIONS] = "CREATE_PARALLEL_REGIONS"; passNames[PRIVATE_REMOVING_ANALYSIS] = "PRIVATE_REMOVING_ANALYSIS"; passNames[PRIVATE_REMOVING] = "PRIVATE_REMOVING"; diff --git a/src/SwapOperators/swapOperators.cpp b/src/SwapOperators/swapOperators.cpp new file mode 100644 index 0000000..d86615b --- /dev/null +++ b/src/SwapOperators/swapOperators.cpp @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include + +#include "swapOperators.h" + + +void runSwapOperators(std::map>& loopGraph, std::map>& FullIR) +{ + std::cout << "SWAP_OPERATORS Pass" << std::endl; + return; +}; \ No newline at end of file diff --git a/src/SwapOperators/swapOperators.h b/src/SwapOperators/swapOperators.h new file mode 100644 index 0000000..7120367 --- /dev/null +++ b/src/SwapOperators/swapOperators.h @@ -0,0 +1,6 @@ +#pragma once + +#include "../GraphLoop/graph_loops.h" +#include "../CFGraph/CFGraph.h" + +void runSwapOperators(std::map>& loopGraph, std::map>& FullIR); diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index f2715d3..cdf1b79 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -212,6 +212,8 @@ void InitPassesDependencies(map> &passDepsIn, set Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE); + Pass(BUILD_IR) <= Pass(SWAP_OPERATORS) <= Pass(PRIVATE_REMOVING); + list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS); list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING); From 3b9e4653b63f188a7dd9f3da97bb4a27b9faadfe Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Sat, 29 Mar 2025 15:41:58 +0300 Subject: [PATCH 02/20] change pass deps --- src/Utils/PassManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index cdf1b79..a9a866a 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -212,7 +212,7 @@ void InitPassesDependencies(map> &passDepsIn, set Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE); - Pass(BUILD_IR) <= Pass(SWAP_OPERATORS) <= Pass(PRIVATE_REMOVING); + list({BUILD_IR, CALL_GRAPH2}) <= Pass(SWAP_OPERATORS); list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS); list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING); From e5fa2e41b357dd6fdc9486ee94246bf696119f32 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 15 Apr 2025 18:10:13 +0300 Subject: [PATCH 03/20] Pass with output file added --- src/Sapfor.cpp | 6 ++++-- src/SwapOperators/swapOperators.cpp | 3 ++- src/SwapOperators/swapOperators.h | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index ddebbc1..b48858e 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -944,7 +944,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne } else if (curr_regime == SWAP_OPERATORS) { - runSwapOperators(loopGraph, fullIR); + runSwapOperators(loopGraph, fullIR, countOfTransform); } else if (curr_regime == PRIVATE_REMOVING_ANALYSIS) { @@ -1042,7 +1042,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne PRIVATE_REMOVING, PRIVATE_ARRAYS_EXPANSION, PRIVATE_ARRAYS_SHRINKING, - REMOVE_DEAD_CODE }; + REMOVE_DEAD_CODE, + SWAP_OPERATORS }; if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end()) { @@ -2344,6 +2345,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam case INSERT_NO_DISTR_FLAGS_FROM_GUI: case PRIVATE_REMOVING: case RENAME_INLCUDES: + case SWAP_OPERATORS: runAnalysis(*project, curr_regime, true, "", folderName); break; case INLINE_PROCEDURES: diff --git a/src/SwapOperators/swapOperators.cpp b/src/SwapOperators/swapOperators.cpp index d86615b..54cc60b 100644 --- a/src/SwapOperators/swapOperators.cpp +++ b/src/SwapOperators/swapOperators.cpp @@ -7,8 +7,9 @@ #include "swapOperators.h" -void runSwapOperators(std::map>& loopGraph, std::map>& FullIR) +void runSwapOperators(std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) { std::cout << "SWAP_OPERATORS Pass" << std::endl; + countOfTransform += 1; return; }; \ No newline at end of file diff --git a/src/SwapOperators/swapOperators.h b/src/SwapOperators/swapOperators.h index 7120367..b159c44 100644 --- a/src/SwapOperators/swapOperators.h +++ b/src/SwapOperators/swapOperators.h @@ -3,4 +3,4 @@ #include "../GraphLoop/graph_loops.h" #include "../CFGraph/CFGraph.h" -void runSwapOperators(std::map>& loopGraph, std::map>& FullIR); +void runSwapOperators(std::map>& loopGraph, std::map>& FullIR, int& countOfTransform); From 61c6ad136346ca6caa00432343acc4c767a00fea Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 13 May 2025 00:46:32 +0300 Subject: [PATCH 04/20] Some actions simplify analyzing IR --- src/Sapfor.cpp | 2 +- src/SwapOperators/swapOperators.cpp | 96 +++++++++++++++++++++++++++-- src/SwapOperators/swapOperators.h | 2 +- 3 files changed, 94 insertions(+), 6 deletions(-) diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index b48858e..eb280d5 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -944,7 +944,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne } else if (curr_regime == SWAP_OPERATORS) { - runSwapOperators(loopGraph, fullIR, countOfTransform); + runSwapOperators(file, loopGraph, fullIR, countOfTransform); } else if (curr_regime == PRIVATE_REMOVING_ANALYSIS) { diff --git a/src/SwapOperators/swapOperators.cpp b/src/SwapOperators/swapOperators.cpp index 54cc60b..e0f68a2 100644 --- a/src/SwapOperators/swapOperators.cpp +++ b/src/SwapOperators/swapOperators.cpp @@ -4,12 +4,100 @@ #include #include +#include "../Utils/errors.h" +#include "../Utils/SgUtils.h" +#include "../GraphCall/graph_calls.h" +#include "../GraphCall/graph_calls_func.h" +#include "../CFGraph/CFGraph.h" +#include "../CFGraph/IR.h" +#include "../GraphLoop/graph_loops.h" #include "swapOperators.h" +using namespace std; -void runSwapOperators(std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) + +unordered_set loop_tags = {FOR_NODE/*, FORALL_NODE, WHILE_NODE, DO_WHILE_NODE*/}; + + +vector findInstructionsFromOperator(SgStatement* st, vector Blocks) { - std::cout << "SWAP_OPERATORS Pass" << std::endl; - countOfTransform += 1; + vector result; + string filename = st -> fileName(); + for (auto& block: Blocks) + { + vector instructionsInBlock = block -> getInstructions(); + for (auto& instruction: instructionsInBlock) + { + SgStatement* curOperator = instruction -> getInstruction() -> getOperator(); + if (curOperator -> lineNumber() == st -> lineNumber()) + result.push_back(instruction); + } + } + return result; +} + +vector findFuncBlocksByFuncStatement(SgStatement *st, std::map>& FullIR) +{ + vector result; + Statement* forSt = (Statement*)st; + for (auto& func : FullIR) + { + if (func.first -> funcPointer -> getCurrProcessFile() == forSt -> getCurrProcessFile() + && func.first -> funcPointer -> lineNumber() == forSt -> lineNumber()) + result = func.second; + } + return result; +} + +map> findAndAnalyzeLoops(SgStatement *st, vector blocks) +{ + map> result; + SgStatement *lastNode = st->lastNodeOfStmt(); + while (st && st != lastNode) + { + if (loop_tags.find(st -> variant()) != loop_tags.end()) + { + // part with find statements of loop + SgForStmt *forSt = (SgForStmt*)st; + SgStatement *loopBody = forSt -> body(); + SgStatement *lastLoopNode = st->lastNodeOfStmt(); + // part with find blocks and instructions of loops + while (loopBody && loopBody != lastLoopNode) + { + SAPFOR::IR_Block* IR = findInstructionsFromOperator(loopBody, blocks).front(); + result[forSt].push_back(IR -> getBasicBlock()); // change this part for taking only unique blocks to vector + loopBody = loopBody -> lexNext(); + } + } + st = st -> lexNext(); + } + return result; +} + +vector> AnalyzeLoop(SgForStmt* forStatement, vector loopBlocks) +{ + vector> result; + // Analyze loop and create rules for moving operators in loops + // Return vector with moving rules (from line to line for operators) + return result; +} + +void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) +{ + std::cout << "SWAP_OPERATORS Pass" << std::endl; // to remove + countOfTransform += 1; // to remove + + const int funcNum = file->numberOfFunctions(); + for (int i = 0; i < funcNum; ++i) + { + SgStatement *st = file->functions(i); + vector blocks = findFuncBlocksByFuncStatement(st, FullIR); + map> loopsMapping = findAndAnalyzeLoops(st, blocks); + for (pair> loopForAnalyze: loopsMapping) + { + vector> moveRules = AnalyzeLoop(loopForAnalyze.first, loopForAnalyze.second); + } + } + return; -}; \ No newline at end of file +}; diff --git a/src/SwapOperators/swapOperators.h b/src/SwapOperators/swapOperators.h index b159c44..b66152f 100644 --- a/src/SwapOperators/swapOperators.h +++ b/src/SwapOperators/swapOperators.h @@ -3,4 +3,4 @@ #include "../GraphLoop/graph_loops.h" #include "../CFGraph/CFGraph.h" -void runSwapOperators(std::map>& loopGraph, std::map>& FullIR, int& countOfTransform); +void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform); From 0c20b37923b4be30aad33a5112fb82141daccccb Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Mon, 19 May 2025 22:23:36 +0300 Subject: [PATCH 05/20] Add _bin to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d9bf98a..0957d80 100644 --- a/.gitignore +++ b/.gitignore @@ -78,3 +78,4 @@ Sapfor/Sapc++/x64/ Sapfor/out/ Sapfor/_bin/* +_bin/* From 9e4db270fcd7c3d15cf594512be40d790886d305 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Thu, 22 May 2025 22:41:09 +0300 Subject: [PATCH 06/20] some loop analysis done --- src/SwapOperators/swapOperators.cpp | 71 ++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/src/SwapOperators/swapOperators.cpp b/src/SwapOperators/swapOperators.cpp index e0f68a2..cb76dcb 100644 --- a/src/SwapOperators/swapOperators.cpp +++ b/src/SwapOperators/swapOperators.cpp @@ -62,26 +62,80 @@ map> findAndAnalyzeLoops(SgStatement *st SgStatement *loopBody = forSt -> body(); SgStatement *lastLoopNode = st->lastNodeOfStmt(); // part with find blocks and instructions of loops + unordered_set blocks_nums; while (loopBody && loopBody != lastLoopNode) { SAPFOR::IR_Block* IR = findInstructionsFromOperator(loopBody, blocks).front(); - result[forSt].push_back(IR -> getBasicBlock()); // change this part for taking only unique blocks to vector + if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end()) + { + result[forSt].push_back(IR -> getBasicBlock()); + blocks_nums.insert(IR -> getBasicBlock() -> getNumber()); + } loopBody = loopBody -> lexNext(); } + std::sort(result[forSt].begin(), result[forSt].end()); } st = st -> lexNext(); } return result; } -vector> AnalyzeLoop(SgForStmt* forStatement, vector loopBlocks) +map> AnalyzeLoopAndFindDeps(SgForStmt* forStatement, vector loopBlocks, map>& FullIR) { - vector> result; - // Analyze loop and create rules for moving operators in loops - // Return vector with moving rules (from line to line for operators) + map> result; + for (SAPFOR::BasicBlock* bb: loopBlocks) { + std::map> blockReachingDefinitions = bb -> getRD_In(); + vector instructions = bb -> getInstructions(); + for (SAPFOR::IR_Block* irBlock: instructions) { + SAPFOR::Instruction* instr = irBlock -> getInstruction(); + // take Argument 1 and it's RD and push operators to final set + if (instr -> getArg1() != NULL) { + SAPFOR::Argument* arg = instr -> getArg1(); + set prevInstructionsNumbers = blockReachingDefinitions[arg]; + for (int i: prevInstructionsNumbers) { + SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; + if (foundInstruction != NULL) { + SgStatement* prevOp = foundInstruction -> getOperator(); + if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber()) + result[instr -> getOperator()].insert(prevOp); + } + } + } + // take Argument 2 (if exists) and it's RD and push operators to final set + if (instr -> getArg2() != NULL) { + SAPFOR::Argument* arg = instr -> getArg2(); + set prevInstructionsNumbers = blockReachingDefinitions[arg]; + for (int i: prevInstructionsNumbers) { + SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; + if (foundInstruction != NULL) { + SgStatement* prevOp = foundInstruction -> getOperator(); + if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber()) + result[instr -> getOperator()].insert(prevOp); + } + } + } + // update RD + if (instr -> getResult() != NULL) + blockReachingDefinitions[instr -> getResult()] = {instr -> getNumber()}; + } + } return result; } +int RebuildLoop(int firstLine, int lastLine, map> moveRules) { + // only cout done yet (( + cout << "LOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES\n" << endl; + for (auto r: moveRules) { + cout << "OPERATOR: " << endl; + cout << r.first -> lineNumber() << r.first -> sunparse(); + cout << "DEPENDS FROM NEXT: " << endl; + for (SgStatement* st: r.second) + cout << st -> lineNumber() << endl; + } + cout << "\n\n\n"; + return 0; +} + void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) { std::cout << "SWAP_OPERATORS Pass" << std::endl; // to remove @@ -95,7 +149,12 @@ void runSwapOperators(SgFile *file, std::map> loopsMapping = findAndAnalyzeLoops(st, blocks); for (pair> loopForAnalyze: loopsMapping) { - vector> moveRules = AnalyzeLoop(loopForAnalyze.first, loopForAnalyze.second); + map> moveRules = AnalyzeLoopAndFindDeps(loopForAnalyze.first, loopForAnalyze.second, FullIR); + if (moveRules.size() != 0) { + int firstLine = loopForAnalyze.first -> lineNumber(); + int lastLine = loopForAnalyze.first -> lastNodeOfStmt() -> lineNumber(); + countOfTransform += RebuildLoop(firstLine, lastLine, moveRules); + } } } From 8728f84546694293c224503f806803f64c684407 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Sat, 24 May 2025 19:56:15 +0300 Subject: [PATCH 07/20] biulding new order --- src/SwapOperators/swapOperators.cpp | 149 +++++++++++++++++++++++++--- 1 file changed, 133 insertions(+), 16 deletions(-) diff --git a/src/SwapOperators/swapOperators.cpp b/src/SwapOperators/swapOperators.cpp index cb76dcb..078c872 100644 --- a/src/SwapOperators/swapOperators.cpp +++ b/src/SwapOperators/swapOperators.cpp @@ -80,14 +80,16 @@ map> findAndAnalyzeLoops(SgStatement *st return result; } -map> AnalyzeLoopAndFindDeps(SgForStmt* forStatement, vector loopBlocks, map>& FullIR) +map> AnalyzeLoopAndFindDeps(SgForStmt* forStatement, vector loopBlocks, map>& FullIR) { - map> result; + map> result; for (SAPFOR::BasicBlock* bb: loopBlocks) { std::map> blockReachingDefinitions = bb -> getRD_In(); vector instructions = bb -> getInstructions(); for (SAPFOR::IR_Block* irBlock: instructions) { + // TODO: Think about what to do with function calls and array references. Because there are also dependencies there that are not reflected in RD, but they must be taken into account SAPFOR::Instruction* instr = irBlock -> getInstruction(); + result[instr -> getOperator()]; // take Argument 1 and it's RD and push operators to final set if (instr -> getArg1() != NULL) { SAPFOR::Argument* arg = instr -> getArg1(); @@ -122,18 +124,119 @@ map> AnalyzeLoopAndFindDeps(SgForStmt* return result; } -int RebuildLoop(int firstLine, int lastLine, map> moveRules) { - // only cout done yet (( - cout << "LOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES\n" << endl; - for (auto r: moveRules) { - cout << "OPERATOR: " << endl; - cout << r.first -> lineNumber() << r.first -> sunparse(); - cout << "DEPENDS FROM NEXT: " << endl; - for (SgStatement* st: r.second) - cout << st -> lineNumber() << endl; +// int PrintSmthFromLoop(int firstLine, int lastLine, map> moveRules) { +// // only cout done yet (( +// cout << "LOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES\n" << endl; +// for (auto r: moveRules) { +// cout << "OPERATOR: " << endl; +// cout << r.first -> lineNumber() << r.first -> sunparse(); +// cout << "DEPENDS FROM NEXT: " << endl; +// for (SgStatement* st: r.second) +// cout << st -> lineNumber() << endl; +// } +// cout << "\n\n\n"; +// return 0; +// } + +void GenNodesOfGraph( + const map>& dependencies, + set& allNodes, + map>& outEdges, + map>& inEdges) +{ + for (const auto& node: dependencies) { + SgStatement* u = node.first; + allNodes.insert(u); + for (SgStatement* v: node.second) { + allNodes.insert(v); + outEdges[v].insert(u); + inEdges[u].insert(v); + outEdges[u]; + inEdges[v]; + } + outEdges[u]; + inEdges[u]; } - cout << "\n\n\n"; - return 0; +} + +vector> FindLinksInGraph( + const set& allNodes, + const map>& outEdges, + const map>& inEdges) +{ + set visited; + vector> components; + for (SgStatement* v: allNodes) { + if (visited.count(v)) { + continue; + } + set component; + queue q; + q.push(v); + visited.insert(v); + + while (!q.empty()) { + SgStatement* curr = q.front(); + q.pop(); + component.insert(curr); + for (SgStatement* neighbour: outEdges.at(curr)) { + if (!visited.count(neighbour)) { + q.push(neighbour); visited.insert(neighbour); + } + } + for (SgStatement* neighbour: inEdges.at(curr)) { + if (!visited.count(neighbour)) { + q.push(neighbour); visited.insert(neighbour); + } + } + } + components.push_back(component); + } + return components; +} + +vector SortComponent( + const set& component, + const map>& outEdges, + const map>& inEdges) +{ + map inDegree; + for (auto v: component) { + inDegree[v] = inEdges.at(v).size(); + } + queue q; + for (auto v : component) { + if (inDegree[v] == 0) q.push(v); + } + vector result; + while (!q.empty()) { + auto curr = q.front(); + q.pop(); + result.push_back(curr); + for (SgStatement* neighbour: outEdges.at(curr)) { + if (component.count(neighbour)) { + inDegree[neighbour]--; + if (inDegree[neighbour] == 0) { + q.push(neighbour); + } + } + } + } + return result; +} + +vector SortNoInterleaving(const map>& dependencies) +{ + set allNodes; + map> outEdges, inEdges; + GenNodesOfGraph(dependencies, allNodes, outEdges, inEdges); + auto components = FindLinksInGraph(allNodes, outEdges, inEdges); + vector totalOrder; + for (auto& comp : components) { + auto part = SortComponent(comp, outEdges, inEdges); + totalOrder.insert(totalOrder.end(), part.begin(), part.end()); + } + return totalOrder; } void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) @@ -149,11 +252,25 @@ void runSwapOperators(SgFile *file, std::map> loopsMapping = findAndAnalyzeLoops(st, blocks); for (pair> loopForAnalyze: loopsMapping) { - map> moveRules = AnalyzeLoopAndFindDeps(loopForAnalyze.first, loopForAnalyze.second, FullIR); - if (moveRules.size() != 0) { + map> dependencyGraph = AnalyzeLoopAndFindDeps(loopForAnalyze.first, loopForAnalyze.second, FullIR); + // TODO: Write a function that will go through the operators and update all dependencies so that there are no mix-ups and splits inside the semantic blocks (for if, do and may be some other cases) + cout << "\n\n"; + for (auto v: dependencyGraph) { + cout << "OPERATOR: " << v.first -> lineNumber() << "\nDEPENDS ON:" << endl; + for (auto vv: v.second) { + cout << vv -> lineNumber() << " "; + } + cout << endl; + } + if (dependencyGraph.size() != 0) { int firstLine = loopForAnalyze.first -> lineNumber(); int lastLine = loopForAnalyze.first -> lastNodeOfStmt() -> lineNumber(); - countOfTransform += RebuildLoop(firstLine, lastLine, moveRules); + // countOfTransform += PrintSmthFromLoop(firstLine, lastLine, dependencyGraph); + vector new_order = SortNoInterleaving(dependencyGraph); + cout << "\n\nLOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES\n" << endl; + for (auto v: new_order) + if (v -> lineNumber() > firstLine) + cout << v -> lineNumber() << " "; } } } From c5927fe80fc01bf47f95123004b582d0cb8ea8e1 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Sat, 24 May 2025 23:15:30 +0300 Subject: [PATCH 08/20] update in new order --- src/SwapOperators/swapOperators.cpp | 67 ++++++++++++++++++----------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/src/SwapOperators/swapOperators.cpp b/src/SwapOperators/swapOperators.cpp index 078c872..d9483c7 100644 --- a/src/SwapOperators/swapOperators.cpp +++ b/src/SwapOperators/swapOperators.cpp @@ -17,6 +17,8 @@ using namespace std; unordered_set loop_tags = {FOR_NODE/*, FORALL_NODE, WHILE_NODE, DO_WHILE_NODE*/}; +unordered_set importantDepsTags = {FOR_NODE, IF_NODE, ELSEIF_NODE}; +unordered_set importantEndTags = {CONTROL_END}; vector findInstructionsFromOperator(SgStatement* st, vector Blocks) @@ -124,19 +126,34 @@ map> AnalyzeLoopAndFindDeps(SgForStmt* forStatem return result; } -// int PrintSmthFromLoop(int firstLine, int lastLine, map> moveRules) { -// // only cout done yet (( -// cout << "LOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES\n" << endl; -// for (auto r: moveRules) { -// cout << "OPERATOR: " << endl; -// cout << r.first -> lineNumber() << r.first -> sunparse(); -// cout << "DEPENDS FROM NEXT: " << endl; -// for (SgStatement* st: r.second) -// cout << st -> lineNumber() << endl; -// } -// cout << "\n\n\n"; -// return 0; -// } +void buildAdditionalDeps(SgForStmt* forStatement, map>& dependencies) +{ + SgStatement* lastNode = forStatement->lastNodeOfStmt(); + vector importantDeps; + SgStatement* st = (SgStatement*) forStatement; + SgStatement* logIfOp = NULL; + importantDeps.push_back(st); + while (st && st != lastNode) + { + if (st != importantDeps.back()) { + dependencies[st].insert(importantDeps.back()); + } + if (logIfOp != NULL) { + dependencies[st].insert(logIfOp); + logIfOp = NULL; + } + if (st -> variant() == LOGIF_NODE) { + logIfOp = st; + } + if (importantDepsTags.find(st -> variant()) != importantDepsTags.end()) { + importantDeps.push_back(st); + } + if (importantEndTags.find(st -> variant()) != importantEndTags.end()) { + importantDeps.pop_back(); + } + st = st -> lexNext(); + } +} void GenNodesOfGraph( const map>& dependencies, @@ -254,23 +271,25 @@ void runSwapOperators(SgFile *file, std::map> dependencyGraph = AnalyzeLoopAndFindDeps(loopForAnalyze.first, loopForAnalyze.second, FullIR); // TODO: Write a function that will go through the operators and update all dependencies so that there are no mix-ups and splits inside the semantic blocks (for if, do and may be some other cases) + buildAdditionalDeps(loopForAnalyze.first, dependencyGraph); cout << "\n\n"; - for (auto v: dependencyGraph) { - cout << "OPERATOR: " << v.first -> lineNumber() << "\nDEPENDS ON:" << endl; - for (auto vv: v.second) { - cout << vv -> lineNumber() << " "; - } - cout << endl; - } + int firstLine = loopForAnalyze.first -> lineNumber(); + int lastLine = loopForAnalyze.first -> lastNodeOfStmt() -> lineNumber(); + // for (auto v: dependencyGraph) { + // cout << "OPERATOR: " << v.first -> lineNumber() << "\nDEPENDS ON:" << endl; + // if (v.second.size() != 0) + // for (auto vv: v.second) { + // if (vv -> lineNumber() > firstLine) + // cout << vv -> lineNumber() << " "; + // } + // cout << endl; + // } if (dependencyGraph.size() != 0) { - int firstLine = loopForAnalyze.first -> lineNumber(); - int lastLine = loopForAnalyze.first -> lastNodeOfStmt() -> lineNumber(); - // countOfTransform += PrintSmthFromLoop(firstLine, lastLine, dependencyGraph); vector new_order = SortNoInterleaving(dependencyGraph); cout << "\n\nLOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES\n" << endl; for (auto v: new_order) if (v -> lineNumber() > firstLine) - cout << v -> lineNumber() << " "; + cout << v -> lineNumber() << endl; } } } From 085e6312a361477392b0cf3103d94bfeb1d72445 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 27 May 2025 01:41:50 +0300 Subject: [PATCH 09/20] Use more complex algorythm for building new order of statements --- src/SwapOperators/swapOperators.cpp | 223 ++++++++++++++-------------- 1 file changed, 109 insertions(+), 114 deletions(-) diff --git a/src/SwapOperators/swapOperators.cpp b/src/SwapOperators/swapOperators.cpp index d9483c7..bfe33a2 100644 --- a/src/SwapOperators/swapOperators.cpp +++ b/src/SwapOperators/swapOperators.cpp @@ -17,7 +17,8 @@ using namespace std; unordered_set loop_tags = {FOR_NODE/*, FORALL_NODE, WHILE_NODE, DO_WHILE_NODE*/}; -unordered_set importantDepsTags = {FOR_NODE, IF_NODE, ELSEIF_NODE}; +unordered_set importantDepsTags = {FOR_NODE, IF_NODE}; +unordered_set importantUpdDepsTags = {ELSEIF_NODE}; unordered_set importantEndTags = {CONTROL_END}; @@ -38,7 +39,7 @@ vector findInstructionsFromOperator(SgStatement* st, vector findFuncBlocksByFuncStatement(SgStatement *st, std::map>& FullIR) +vector findFuncBlocksByFuncStatement(SgStatement *st, map>& FullIR) { vector result; Statement* forSt = (Statement*)st; @@ -86,7 +87,7 @@ map> AnalyzeLoopAndFindDeps(SgForStmt* forStatem { map> result; for (SAPFOR::BasicBlock* bb: loopBlocks) { - std::map> blockReachingDefinitions = bb -> getRD_In(); + map> blockReachingDefinitions = bb -> getRD_In(); vector instructions = bb -> getInstructions(); for (SAPFOR::IR_Block* irBlock: instructions) { // TODO: Think about what to do with function calls and array references. Because there are also dependencies there that are not reflected in RD, but they must be taken into account @@ -100,7 +101,8 @@ map> AnalyzeLoopAndFindDeps(SgForStmt* forStatem SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; if (foundInstruction != NULL) { SgStatement* prevOp = foundInstruction -> getOperator(); - if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber()) + if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber() + && prevOp -> lineNumber() > forStatement -> lineNumber()) result[instr -> getOperator()].insert(prevOp); } } @@ -113,7 +115,8 @@ map> AnalyzeLoopAndFindDeps(SgForStmt* forStatem SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; if (foundInstruction != NULL) { SgStatement* prevOp = foundInstruction -> getOperator(); - if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber()) + if (prevOp != forStatement && instr -> getOperator() != forStatement&& instr -> getOperator() -> lineNumber() > prevOp -> lineNumber() + && prevOp -> lineNumber() > forStatement -> lineNumber()) result[instr -> getOperator()].insert(prevOp); } } @@ -131,12 +134,13 @@ void buildAdditionalDeps(SgForStmt* forStatement, maplastNodeOfStmt(); vector importantDeps; SgStatement* st = (SgStatement*) forStatement; + st = st -> lexNext(); SgStatement* logIfOp = NULL; - importantDeps.push_back(st); while (st && st != lastNode) { - if (st != importantDeps.back()) { - dependencies[st].insert(importantDeps.back()); + if(importantDeps.size() != 0) + if (st != importantDeps.back()) { + dependencies[st].insert(importantDeps.back()); } if (logIfOp != NULL) { dependencies[st].insert(logIfOp); @@ -148,123 +152,117 @@ void buildAdditionalDeps(SgForStmt* forStatement, map variant()) != importantDepsTags.end()) { importantDeps.push_back(st); } - if (importantEndTags.find(st -> variant()) != importantEndTags.end()) { + if (importantUpdDepsTags.find(st -> variant()) != importantUpdDepsTags.end()) { importantDeps.pop_back(); + importantDeps.push_back(st); + } + if (importantEndTags.find(st -> variant()) != importantEndTags.end()) { + if(importantDeps.size() != 0) + importantDeps.pop_back(); } st = st -> lexNext(); } } -void GenNodesOfGraph( - const map>& dependencies, - set& allNodes, - map>& outEdges, - map>& inEdges) -{ - for (const auto& node: dependencies) { - SgStatement* u = node.first; - allNodes.insert(u); - for (SgStatement* v: node.second) { - allNodes.insert(v); - outEdges[v].insert(u); - inEdges[u].insert(v); - outEdges[u]; - inEdges[v]; - } - outEdges[u]; - inEdges[u]; +struct ReadyOp { + SgStatement* stmt; + int degree; + size_t arrival; + ReadyOp(SgStatement* s, int d, size_t a): stmt(s), degree(d), arrival(a) {} +}; + +struct ReadyOpCompare { + bool operator()(const ReadyOp& a, const ReadyOp& b) const { + if (a.degree != b.degree) + return a.degree > b.degree; + else + return a.arrival > b.arrival; } -} +}; -vector> FindLinksInGraph( - const set& allNodes, - const map>& outEdges, - const map>& inEdges) -{ - set visited; - vector> components; - for (SgStatement* v: allNodes) { - if (visited.count(v)) { - continue; - } - set component; - queue q; - q.push(v); - visited.insert(v); - - while (!q.empty()) { - SgStatement* curr = q.front(); - q.pop(); - component.insert(curr); - for (SgStatement* neighbour: outEdges.at(curr)) { - if (!visited.count(neighbour)) { - q.push(neighbour); visited.insert(neighbour); - } - } - for (SgStatement* neighbour: inEdges.at(curr)) { - if (!visited.count(neighbour)) { - q.push(neighbour); visited.insert(neighbour); - } +vector scheduleOperations( + const map>& dependencies +) { + // get all statements + unordered_set allStmtsSet; + for (const auto& pair : dependencies) { + allStmtsSet.insert(pair.first); + for (SgStatement* dep : pair.second) + allStmtsSet.insert(dep); + } + vector allStmts(allStmtsSet.begin(), allStmtsSet.end()); + // count deps and build reversed graph + unordered_map> graph; + unordered_map inDegree; + unordered_map degree; + for (auto op : allStmts) + inDegree[op] = 0; + // find and remember initial dependencies + unordered_set dependentStmts; + for (const auto& pair : dependencies) { + SgStatement* op = pair.first; + const auto& deps = pair.second; + degree[op] = deps.size(); + inDegree[op] = deps.size(); + if (!deps.empty()) + dependentStmts.insert(op); + for (auto dep : deps) + graph[dep].push_back(op); + } + for (SgStatement* op : allStmts) + if (!degree.count(op)) + degree[op] = 0; + // build queues + using PQ = priority_queue, ReadyOpCompare>; + PQ readyDependent; + queue readyIndependent; + size_t arrivalCounter = 0; + for (auto op : allStmts) { + if (inDegree[op] == 0) { + if (dependentStmts.count(op)) { + readyDependent.emplace(op, degree[op], arrivalCounter++); + } else { + readyIndependent.push(op); } } - components.push_back(component); } - return components; -} - -vector SortComponent( - const set& component, - const map>& outEdges, - const map>& inEdges) -{ - map inDegree; - for (auto v: component) { - inDegree[v] = inEdges.at(v).size(); - } - queue q; - for (auto v : component) { - if (inDegree[v] == 0) q.push(v); - } - vector result; - while (!q.empty()) { - auto curr = q.front(); - q.pop(); - result.push_back(curr); - for (SgStatement* neighbour: outEdges.at(curr)) { - if (component.count(neighbour)) { - inDegree[neighbour]--; - if (inDegree[neighbour] == 0) { - q.push(neighbour); + // main sort algorythm + vector executionOrder; + while (!readyDependent.empty() || !readyIndependent.empty()) { + SgStatement* current = nullptr; + if (!readyDependent.empty()) { + current = readyDependent.top().stmt; + readyDependent.pop(); + } else { + current = readyIndependent.front(); + readyIndependent.pop(); + } + executionOrder.push_back(current); + for (SgStatement* neighbor : graph[current]) { + inDegree[neighbor]--; + if (inDegree[neighbor] == 0) { + if (dependentStmts.count(neighbor)) { + readyDependent.emplace(neighbor, degree[neighbor], arrivalCounter++); + } else { + readyIndependent.push(neighbor); } } } } - return result; + return executionOrder; } -vector SortNoInterleaving(const map>& dependencies) -{ - set allNodes; - map> outEdges, inEdges; - GenNodesOfGraph(dependencies, allNodes, outEdges, inEdges); - auto components = FindLinksInGraph(allNodes, outEdges, inEdges); - vector totalOrder; - for (auto& comp : components) { - auto part = SortComponent(comp, outEdges, inEdges); - totalOrder.insert(totalOrder.end(), part.begin(), part.end()); - } - return totalOrder; -} + void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) { std::cout << "SWAP_OPERATORS Pass" << std::endl; // to remove countOfTransform += 1; // to remove - const int funcNum = file->numberOfFunctions(); + const int funcNum = file -> numberOfFunctions(); for (int i = 0; i < funcNum; ++i) { - SgStatement *st = file->functions(i); + SgStatement *st = file -> functions(i); vector blocks = findFuncBlocksByFuncStatement(st, FullIR); map> loopsMapping = findAndAnalyzeLoops(st, blocks); for (pair> loopForAnalyze: loopsMapping) @@ -272,25 +270,22 @@ void runSwapOperators(SgFile *file, std::map> dependencyGraph = AnalyzeLoopAndFindDeps(loopForAnalyze.first, loopForAnalyze.second, FullIR); // TODO: Write a function that will go through the operators and update all dependencies so that there are no mix-ups and splits inside the semantic blocks (for if, do and may be some other cases) buildAdditionalDeps(loopForAnalyze.first, dependencyGraph); - cout << "\n\n"; + cout << endl; int firstLine = loopForAnalyze.first -> lineNumber(); int lastLine = loopForAnalyze.first -> lastNodeOfStmt() -> lineNumber(); - // for (auto v: dependencyGraph) { - // cout << "OPERATOR: " << v.first -> lineNumber() << "\nDEPENDS ON:" << endl; + cout << "LOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES" << endl; + // for (auto &v: dependencyGraph) { + // cout << "OPERATOR: " << v.first -> lineNumber() << " " << v.first -> variant() << "\nDEPENDS ON:" << endl; // if (v.second.size() != 0) - // for (auto vv: v.second) { - // if (vv -> lineNumber() > firstLine) - // cout << vv -> lineNumber() << " "; - // } + // for (auto vv: v.second) + // cout << vv -> lineNumber() << " "; // cout << endl; // } - if (dependencyGraph.size() != 0) { - vector new_order = SortNoInterleaving(dependencyGraph); - cout << "\n\nLOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES\n" << endl; - for (auto v: new_order) - if (v -> lineNumber() > firstLine) - cout << v -> lineNumber() << endl; - } + vector new_order = scheduleOperations(dependencyGraph); + cout << "RESULT ORDER:" << endl; + for (auto v: new_order) + if (v -> lineNumber() > firstLine) + cout << v -> lineNumber() << endl; } } From 029da32719001f7c3a7cb5a8217eb95298c3a8d1 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 27 May 2025 15:55:02 +0300 Subject: [PATCH 10/20] swap operators in AST --- src/SwapOperators/swapOperators.cpp | 120 +++++++++++++++++++++------- 1 file changed, 90 insertions(+), 30 deletions(-) diff --git a/src/SwapOperators/swapOperators.cpp b/src/SwapOperators/swapOperators.cpp index bfe33a2..4985c43 100644 --- a/src/SwapOperators/swapOperators.cpp +++ b/src/SwapOperators/swapOperators.cpp @@ -43,7 +43,7 @@ vector findFuncBlocksByFuncStatement(SgStatement *st, map result; Statement* forSt = (Statement*)st; - for (auto& func : FullIR) + for (auto& func: FullIR) { if (func.first -> funcPointer -> getCurrProcessFile() == forSt -> getCurrProcessFile() && func.first -> funcPointer -> lineNumber() == forSt -> lineNumber()) @@ -86,20 +86,25 @@ map> findAndAnalyzeLoops(SgStatement *st map> AnalyzeLoopAndFindDeps(SgForStmt* forStatement, vector loopBlocks, map>& FullIR) { map> result; - for (SAPFOR::BasicBlock* bb: loopBlocks) { + for (SAPFOR::BasicBlock* bb: loopBlocks) + { map> blockReachingDefinitions = bb -> getRD_In(); vector instructions = bb -> getInstructions(); - for (SAPFOR::IR_Block* irBlock: instructions) { + for (SAPFOR::IR_Block* irBlock: instructions) + { // TODO: Think about what to do with function calls and array references. Because there are also dependencies there that are not reflected in RD, but they must be taken into account SAPFOR::Instruction* instr = irBlock -> getInstruction(); result[instr -> getOperator()]; // take Argument 1 and it's RD and push operators to final set - if (instr -> getArg1() != NULL) { + if (instr -> getArg1() != NULL) + { SAPFOR::Argument* arg = instr -> getArg1(); set prevInstructionsNumbers = blockReachingDefinitions[arg]; - for (int i: prevInstructionsNumbers) { + for (int i: prevInstructionsNumbers) + { SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; - if (foundInstruction != NULL) { + if (foundInstruction != NULL) + { SgStatement* prevOp = foundInstruction -> getOperator(); if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber() && prevOp -> lineNumber() > forStatement -> lineNumber()) @@ -108,12 +113,15 @@ map> AnalyzeLoopAndFindDeps(SgForStmt* forStatem } } // take Argument 2 (if exists) and it's RD and push operators to final set - if (instr -> getArg2() != NULL) { + if (instr -> getArg2() != NULL) + { SAPFOR::Argument* arg = instr -> getArg2(); set prevInstructionsNumbers = blockReachingDefinitions[arg]; - for (int i: prevInstructionsNumbers) { + for (int i: prevInstructionsNumbers) + { SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; - if (foundInstruction != NULL) { + if (foundInstruction != NULL) + { SgStatement* prevOp = foundInstruction -> getOperator(); if (prevOp != forStatement && instr -> getOperator() != forStatement&& instr -> getOperator() -> lineNumber() > prevOp -> lineNumber() && prevOp -> lineNumber() > forStatement -> lineNumber()) @@ -139,26 +147,36 @@ void buildAdditionalDeps(SgForStmt* forStatement, map variant() == LOGIF_NODE) { + if (st -> variant() == LOGIF_NODE) + { logIfOp = st; } - if (importantDepsTags.find(st -> variant()) != importantDepsTags.end()) { + if (importantDepsTags.find(st -> variant()) != importantDepsTags.end()) + { importantDeps.push_back(st); } - if (importantUpdDepsTags.find(st -> variant()) != importantUpdDepsTags.end()) { + if (importantUpdDepsTags.find(st -> variant()) != importantUpdDepsTags.end()) + { importantDeps.pop_back(); importantDeps.push_back(st); } - if (importantEndTags.find(st -> variant()) != importantEndTags.end()) { + if (importantEndTags.find(st -> variant()) != importantEndTags.end()) + { if(importantDeps.size() != 0) + { importantDeps.pop_back(); + } } st = st -> lexNext(); } @@ -180,15 +198,17 @@ struct ReadyOpCompare { } }; -vector scheduleOperations( - const map>& dependencies -) { +vector scheduleOperations(const map>& dependencies) +{ // get all statements unordered_set allStmtsSet; - for (const auto& pair : dependencies) { + for (const auto& pair : dependencies) + { allStmtsSet.insert(pair.first); for (SgStatement* dep : pair.second) + { allStmtsSet.insert(dep); + } } vector allStmts(allStmtsSet.begin(), allStmtsSet.end()); // count deps and build reversed graph @@ -199,7 +219,8 @@ vector scheduleOperations( inDegree[op] = 0; // find and remember initial dependencies unordered_set dependentStmts; - for (const auto& pair : dependencies) { + for (const auto& pair : dependencies) + { SgStatement* op = pair.first; const auto& deps = pair.second; degree[op] = deps.size(); @@ -210,40 +231,57 @@ vector scheduleOperations( graph[dep].push_back(op); } for (SgStatement* op : allStmts) + { if (!degree.count(op)) + { degree[op] = 0; + } + } // build queues using PQ = priority_queue, ReadyOpCompare>; PQ readyDependent; queue readyIndependent; size_t arrivalCounter = 0; - for (auto op : allStmts) { - if (inDegree[op] == 0) { - if (dependentStmts.count(op)) { + for (auto op : allStmts) + { + if (inDegree[op] == 0) + { + if (dependentStmts.count(op)) + { readyDependent.emplace(op, degree[op], arrivalCounter++); - } else { + } + else + { readyIndependent.push(op); } } } // main sort algorythm vector executionOrder; - while (!readyDependent.empty() || !readyIndependent.empty()) { + while (!readyDependent.empty() || !readyIndependent.empty()) + { SgStatement* current = nullptr; - if (!readyDependent.empty()) { + if (!readyDependent.empty()) + { current = readyDependent.top().stmt; readyDependent.pop(); - } else { + } + else + { current = readyIndependent.front(); readyIndependent.pop(); } executionOrder.push_back(current); - for (SgStatement* neighbor : graph[current]) { + for (SgStatement* neighbor : graph[current]) + { inDegree[neighbor]--; if (inDegree[neighbor] == 0) { - if (dependentStmts.count(neighbor)) { + if (dependentStmts.count(neighbor)) + { readyDependent.emplace(neighbor, degree[neighbor], arrivalCounter++); - } else { + } + else + { readyIndependent.push(neighbor); } } @@ -252,6 +290,21 @@ vector scheduleOperations( return executionOrder; } +void buildNewAST(SgStatement* loop, vector& newBody) +{ + SgStatement* endDo = loop->lastNodeOfStmt(); + SgStatement* st = loop; + int lineNum = loop -> lineNumber() + 1; + for (int i = 0; i < newBody.size(); i++) + { + st -> setLexNext(*newBody[i]); + st = st -> lexNext(); + st -> setlineNumber(lineNum); + lineNum++; + } + st -> setLexNext(*endDo); +} + void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) @@ -286,6 +339,13 @@ void runSwapOperators(SgFile *file, std::map lineNumber() > firstLine) cout << v -> lineNumber() << endl; + buildNewAST(loopForAnalyze.first, new_order); + st = loopForAnalyze.first -> lexNext(); + while (st != loopForAnalyze.first -> lastNodeOfStmt()) + { + cout << st -> lineNumber() << " " << st -> sunparse() << endl; + st = st -> lexNext(); + } } } From d09e92a947839d3394ea7506c2e575b5bc26145c Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 2 Jun 2025 08:54:45 +0300 Subject: [PATCH 11/20] moved to transformations --- CMakeLists.txt | 12 ++++++------ src/Sapfor.cpp | 8 +++----- .../SwapOperators/swap_operators.cpp} | 16 ++++++++-------- .../SwapOperators/swap_operators.h} | 4 ++-- 4 files changed, 19 insertions(+), 21 deletions(-) rename src/{SwapOperators/swapOperators.cpp => Transformations/SwapOperators/swap_operators.cpp} (97%) rename src/{SwapOperators/swapOperators.h => Transformations/SwapOperators/swap_operators.h} (72%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d124f0..eb214e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,8 +208,8 @@ set(TR_INLINER src/Transformations/FunctionInlining/inliner.cpp src/Transformations/FunctionInlining/inliner.h) set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp src/Transformations/RenameSymbols/rename_symbols.h) -SET(SWAP_OPERATORS src/SwapOperators/swapOperators.cpp - src/SwapOperators/swapOperators.h) +SET(TR_SWAP_OPERATORS src/Transformations/SwapOperators/swap_operators.cpp + src/Transformations/SwapOperators/swap_operators.h) set(TRANSFORMS ${TR_DEAD_CODE} @@ -232,7 +232,8 @@ set(TRANSFORMS ${TR_REPLACE_ARRAYS_IN_IO} ${TR_EXPR_TRANSFORM} ${TR_INLINER} - ${TR_RENAME_SYMBOLS}) + ${TR_RENAME_SYMBOLS} + ${TR_SWAP_OPERATORS}) set(CFG src/CFGraph/IR.cpp src/CFGraph/IR.h @@ -440,8 +441,7 @@ set(SOURCE_EXE ${ZLIB} ${GR_LAYOUT} ${PR_PARAM} - ${PROJ_MAN} - ${SWAP_OPERATORS}) + ${PROJ_MAN}) add_executable(Sapfor_F ${SOURCE_EXE}) source_group (CFGraph FILES ${CFG}) @@ -467,6 +467,7 @@ source_group (Transformations\\GlobalVariables FILES ${TR_GV}) source_group (Transformations\\ConvertToC FILES ${TR_CONV}) source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE}) source_group (Transformations\\ReplaceArraysInIO FILES ${TR_REPLACE_ARRAYS_IN_IO}) +source_group (Transformations\\SwapOperators FILES ${TR_SWAP_OPERATORS}) source_group (CreateIntervals FILES ${CREATE_INTER_T}) @@ -486,7 +487,6 @@ source_group (Utils FILES ${UTILS}) source_group (VerificationCode FILES ${VERIF}) source_group (ProjectParameters FILES ${PR_PARAM}) source_group (ProjectManipulation FILES ${PROJ_MAN}) -source_group (SwapOperators FILES ${SWAP_OPERATORS}) source_group (VisualizerCalls FILES ${VS_CALLS}) source_group (VisualizerCalls\\GraphLayout FILES ${GR_LAYOUT}) diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index eb280d5..257d38d 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -90,7 +90,7 @@ #include "Transformations/DeadCodeRemoving/dead_code.h" #include "Transformations/RenameSymbols/rename_symbols.h" #include "Transformations/FunctionInlining/inliner.h" -#include "SwapOperators/swapOperators.h" +#include "Transformations/SwapOperators/swap_operators.h" #include "ProjectParameters/projectParameters.h" @@ -942,10 +942,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne internalExit = err; } } - else if (curr_regime == SWAP_OPERATORS) - { - runSwapOperators(file, loopGraph, fullIR, countOfTransform); - } + else if (curr_regime == SWAP_OPERATORS) + runSwapOperators(file, loopGraph, fullIR, countOfTransform); else if (curr_regime == PRIVATE_REMOVING_ANALYSIS) { auto itFound = loopGraph.find(file->filename()); diff --git a/src/SwapOperators/swapOperators.cpp b/src/Transformations/SwapOperators/swap_operators.cpp similarity index 97% rename from src/SwapOperators/swapOperators.cpp rename to src/Transformations/SwapOperators/swap_operators.cpp index 4985c43..162624f 100644 --- a/src/SwapOperators/swapOperators.cpp +++ b/src/Transformations/SwapOperators/swap_operators.cpp @@ -4,14 +4,14 @@ #include #include -#include "../Utils/errors.h" -#include "../Utils/SgUtils.h" -#include "../GraphCall/graph_calls.h" -#include "../GraphCall/graph_calls_func.h" -#include "../CFGraph/CFGraph.h" -#include "../CFGraph/IR.h" -#include "../GraphLoop/graph_loops.h" -#include "swapOperators.h" +#include "../../Utils/errors.h" +#include "../../Utils/SgUtils.h" +#include "../../GraphCall/graph_calls.h" +#include "../../GraphCall/graph_calls_func.h" +#include "../../CFGraph/CFGraph.h" +#include "../../CFGraph/IR.h" +#include "../../GraphLoop/graph_loops.h" +#include "swap_operators.h" using namespace std; diff --git a/src/SwapOperators/swapOperators.h b/src/Transformations/SwapOperators/swap_operators.h similarity index 72% rename from src/SwapOperators/swapOperators.h rename to src/Transformations/SwapOperators/swap_operators.h index b66152f..a23add9 100644 --- a/src/SwapOperators/swapOperators.h +++ b/src/Transformations/SwapOperators/swap_operators.h @@ -1,6 +1,6 @@ #pragma once -#include "../GraphLoop/graph_loops.h" -#include "../CFGraph/CFGraph.h" +#include "../../GraphLoop/graph_loops.h" +#include "../../CFGraph/CFGraph.h" void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform); From f527deb02c6267bed12685c26c657d189136c9fe Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Wed, 8 Oct 2025 23:14:19 +0300 Subject: [PATCH 12/20] attempt to build new ast --- .../SwapOperators/swap_operators.cpp | 95 ++++++++++++++++--- 1 file changed, 82 insertions(+), 13 deletions(-) diff --git a/src/Transformations/SwapOperators/swap_operators.cpp b/src/Transformations/SwapOperators/swap_operators.cpp index 162624f..b5cba8c 100644 --- a/src/Transformations/SwapOperators/swap_operators.cpp +++ b/src/Transformations/SwapOperators/swap_operators.cpp @@ -290,22 +290,88 @@ vector scheduleOperations(const map& newBody) +static bool buildNewAST(SgStatement* loop, vector& newBody) { - SgStatement* endDo = loop->lastNodeOfStmt(); - SgStatement* st = loop; - int lineNum = loop -> lineNumber() + 1; - for (int i = 0; i < newBody.size(); i++) - { - st -> setLexNext(*newBody[i]); - st = st -> lexNext(); - st -> setlineNumber(lineNum); - lineNum++; + if (!loop) {return false;} + if (newBody.empty()) {return true;} + if (loop->variant() != FOR_NODE) {return false;} + + SgStatement* loopStart = loop->lexNext(); + SgStatement* loopEnd = loop->lastNodeOfStmt(); + if (!loopStart || !loopEnd) {return false;} + + for (SgStatement* stmt : newBody) { + if (stmt && stmt != loop && stmt != loopEnd) { + SgStatement* current = loopStart; + bool found = false; + while (current && current != loopEnd->lexNext()) { + if (current == stmt) { + found = true; + break; + } + current = current->lexNext(); + } + if (!found) {return false;} + } } - st -> setLexNext(*endDo); + + vector extractedStatements; + vector savedComments; + vector savedLineNumbers; + + for (SgStatement* stmt : newBody) { + if (stmt && stmt != loop && stmt != loopEnd) { + savedComments.push_back(stmt->comments() ? strdup(stmt->comments()) : nullptr); + savedLineNumbers.push_back(stmt->lineNumber()); + SgStatement* extracted = stmt->extractStmt(); + if (extracted) {extractedStatements.push_back(extracted);} + } + } + + SgStatement* currentPos = loop; + int lineCounter = loop->lineNumber() + 1; + + for (size_t i = 0; i < extractedStatements.size(); i++) { + SgStatement* stmt = extractedStatements[i]; + if (stmt) { + if (i < savedComments.size() && savedComments[i]) { + stmt->setComments(savedComments[i]); + } + stmt->setlineNumber(lineCounter++); + currentPos->insertStmtAfter(*stmt, *loop); + currentPos = stmt; + } + } + + for (char* comment : savedComments) { + if (comment) { + free(comment); + } + } + + if (currentPos && currentPos->lexNext() != loopEnd) { + currentPos->setLexNext(*loopEnd); + } + + return true; } - +static bool validateNewOrder(SgStatement* loop, const vector& newOrder) +{ + if (!loop || newOrder.empty()) { + return true; + } + unordered_set seen; + for (SgStatement* stmt : newOrder) { + if (stmt && stmt != loop && stmt != loop->lastNodeOfStmt()) { + if (seen.count(stmt)) { + return false; + } + seen.insert(stmt); + } + } + return true; +} void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) { @@ -339,7 +405,10 @@ void runSwapOperators(SgFile *file, std::map lineNumber() > firstLine) cout << v -> lineNumber() << endl; - buildNewAST(loopForAnalyze.first, new_order); + + if (validateNewOrder(loopForAnalyze.first, new_order)) { + buildNewAST(loopForAnalyze.first, new_order); + } st = loopForAnalyze.first -> lexNext(); while (st != loopForAnalyze.first -> lastNodeOfStmt()) { From 1c37336459d310fa003844a614bccfb58d911f45 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Thu, 23 Oct 2025 14:54:43 +0300 Subject: [PATCH 13/20] Make pass correct --- .../SwapOperators/swap_operators.cpp | 559 +++++++----------- 1 file changed, 218 insertions(+), 341 deletions(-) diff --git a/src/Transformations/SwapOperators/swap_operators.cpp b/src/Transformations/SwapOperators/swap_operators.cpp index b5cba8c..47565fa 100644 --- a/src/Transformations/SwapOperators/swap_operators.cpp +++ b/src/Transformations/SwapOperators/swap_operators.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "../../Utils/errors.h" #include "../../Utils/SgUtils.h" @@ -15,319 +16,206 @@ using namespace std; +string getNameByArg(SAPFOR::Argument* arg); +SgSymbol* getSybolByArg(SAPFOR::Argument* arg); -unordered_set loop_tags = {FOR_NODE/*, FORALL_NODE, WHILE_NODE, DO_WHILE_NODE*/}; -unordered_set importantDepsTags = {FOR_NODE, IF_NODE}; -unordered_set importantUpdDepsTags = {ELSEIF_NODE}; -unordered_set importantEndTags = {CONTROL_END}; - - -vector findInstructionsFromOperator(SgStatement* st, vector Blocks) -{ +static vector findInstructionsFromOperator(SgStatement* st, vector Blocks) { vector result; - string filename = st -> fileName(); - for (auto& block: Blocks) - { - vector instructionsInBlock = block -> getInstructions(); - for (auto& instruction: instructionsInBlock) - { - SgStatement* curOperator = instruction -> getInstruction() -> getOperator(); - if (curOperator -> lineNumber() == st -> lineNumber()) + string filename = st->fileName(); + + for (auto& block: Blocks) { + vector instructionsInBlock = block->getInstructions(); + for (auto& instruction: instructionsInBlock) { + SgStatement* curOperator = instruction->getInstruction()->getOperator(); + // Match by line number to find corresponding IR instruction + if (curOperator->lineNumber() == st->lineNumber()) { result.push_back(instruction); + } } } return result; } -vector findFuncBlocksByFuncStatement(SgStatement *st, map>& FullIR) -{ - vector result; - Statement* forSt = (Statement*)st; - for (auto& func: FullIR) - { - if (func.first -> funcPointer -> getCurrProcessFile() == forSt -> getCurrProcessFile() - && func.first -> funcPointer -> lineNumber() == forSt -> lineNumber()) - result = func.second; - } - return result; -} +unordered_set loop_tags = {FOR_NODE}; +unordered_set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE}; +unordered_set control_end_tags = {CONTROL_END}; -map> findAndAnalyzeLoops(SgStatement *st, vector blocks) -{ - map> result; - SgStatement *lastNode = st->lastNodeOfStmt(); - while (st && st != lastNode) - { - if (loop_tags.find(st -> variant()) != loop_tags.end()) - { - // part with find statements of loop - SgForStmt *forSt = (SgForStmt*)st; - SgStatement *loopBody = forSt -> body(); - SgStatement *lastLoopNode = st->lastNodeOfStmt(); - // part with find blocks and instructions of loops - unordered_set blocks_nums; - while (loopBody && loopBody != lastLoopNode) - { - SAPFOR::IR_Block* IR = findInstructionsFromOperator(loopBody, blocks).front(); - if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end()) - { - result[forSt].push_back(IR -> getBasicBlock()); - blocks_nums.insert(IR -> getBasicBlock() -> getNumber()); - } - loopBody = loopBody -> lexNext(); - } - std::sort(result[forSt].begin(), result[forSt].end()); - } - st = st -> lexNext(); - } - return result; -} - -map> AnalyzeLoopAndFindDeps(SgForStmt* forStatement, vector loopBlocks, map>& FullIR) -{ - map> result; - for (SAPFOR::BasicBlock* bb: loopBlocks) - { - map> blockReachingDefinitions = bb -> getRD_In(); - vector instructions = bb -> getInstructions(); - for (SAPFOR::IR_Block* irBlock: instructions) - { - // TODO: Think about what to do with function calls and array references. Because there are also dependencies there that are not reflected in RD, but they must be taken into account - SAPFOR::Instruction* instr = irBlock -> getInstruction(); - result[instr -> getOperator()]; - // take Argument 1 and it's RD and push operators to final set - if (instr -> getArg1() != NULL) - { - SAPFOR::Argument* arg = instr -> getArg1(); - set prevInstructionsNumbers = blockReachingDefinitions[arg]; - for (int i: prevInstructionsNumbers) - { - SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; - if (foundInstruction != NULL) - { - SgStatement* prevOp = foundInstruction -> getOperator(); - if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber() - && prevOp -> lineNumber() > forStatement -> lineNumber()) - result[instr -> getOperator()].insert(prevOp); - } - } - } - // take Argument 2 (if exists) and it's RD and push operators to final set - if (instr -> getArg2() != NULL) - { - SAPFOR::Argument* arg = instr -> getArg2(); - set prevInstructionsNumbers = blockReachingDefinitions[arg]; - for (int i: prevInstructionsNumbers) - { - SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; - if (foundInstruction != NULL) - { - SgStatement* prevOp = foundInstruction -> getOperator(); - if (prevOp != forStatement && instr -> getOperator() != forStatement&& instr -> getOperator() -> lineNumber() > prevOp -> lineNumber() - && prevOp -> lineNumber() > forStatement -> lineNumber()) - result[instr -> getOperator()].insert(prevOp); - } - } - } - // update RD - if (instr -> getResult() != NULL) - blockReachingDefinitions[instr -> getResult()] = {instr -> getNumber()}; - } - } - return result; -} - -void buildAdditionalDeps(SgForStmt* forStatement, map>& dependencies) -{ - SgStatement* lastNode = forStatement->lastNodeOfStmt(); - vector importantDeps; - SgStatement* st = (SgStatement*) forStatement; - st = st -> lexNext(); - SgStatement* logIfOp = NULL; - while (st && st != lastNode) - { - if(importantDeps.size() != 0) - { - if (st != importantDeps.back()) - { - dependencies[st].insert(importantDeps.back()); - } - } - if (logIfOp != NULL) - { - dependencies[st].insert(logIfOp); - logIfOp = NULL; - } - if (st -> variant() == LOGIF_NODE) - { - logIfOp = st; - } - if (importantDepsTags.find(st -> variant()) != importantDepsTags.end()) - { - importantDeps.push_back(st); - } - if (importantUpdDepsTags.find(st -> variant()) != importantUpdDepsTags.end()) - { - importantDeps.pop_back(); - importantDeps.push_back(st); - } - if (importantEndTags.find(st -> variant()) != importantEndTags.end()) - { - if(importantDeps.size() != 0) - { - importantDeps.pop_back(); - } - } - st = st -> lexNext(); - } -} - -struct ReadyOp { +struct OperatorInfo { SgStatement* stmt; - int degree; - size_t arrival; - ReadyOp(SgStatement* s, int d, size_t a): stmt(s), degree(d), arrival(a) {} + set usedVars; + set definedVars; + int lineNumber; + bool isMovable; + OperatorInfo(SgStatement* s) : stmt(s), lineNumber(s->lineNumber()), isMovable(true) {} }; -struct ReadyOpCompare { - bool operator()(const ReadyOp& a, const ReadyOp& b) const { - if (a.degree != b.degree) - return a.degree > b.degree; - else - return a.arrival > b.arrival; - } -}; - -vector scheduleOperations(const map>& dependencies) -{ - // get all statements - unordered_set allStmtsSet; - for (const auto& pair : dependencies) - { - allStmtsSet.insert(pair.first); - for (SgStatement* dep : pair.second) - { - allStmtsSet.insert(dep); - } - } - vector allStmts(allStmtsSet.begin(), allStmtsSet.end()); - // count deps and build reversed graph - unordered_map> graph; - unordered_map inDegree; - unordered_map degree; - for (auto op : allStmts) - inDegree[op] = 0; - // find and remember initial dependencies - unordered_set dependentStmts; - for (const auto& pair : dependencies) - { - SgStatement* op = pair.first; - const auto& deps = pair.second; - degree[op] = deps.size(); - inDegree[op] = deps.size(); - if (!deps.empty()) - dependentStmts.insert(op); - for (auto dep : deps) - graph[dep].push_back(op); - } - for (SgStatement* op : allStmts) - { - if (!degree.count(op)) - { - degree[op] = 0; - } - } - // build queues - using PQ = priority_queue, ReadyOpCompare>; - PQ readyDependent; - queue readyIndependent; - size_t arrivalCounter = 0; - for (auto op : allStmts) - { - if (inDegree[op] == 0) - { - if (dependentStmts.count(op)) - { - readyDependent.emplace(op, degree[op], arrivalCounter++); - } - else - { - readyIndependent.push(op); - } - } - } - // main sort algorythm - vector executionOrder; - while (!readyDependent.empty() || !readyIndependent.empty()) - { - SgStatement* current = nullptr; - if (!readyDependent.empty()) - { - current = readyDependent.top().stmt; - readyDependent.pop(); - } - else - { - current = readyIndependent.front(); - readyIndependent.pop(); - } - executionOrder.push_back(current); - for (SgStatement* neighbor : graph[current]) - { - inDegree[neighbor]--; - if (inDegree[neighbor] == 0) { - if (dependentStmts.count(neighbor)) - { - readyDependent.emplace(neighbor, degree[neighbor], arrivalCounter++); - } - else - { - readyIndependent.push(neighbor); - } - } - } - } - return executionOrder; -} - -static bool buildNewAST(SgStatement* loop, vector& newBody) -{ - if (!loop) {return false;} - if (newBody.empty()) {return true;} - if (loop->variant() != FOR_NODE) {return false;} - +static vector analyzeOperatorsInLoop(SgForStmt* loop, vector blocks, map>& FullIR) { + vector operators; SgStatement* loopStart = loop->lexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); - if (!loopStart || !loopEnd) {return false;} + + SgStatement* current = loopStart; + while (current && current != loopEnd) { + if (isSgExecutableStatement(current)) { + OperatorInfo opInfo(current); + + vector irBlocks = findInstructionsFromOperator(current, blocks); + for (auto irBlock : irBlocks) { + SAPFOR::Instruction* instr = irBlock->getInstruction(); + + if (instr->getArg1()) { + string varName = getNameByArg(instr->getArg1()); + if (!varName.empty()) { + opInfo.usedVars.insert(varName); + } + } + if (instr->getArg2()) { + string varName = getNameByArg(instr->getArg2()); + if (!varName.empty()) { + opInfo.usedVars.insert(varName); + } + } + if (instr->getResult()) { + string varName = getNameByArg(instr->getResult()); + if (!varName.empty()) { + opInfo.definedVars.insert(varName); + } + } + } + + if (control_tags.find(current->variant()) != control_tags.end()) { + opInfo.isMovable = false; + } + + operators.push_back(opInfo); + } + current = current->lexNext(); + } + + return operators; +} - for (SgStatement* stmt : newBody) { - if (stmt && stmt != loop && stmt != loopEnd) { - SgStatement* current = loopStart; - bool found = false; - while (current && current != loopEnd->lexNext()) { - if (current == stmt) { - found = true; +static map> findVariableDefinitions(SgForStmt* loop, vector& operators) { + map> varDefinitions; + + for (auto& op : operators) { + for (const string& var : op.definedVars) { + varDefinitions[var].push_back(op.stmt); + } + } + + return varDefinitions; +} + +static int calculateDistance(SgStatement* from, SgStatement* to) { + if (!from || !to) return INT_MAX; + return abs(to->lineNumber() - from->lineNumber()); +} + +static SgStatement* findBestPosition(SgStatement* operatorStmt, vector& operators, map>& varDefinitions) { + OperatorInfo* opInfo = nullptr; + for (auto& op : operators) { + if (op.stmt == operatorStmt) { + opInfo = &op; + break; + } + } + + if (!opInfo || !opInfo->isMovable) return nullptr; + + SgStatement* bestPos = nullptr; + int minDistance = INT_MAX; + + for (const string& usedVar : opInfo->usedVars) { + if (varDefinitions.find(usedVar) != varDefinitions.end()) { + for (SgStatement* defStmt : varDefinitions[usedVar]) { + int distance = calculateDistance(operatorStmt, defStmt); + if (distance < minDistance) { + minDistance = distance; + bestPos = defStmt; + } + } + } + } + + return bestPos; +} + +static bool canMoveTo(SgStatement* from, SgStatement* to, SgForStmt* loop) { + if (!from || !to || from == to) return false; + + SgStatement* loopStart = loop->lexNext(); + SgStatement* loopEnd = loop->lastNodeOfStmt(); + + if (to->lineNumber() < loopStart->lineNumber() || to->lineNumber() > loopEnd->lineNumber()) { + return false; + } + + SgStatement* current = from; + while (current && current != loopEnd) { + if (control_tags.find(current->variant()) != control_tags.end()) { + return false; + } + if (current == to) break; + current = current->lexNext(); + } + + return true; +} + +static vector optimizeOperatorOrder(SgForStmt* loop, vector& operators, map>& varDefinitions) { + vector newOrder; + vector moved(operators.size(), false); + + for (size_t i = 0; i < operators.size(); i++) { + if (moved[i] || !operators[i].isMovable) { + newOrder.push_back(operators[i].stmt); + moved[i] = true; + continue; + } + + SgStatement* bestPos = findBestPosition(operators[i].stmt, operators, varDefinitions); + + if (bestPos && canMoveTo(operators[i].stmt, bestPos, loop)) { + bool inserted = false; + for (size_t j = 0; j < newOrder.size(); j++) { + if (newOrder[j] == bestPos) { + newOrder.insert(newOrder.begin() + j + 1, operators[i].stmt); + inserted = true; break; } - current = current->lexNext(); } - if (!found) {return false;} + if (!inserted) { + newOrder.push_back(operators[i].stmt); + } + } else { + newOrder.push_back(operators[i].stmt); } + moved[i] = true; } + + return newOrder; +} +static bool applyOperatorReordering(SgForStmt* loop, vector& newOrder) { + if (!loop || newOrder.empty()) return false; + + SgStatement* loopStart = loop->lexNext(); + SgStatement* loopEnd = loop->lastNodeOfStmt(); + vector extractedStatements; vector savedComments; - vector savedLineNumbers; - - for (SgStatement* stmt : newBody) { + + for (SgStatement* stmt : newOrder) { if (stmt && stmt != loop && stmt != loopEnd) { savedComments.push_back(stmt->comments() ? strdup(stmt->comments()) : nullptr); - savedLineNumbers.push_back(stmt->lineNumber()); SgStatement* extracted = stmt->extractStmt(); - if (extracted) {extractedStatements.push_back(extracted);} + if (extracted) { + extractedStatements.push_back(extracted); + } } } - + SgStatement* currentPos = loop; int lineCounter = loop->lineNumber() + 1; @@ -342,13 +230,13 @@ static bool buildNewAST(SgStatement* loop, vector& newBody) currentPos = stmt; } } - + for (char* comment : savedComments) { if (comment) { free(comment); } } - + if (currentPos && currentPos->lexNext() != loopEnd) { currentPos->setLexNext(*loopEnd); } @@ -356,67 +244,56 @@ static bool buildNewAST(SgStatement* loop, vector& newBody) return true; } -static bool validateNewOrder(SgStatement* loop, const vector& newOrder) -{ - if (!loop || newOrder.empty()) { - return true; +vector findFuncBlocksByFuncStatement(SgStatement *st, map>& FullIR) { + vector result; + Statement* forSt = (Statement*)st; + for (auto& func: FullIR) { + if (func.first -> funcPointer -> getCurrProcessFile() == forSt -> getCurrProcessFile() + && func.first -> funcPointer -> lineNumber() == forSt -> lineNumber()) + result = func.second; } - unordered_set seen; - for (SgStatement* stmt : newOrder) { - if (stmt && stmt != loop && stmt != loop->lastNodeOfStmt()) { - if (seen.count(stmt)) { - return false; - } - seen.insert(stmt); - } - } - return true; + return result; } -void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) -{ - std::cout << "SWAP_OPERATORS Pass" << std::endl; // to remove - countOfTransform += 1; // to remove +map> findAndAnalyzeLoops(SgStatement *st, vector blocks) { + map> result; + SgStatement *lastNode = st->lastNodeOfStmt(); + while (st && st != lastNode) { + if (loop_tags.find(st -> variant()) != loop_tags.end()) { + SgForStmt *forSt = (SgForStmt*)st; + SgStatement *loopBody = forSt -> body(); + SgStatement *lastLoopNode = st->lastNodeOfStmt(); + unordered_set blocks_nums; + while (loopBody && loopBody != lastLoopNode) { + SAPFOR::IR_Block* IR = findInstructionsFromOperator(loopBody, blocks).front(); + if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end()) { + result[forSt].push_back(IR -> getBasicBlock()); + blocks_nums.insert(IR -> getBasicBlock() -> getNumber()); + } + loopBody = loopBody -> lexNext(); + } + std::sort(result[forSt].begin(), result[forSt].end()); + } + st = st -> lexNext(); + } + return result; +} + +void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) { + countOfTransform += 1; const int funcNum = file -> numberOfFunctions(); - for (int i = 0; i < funcNum; ++i) - { + for (int i = 0; i < funcNum; ++i) { SgStatement *st = file -> functions(i); vector blocks = findFuncBlocksByFuncStatement(st, FullIR); map> loopsMapping = findAndAnalyzeLoops(st, blocks); - for (pair> loopForAnalyze: loopsMapping) - { - map> dependencyGraph = AnalyzeLoopAndFindDeps(loopForAnalyze.first, loopForAnalyze.second, FullIR); - // TODO: Write a function that will go through the operators and update all dependencies so that there are no mix-ups and splits inside the semantic blocks (for if, do and may be some other cases) - buildAdditionalDeps(loopForAnalyze.first, dependencyGraph); - cout << endl; - int firstLine = loopForAnalyze.first -> lineNumber(); - int lastLine = loopForAnalyze.first -> lastNodeOfStmt() -> lineNumber(); - cout << "LOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES" << endl; - // for (auto &v: dependencyGraph) { - // cout << "OPERATOR: " << v.first -> lineNumber() << " " << v.first -> variant() << "\nDEPENDS ON:" << endl; - // if (v.second.size() != 0) - // for (auto vv: v.second) - // cout << vv -> lineNumber() << " "; - // cout << endl; - // } - vector new_order = scheduleOperations(dependencyGraph); - cout << "RESULT ORDER:" << endl; - for (auto v: new_order) - if (v -> lineNumber() > firstLine) - cout << v -> lineNumber() << endl; - - if (validateNewOrder(loopForAnalyze.first, new_order)) { - buildNewAST(loopForAnalyze.first, new_order); - } - st = loopForAnalyze.first -> lexNext(); - while (st != loopForAnalyze.first -> lastNodeOfStmt()) - { - cout << st -> lineNumber() << " " << st -> sunparse() << endl; - st = st -> lexNext(); - } + + for (pair> loopForAnalyze: loopsMapping) { + vector operators = analyzeOperatorsInLoop(loopForAnalyze.first, loopForAnalyze.second, FullIR); + map> varDefinitions = findVariableDefinitions(loopForAnalyze.first, operators); + + vector newOrder = optimizeOperatorOrder(loopForAnalyze.first, operators, varDefinitions); + applyOperatorReordering(loopForAnalyze.first, newOrder); } } - - return; -}; +} \ No newline at end of file From 582d2d5e70a285389bdbe7ddd8bd1ec1d1447cbb Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Thu, 11 Dec 2025 01:41:58 +0300 Subject: [PATCH 14/20] Adding handing of nested loops and conditional statements --- .../SwapOperators/swap_operators.cpp | 274 ++++++++++++++++-- 1 file changed, 255 insertions(+), 19 deletions(-) diff --git a/src/Transformations/SwapOperators/swap_operators.cpp b/src/Transformations/SwapOperators/swap_operators.cpp index 47565fa..3f5d28a 100644 --- a/src/Transformations/SwapOperators/swap_operators.cpp +++ b/src/Transformations/SwapOperators/swap_operators.cpp @@ -17,7 +17,6 @@ using namespace std; string getNameByArg(SAPFOR::Argument* arg); -SgSymbol* getSybolByArg(SAPFOR::Argument* arg); static vector findInstructionsFromOperator(SgStatement* st, vector Blocks) { vector result; @@ -36,9 +35,9 @@ static vector findInstructionsFromOperator(SgStatement* st, v return result; } -unordered_set loop_tags = {FOR_NODE}; -unordered_set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE}; -unordered_set control_end_tags = {CONTROL_END}; +unordered_set loop_tags = {FOR_NODE}; // Loop statements +unordered_set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; // Control structures that cannot be moved +unordered_set control_end_tags = {CONTROL_END}; // End marker struct OperatorInfo { SgStatement* stmt; @@ -46,21 +45,170 @@ struct OperatorInfo { set definedVars; int lineNumber; bool isMovable; + OperatorInfo(SgStatement* s) : stmt(s), lineNumber(s->lineNumber()), isMovable(true) {} }; +static bool isStatementEmbedded(SgStatement* stmt, SgStatement* parent) { + if (!stmt || !parent || stmt == parent) return false; + + if (parent->variant() == LOGIF_NODE) { + if (stmt->lineNumber() == parent->lineNumber()) { + return true; + } + + SgStatement* current = parent; + SgStatement* lastNode = parent->lastNodeOfStmt(); + + while (current && current != lastNode) { + if (current == stmt) { + return true; + } + if (current->isIncludedInStmt(*stmt)) { + return true; + } + current = current->lexNext(); + } + } + + if (parent->isIncludedInStmt(*stmt)) { + return true; + } + + return false; +} + +static bool isLoopBoundary(SgStatement* stmt) { + if (!stmt) return false; + + if (stmt->variant() == FOR_NODE || stmt->variant() == CONTROL_END) { + return true; + } + + return false; +} + +static bool isPartOfNestedLoop(SgStatement* stmt, SgForStmt* loop) { + if (!stmt || !loop) return false; + + SgStatement* loopStart = loop->lexNext(); + SgStatement* loopEnd = loop->lastNodeOfStmt(); + if (!loopStart || !loopEnd) return false; + + if (stmt->lineNumber() < loopStart->lineNumber() || stmt->lineNumber() > loopEnd->lineNumber()) { + return false; + } + + SgStatement* current = loopStart; + + while (current && current != loopEnd) { + + if (current->variant() == FOR_NODE && current != loop) { + SgForStmt* nestedLoop = (SgForStmt*)current; + SgStatement* nestedStart = nestedLoop->lexNext(); + SgStatement* nestedEnd = nestedLoop->lastNodeOfStmt(); + + if (nestedStart && nestedEnd && + stmt->lineNumber() >= nestedStart->lineNumber() && + stmt->lineNumber() <= nestedEnd->lineNumber()) { + return true; + } + } + + current = current->lexNext(); + } + + return false; +} + +static bool canSafelyExtract(SgStatement* stmt, SgForStmt* loop) { + if (!stmt || !loop) return false; + + if (isLoopBoundary(stmt)) { + return false; + } + + if (control_tags.find(stmt->variant()) != control_tags.end()) { + return false; + } + + if (isPartOfNestedLoop(stmt, loop)) { + return false; + } + + SgStatement* loopStart = loop->lexNext(); + SgStatement* loopEnd = loop->lastNodeOfStmt(); + if (!loopStart || !loopEnd) return false; + + SgStatement* current = loopStart; + + while (current && current != loopEnd) { + if (current->variant() == LOGIF_NODE && current->lineNumber() == stmt->lineNumber()) { + return false; + } + + if (control_tags.find(current->variant()) != control_tags.end()) { + if (isStatementEmbedded(stmt, current)) { + return false; + } + } + if (current == stmt) break; + current = current->lexNext(); + } + + return true; +} + static vector analyzeOperatorsInLoop(SgForStmt* loop, vector blocks, map>& FullIR) { vector operators; SgStatement* loopStart = loop->lexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); + if (!loopStart || !loopEnd) { + return operators; + } + SgStatement* current = loopStart; + unordered_set visited; + while (current && current != loopEnd) { + + if (visited.find(current) != visited.end()) { + break; + } + visited.insert(current); + + if (isLoopBoundary(current)) { + current = current->lexNext(); + continue; + } + + if (current->variant() == FOR_NODE && current != loop) { + SgStatement* nestedEnd = current->lastNodeOfStmt(); + if (nestedEnd) { + current = nestedEnd->lexNext(); + } else { + current = current->lexNext(); + } + continue; + } + if (isSgExecutableStatement(current)) { + if (control_tags.find(current->variant()) != control_tags.end()) { + current = current->lexNext(); + continue; + } + if (current->variant() != ASSIGN_STAT) { + current = current->lexNext(); + continue; + } + OperatorInfo opInfo(current); vector irBlocks = findInstructionsFromOperator(current, blocks); for (auto irBlock : irBlocks) { + if (!irBlock || !irBlock->getInstruction()) continue; + SAPFOR::Instruction* instr = irBlock->getInstruction(); if (instr->getArg1()) { @@ -83,10 +231,6 @@ static vector analyzeOperatorsInLoop(SgForStmt* loop, vectorvariant()) != control_tags.end()) { - opInfo.isMovable = false; - } - operators.push_back(opInfo); } current = current->lexNext(); @@ -97,13 +241,11 @@ static vector analyzeOperatorsInLoop(SgForStmt* loop, vector> findVariableDefinitions(SgForStmt* loop, vector& operators) { map> varDefinitions; - for (auto& op : operators) { for (const string& var : op.definedVars) { varDefinitions[var].push_back(op.stmt); } } - return varDefinitions; } @@ -121,7 +263,9 @@ static SgStatement* findBestPosition(SgStatement* operatorStmt, vectorisMovable) return nullptr; + if (!opInfo || !opInfo->isMovable) { + return nullptr; + } SgStatement* bestPos = nullptr; int minDistance = INT_MAX; @@ -147,12 +291,22 @@ static bool canMoveTo(SgStatement* from, SgStatement* to, SgForStmt* loop) { SgStatement* loopStart = loop->lexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); + if (!loopStart || !loopEnd) return false; + if (to->lineNumber() < loopStart->lineNumber() || to->lineNumber() > loopEnd->lineNumber()) { return false; } SgStatement* current = from; + unordered_set visited; + while (current && current != loopEnd) { + + if (visited.find(current) != visited.end()) { + return false; + } + visited.insert(current); + if (control_tags.find(current->variant()) != control_tags.end()) { return false; } @@ -203,29 +357,98 @@ static bool applyOperatorReordering(SgForStmt* loop, vector& newOr SgStatement* loopStart = loop->lexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); + if (!loopStart || !loopEnd) return false; + + vector originalOrder; + SgStatement* current = loopStart; + while (current && current != loopEnd) { + if (isSgExecutableStatement(current) && current->variant() == ASSIGN_STAT) { + originalOrder.push_back(current); + } + current = current->lexNext(); + } + + bool orderChanged = false; + if (originalOrder.size() == newOrder.size()) { + for (size_t i = 0; i < originalOrder.size(); i++) { + if (originalOrder[i] != newOrder[i]) { + orderChanged = true; + break; + } + } + } else { + orderChanged = true; + } + + if (!orderChanged) { + return false; + } + vector extractedStatements; vector savedComments; + unordered_set extractedSet; + map originalLineNumbers; for (SgStatement* stmt : newOrder) { - if (stmt && stmt != loop && stmt != loopEnd) { + if (stmt && stmt != loop && stmt != loopEnd && extractedSet.find(stmt) == extractedSet.end()) { + if (control_tags.find(stmt->variant()) != control_tags.end()) { + continue; + } + + if (!canSafelyExtract(stmt, loop)) { + continue; + } + + bool isMoving = false; + for (size_t i = 0; i < originalOrder.size(); i++) { + if (originalOrder[i] == stmt) { + for (size_t j = 0; j < newOrder.size(); j++) { + if (newOrder[j] == stmt && i != j) { + isMoving = true; + break; + } + } + break; + } + } + + if (!isMoving) { + continue; + } + + originalLineNumbers[stmt] = stmt->lineNumber(); savedComments.push_back(stmt->comments() ? strdup(stmt->comments()) : nullptr); SgStatement* extracted = stmt->extractStmt(); if (extracted) { extractedStatements.push_back(extracted); + extractedSet.insert(stmt); } } } SgStatement* currentPos = loop; - int lineCounter = loop->lineNumber() + 1; for (size_t i = 0; i < extractedStatements.size(); i++) { SgStatement* stmt = extractedStatements[i]; if (stmt) { + SgStatement* nextPos = currentPos->lexNext(); + if (nextPos && nextPos != loopEnd) { + if (nextPos->variant() == FOR_NODE && nextPos != loop) { + continue; + } + if (nextPos->variant() == CONTROL_END) { + continue; + } + } + if (i < savedComments.size() && savedComments[i]) { stmt->setComments(savedComments[i]); } - stmt->setlineNumber(lineCounter++); + + if (originalLineNumbers.find(stmt) != originalLineNumbers.end()) { + stmt->setlineNumber(originalLineNumbers[stmt]); + } + currentPos->insertStmtAfter(*stmt, *loop); currentPos = stmt; } @@ -258,17 +481,24 @@ vector findFuncBlocksByFuncStatement(SgStatement *st, map> findAndAnalyzeLoops(SgStatement *st, vector blocks) { map> result; SgStatement *lastNode = st->lastNodeOfStmt(); + while (st && st != lastNode) { if (loop_tags.find(st -> variant()) != loop_tags.end()) { SgForStmt *forSt = (SgForStmt*)st; SgStatement *loopBody = forSt -> body(); SgStatement *lastLoopNode = st->lastNodeOfStmt(); unordered_set blocks_nums; + while (loopBody && loopBody != lastLoopNode) { - SAPFOR::IR_Block* IR = findInstructionsFromOperator(loopBody, blocks).front(); - if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end()) { - result[forSt].push_back(IR -> getBasicBlock()); - blocks_nums.insert(IR -> getBasicBlock() -> getNumber()); + vector irBlocks = findInstructionsFromOperator(loopBody, blocks); + if (!irBlocks.empty()) { + SAPFOR::IR_Block* IR = irBlocks.front(); + if (IR && IR->getBasicBlock()) { + if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end()) { + result[forSt].push_back(IR -> getBasicBlock()); + blocks_nums.insert(IR -> getBasicBlock() -> getNumber()); + } + } } loopBody = loopBody -> lexNext(); } @@ -281,19 +511,25 @@ map> findAndAnalyzeLoops(SgStatement *st void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) { countOfTransform += 1; + + std::cout << "SWAP_OPERATORS Pass Started" << std::endl; const int funcNum = file -> numberOfFunctions(); + for (int i = 0; i < funcNum; ++i) { SgStatement *st = file -> functions(i); + vector blocks = findFuncBlocksByFuncStatement(st, FullIR); + map> loopsMapping = findAndAnalyzeLoops(st, blocks); for (pair> loopForAnalyze: loopsMapping) { vector operators = analyzeOperatorsInLoop(loopForAnalyze.first, loopForAnalyze.second, FullIR); map> varDefinitions = findVariableDefinitions(loopForAnalyze.first, operators); - vector newOrder = optimizeOperatorOrder(loopForAnalyze.first, operators, varDefinitions); applyOperatorReordering(loopForAnalyze.first, newOrder); } } + + std::cout << "SWAP_OPERATORS Pass Completed" << std::endl; } \ No newline at end of file From 6907f44ac54a2d3f1009e2e5b856b09545991033 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Thu, 25 Dec 2025 15:01:01 +0300 Subject: [PATCH 15/20] fixes & improvements --- .../SwapOperators/swap_operators.cpp | 412 +++++++++++++++--- 1 file changed, 347 insertions(+), 65 deletions(-) diff --git a/src/Transformations/SwapOperators/swap_operators.cpp b/src/Transformations/SwapOperators/swap_operators.cpp index 3f5d28a..8871145 100644 --- a/src/Transformations/SwapOperators/swap_operators.cpp +++ b/src/Transformations/SwapOperators/swap_operators.cpp @@ -26,7 +26,6 @@ static vector findInstructionsFromOperator(SgStatement* st, v vector instructionsInBlock = block->getInstructions(); for (auto& instruction: instructionsInBlock) { SgStatement* curOperator = instruction->getInstruction()->getOperator(); - // Match by line number to find corresponding IR instruction if (curOperator->lineNumber() == st->lineNumber()) { result.push_back(instruction); } @@ -35,9 +34,9 @@ static vector findInstructionsFromOperator(SgStatement* st, v return result; } -unordered_set loop_tags = {FOR_NODE}; // Loop statements -unordered_set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; // Control structures that cannot be moved -unordered_set control_end_tags = {CONTROL_END}; // End marker +unordered_set loop_tags = {FOR_NODE}; +unordered_set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; +unordered_set control_end_tags = {CONTROL_END}; struct OperatorInfo { SgStatement* stmt; @@ -254,7 +253,7 @@ static int calculateDistance(SgStatement* from, SgStatement* to) { return abs(to->lineNumber() - from->lineNumber()); } -static SgStatement* findBestPosition(SgStatement* operatorStmt, vector& operators, map>& varDefinitions) { +static SgStatement* findBestPosition(SgStatement* operatorStmt, vector& operators, map>& varDefinitions, SgForStmt* loop) { OperatorInfo* opInfo = nullptr; for (auto& op : operators) { if (op.stmt == operatorStmt) { @@ -268,20 +267,52 @@ static SgStatement* findBestPosition(SgStatement* operatorStmt, vectorusedVars) { if (varDefinitions.find(usedVar) != varDefinitions.end()) { for (SgStatement* defStmt : varDefinitions[usedVar]) { - int distance = calculateDistance(operatorStmt, defStmt); - if (distance < minDistance) { - minDistance = distance; - bestPos = defStmt; + if (defStmt->lineNumber() < operatorStmt->lineNumber()) { + if (defStmt->controlParent() == operatorStmt->controlParent()) { + if (defStmt->lineNumber() > bestLine) { + bestLine = defStmt->lineNumber(); + bestPos = defStmt; + } + } } } } } + if (!bestPos) { + bool allLoopCarried = true; + bool hasAnyDefinition = false; + + for (const string& usedVar : opInfo->usedVars) { + if (varDefinitions.find(usedVar) != varDefinitions.end()) { + for (SgStatement* defStmt : varDefinitions[usedVar]) { + if (defStmt == operatorStmt) { + continue; + } + + hasAnyDefinition = true; + + if (defStmt->lineNumber() < operatorStmt->lineNumber() && + defStmt->controlParent() == operatorStmt->controlParent()) { + allLoopCarried = false; + break; + } + } + } + if (!allLoopCarried) break; + } + + if (allLoopCarried || (!hasAnyDefinition && !opInfo->usedVars.empty())) { + SgStatement* loopStart = loop->lexNext(); + return loopStart; + } + } + return bestPos; } @@ -293,24 +324,37 @@ static bool canMoveTo(SgStatement* from, SgStatement* to, SgForStmt* loop) { if (!loopStart || !loopEnd) return false; + if (to == loopStart) { + SgStatement* fromControlParent = from->controlParent(); + if (!fromControlParent) fromControlParent = loop; + return fromControlParent == loop || fromControlParent == loopStart->controlParent(); + } + + if (from->lineNumber() < loopStart->lineNumber() || from->lineNumber() > loopEnd->lineNumber()) { + return false; + } if (to->lineNumber() < loopStart->lineNumber() || to->lineNumber() > loopEnd->lineNumber()) { return false; } - SgStatement* current = from; - unordered_set visited; + if (to->lineNumber() >= from->lineNumber()) { + return false; + } - while (current && current != loopEnd) { - - if (visited.find(current) != visited.end()) { - return false; - } - visited.insert(current); - + if (from->controlParent() != to->controlParent()) { + return false; + } + + SgStatement* current = to->lexNext(); + while (current && current != from && current != loopEnd) { if (control_tags.find(current->variant()) != control_tags.end()) { - return false; + SgStatement* controlEnd = current->lastNodeOfStmt(); + if (controlEnd && from->lineNumber() <= controlEnd->lineNumber()) { + if (from->controlParent() == current && to->controlParent() != current) { + return false; + } + } } - if (current == to) break; current = current->lexNext(); } @@ -319,33 +363,204 @@ static bool canMoveTo(SgStatement* from, SgStatement* to, SgForStmt* loop) { static vector optimizeOperatorOrder(SgForStmt* loop, vector& operators, map>& varDefinitions) { vector newOrder; - vector moved(operators.size(), false); + for (auto& op : operators) { + newOrder.push_back(op.stmt); + } - for (size_t i = 0; i < operators.size(); i++) { - if (moved[i] || !operators[i].isMovable) { - newOrder.push_back(operators[i].stmt); - moved[i] = true; - continue; - } + map stmtToOpInfo; + for (auto& op : operators) { + stmtToOpInfo[op.stmt] = &op; + } + + bool changed = true; + int iterations = 0; + const int MAX_ITERATIONS = 50; + + while (changed && iterations < MAX_ITERATIONS) { + changed = false; + iterations++; - SgStatement* bestPos = findBestPosition(operators[i].stmt, operators, varDefinitions); - - if (bestPos && canMoveTo(operators[i].stmt, bestPos, loop)) { - bool inserted = false; + for (int i = operators.size() - 1; i >= 0; i--) { + if (!operators[i].isMovable) continue; + + SgStatement* stmt = operators[i].stmt; + OperatorInfo* opInfo = stmtToOpInfo[stmt]; + if (!opInfo) continue; + + size_t currentPos = 0; for (size_t j = 0; j < newOrder.size(); j++) { - if (newOrder[j] == bestPos) { - newOrder.insert(newOrder.begin() + j + 1, operators[i].stmt); - inserted = true; + if (newOrder[j] == stmt) { + currentPos = j; break; } } - if (!inserted) { - newOrder.push_back(operators[i].stmt); + + SgStatement* bestPos = findBestPosition(stmt, operators, varDefinitions, loop); + + if (!bestPos) { + bool hasDependents = false; + for (size_t j = currentPos + 1; j < newOrder.size(); j++) { + SgStatement* candidate = newOrder[j]; + OperatorInfo* candidateOpInfo = stmtToOpInfo[candidate]; + if (candidateOpInfo) { + for (const string& definedVar : opInfo->definedVars) { + if (candidateOpInfo->usedVars.find(definedVar) != candidateOpInfo->usedVars.end()) { + hasDependents = true; + break; + } + } + if (hasDependents) break; + } + } + + continue; + } + + size_t targetPos = 0; + bool foundTarget = false; + + if (bestPos == loop->lexNext()) { + targetPos = 0; + + for (size_t j = 0; j < currentPos && j < newOrder.size(); j++) { + SgStatement* candidate = newOrder[j]; + OperatorInfo* candidateOpInfo = stmtToOpInfo[candidate]; + if (candidateOpInfo) { + bool usesDefinedVar = false; + for (const string& definedVar : opInfo->definedVars) { + if (candidateOpInfo->usedVars.find(definedVar) != candidateOpInfo->usedVars.end()) { + usesDefinedVar = true; + break; + } + } + if (usesDefinedVar) { + targetPos = j; + break; + } + } + } + + foundTarget = true; + + if (currentPos != targetPos && canMoveTo(stmt, bestPos, loop)) { + newOrder.erase(newOrder.begin() + currentPos); + newOrder.insert(newOrder.begin() + targetPos, stmt); + changed = true; + } + } else { + size_t bestPosIdx = 0; + bool foundBestPos = false; + for (size_t j = 0; j < newOrder.size(); j++) { + if (newOrder[j] == bestPos) { + bestPosIdx = j; + foundBestPos = true; + break; + } + } + + if (foundBestPos) { + targetPos = bestPosIdx + 1; + + for (size_t j = bestPosIdx + 1; j < currentPos && j < newOrder.size(); j++) { + SgStatement* candidate = newOrder[j]; + OperatorInfo* candidateOpInfo = stmtToOpInfo[candidate]; + if (candidateOpInfo) { + bool definesUsedVar = false; + for (const string& usedVar : opInfo->usedVars) { + if (candidateOpInfo->definedVars.find(usedVar) != candidateOpInfo->definedVars.end()) { + definesUsedVar = true; + break; + } + } + if (definesUsedVar) { + targetPos = j + 1; + } + } + } + + bool wouldBreakDependency = false; + for (size_t j = targetPos; j < currentPos && j < newOrder.size(); j++) { + SgStatement* candidate = newOrder[j]; + OperatorInfo* candidateOpInfo = stmtToOpInfo[candidate]; + if (candidateOpInfo) { + for (const string& definedVar : opInfo->definedVars) { + if (candidateOpInfo->usedVars.find(definedVar) != candidateOpInfo->usedVars.end()) { + wouldBreakDependency = true; + break; + } + } + if (wouldBreakDependency) break; + } + } + + if (!wouldBreakDependency && currentPos > targetPos && canMoveTo(stmt, bestPos, loop)) { + newOrder.erase(newOrder.begin() + currentPos); + newOrder.insert(newOrder.begin() + targetPos, stmt); + changed = true; + } + } } - } else { - newOrder.push_back(operators[i].stmt); } - moved[i] = true; + } + + bool dependencyViolation = true; + set> triedPairs; + + while (dependencyViolation) { + dependencyViolation = false; + triedPairs.clear(); + + for (size_t i = 0; i < newOrder.size(); i++) { + SgStatement* stmt = newOrder[i]; + OperatorInfo* opInfo = stmtToOpInfo[stmt]; + if (!opInfo) continue; + + for (size_t j = 0; j < i; j++) { + SgStatement* prevStmt = newOrder[j]; + OperatorInfo* prevOpInfo = stmtToOpInfo[prevStmt]; + if (!prevOpInfo) continue; + + pair key = make_pair(stmt, prevStmt); + if (triedPairs.find(key) != triedPairs.end()) { + continue; + } + + bool violation = false; + for (const string& definedVar : opInfo->definedVars) { + if (prevOpInfo->usedVars.find(definedVar) != prevOpInfo->usedVars.end()) { + violation = true; + break; + } + } + + if (violation) { + triedPairs.insert(key); + + bool wouldCreateViolation = false; + for (size_t k = j; k < i; k++) { + SgStatement* betweenStmt = newOrder[k]; + OperatorInfo* betweenOpInfo = stmtToOpInfo[betweenStmt]; + if (!betweenOpInfo) continue; + + for (const string& usedVar : opInfo->usedVars) { + if (betweenOpInfo->definedVars.find(usedVar) != betweenOpInfo->definedVars.end()) { + wouldCreateViolation = true; + break; + } + } + if (wouldCreateViolation) break; + } + + if (!wouldCreateViolation) { + newOrder.erase(newOrder.begin() + i); + newOrder.insert(newOrder.begin() + j, stmt); + dependencyViolation = true; + break; + } + } + } + if (dependencyViolation) break; + } } return newOrder; @@ -388,6 +603,7 @@ static bool applyOperatorReordering(SgForStmt* loop, vector& newOr vector savedComments; unordered_set extractedSet; map originalLineNumbers; + map stmtToExtracted; for (SgStatement* stmt : newOrder) { if (stmt && stmt != loop && stmt != loopEnd && extractedSet.find(stmt) == extractedSet.end()) { @@ -422,35 +638,77 @@ static bool applyOperatorReordering(SgForStmt* loop, vector& newOr if (extracted) { extractedStatements.push_back(extracted); extractedSet.insert(stmt); + stmtToExtracted[stmt] = extracted; } } } - SgStatement* currentPos = loop; + map insertedStatements; - for (size_t i = 0; i < extractedStatements.size(); i++) { - SgStatement* stmt = extractedStatements[i]; - if (stmt) { - SgStatement* nextPos = currentPos->lexNext(); - if (nextPos && nextPos != loopEnd) { - if (nextPos->variant() == FOR_NODE && nextPos != loop) { - continue; - } - if (nextPos->variant() == CONTROL_END) { - continue; + for (size_t idx = 0; idx < newOrder.size(); idx++) { + SgStatement* stmt = newOrder[idx]; + + if (extractedSet.find(stmt) != extractedSet.end()) { + SgStatement* stmtToInsert = stmtToExtracted[stmt]; + if (!stmtToInsert) continue; + + SgStatement* insertAfter = loop; + + for (int i = idx - 1; i >= 0; i--) { + SgStatement* prevStmt = newOrder[i]; + + if (extractedSet.find(prevStmt) != extractedSet.end()) { + if (insertedStatements.find(prevStmt) != insertedStatements.end()) { + insertAfter = insertedStatements[prevStmt]; + break; + } + } else { + SgStatement* search = loop->lexNext(); + while (search && search != loopEnd) { + bool skip = false; + for (size_t j = idx; j < newOrder.size(); j++) { + if (extractedSet.find(newOrder[j]) != extractedSet.end() && + search == newOrder[j]) { + skip = true; + break; + } + } + if (skip) { + search = search->lexNext(); + continue; + } + + if (search == prevStmt) { + insertAfter = search; + break; + } + search = search->lexNext(); + } + if (insertAfter != loop) break; } } - if (i < savedComments.size() && savedComments[i]) { - stmt->setComments(savedComments[i]); + size_t commentIdx = 0; + for (size_t i = 0; i < extractedStatements.size(); i++) { + if (extractedStatements[i] == stmtToInsert) { + commentIdx = i; + break; + } } - + + if (commentIdx < savedComments.size() && savedComments[commentIdx]) { + stmtToInsert->setComments(savedComments[commentIdx]); + } + if (originalLineNumbers.find(stmt) != originalLineNumbers.end()) { - stmt->setlineNumber(originalLineNumbers[stmt]); + stmtToInsert->setlineNumber(originalLineNumbers[stmt]); } - currentPos->insertStmtAfter(*stmt, *loop); - currentPos = stmt; + SgStatement* controlParent = stmt->controlParent(); + if (!controlParent) controlParent = loop; + + insertAfter->insertStmtAfter(*stmtToInsert, *controlParent); + insertedStatements[stmt] = stmtToInsert; } } @@ -460,10 +718,6 @@ static bool applyOperatorReordering(SgForStmt* loop, vector& newOr } } - if (currentPos && currentPos->lexNext() != loopEnd) { - currentPos->setLexNext(*loopEnd); - } - return true; } @@ -509,6 +763,37 @@ map> findAndAnalyzeLoops(SgStatement *st return result; } +static void processLoopRecursively(SgForStmt* loop, vector blocks, map>& FullIR) { + if (!loop) return; + + SgStatement* loopStart = loop->lexNext(); + SgStatement* loopEnd = loop->lastNodeOfStmt(); + if (loopStart && loopEnd) { + SgStatement* current = loopStart; + while (current && current != loopEnd) { + if (current->variant() == FOR_NODE && current != loop) { + SgForStmt* nestedLoop = (SgForStmt*)current; + processLoopRecursively(nestedLoop, blocks, FullIR); + SgStatement* nestedEnd = nestedLoop->lastNodeOfStmt(); + if (nestedEnd) { + current = nestedEnd->lexNext(); + } else { + current = current->lexNext(); + } + } else { + current = current->lexNext(); + } + } + } + + vector operators = analyzeOperatorsInLoop(loop, blocks, FullIR); + if (!operators.empty()) { + map> varDefinitions = findVariableDefinitions(loop, operators); + vector newOrder = optimizeOperatorOrder(loop, operators, varDefinitions); + applyOperatorReordering(loop, newOrder); + } +} + void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) { countOfTransform += 1; @@ -524,10 +809,7 @@ void runSwapOperators(SgFile *file, std::map> loopsMapping = findAndAnalyzeLoops(st, blocks); for (pair> loopForAnalyze: loopsMapping) { - vector operators = analyzeOperatorsInLoop(loopForAnalyze.first, loopForAnalyze.second, FullIR); - map> varDefinitions = findVariableDefinitions(loopForAnalyze.first, operators); - vector newOrder = optimizeOperatorOrder(loopForAnalyze.first, operators, varDefinitions); - applyOperatorReordering(loopForAnalyze.first, newOrder); + processLoopRecursively(loopForAnalyze.first, loopForAnalyze.second, FullIR); } } From d9f54739d25dc4b90ad63215d03547e12e669f2c Mon Sep 17 00:00:00 2001 From: ALEXks Date: Mon, 29 Dec 2025 21:10:55 +0300 Subject: [PATCH 16/20] refactored --- CMakeLists.txt | 10 +- src/Sapfor.cpp | 10 +- src/Sapfor.h | 4 +- .../move_operators.cpp} | 302 +++++++++--------- .../MoveOperators/move_operators.h | 6 + .../SwapOperators/swap_operators.h | 6 - src/Utils/PassManager.h | 4 +- 7 files changed, 174 insertions(+), 168 deletions(-) rename src/Transformations/{SwapOperators/swap_operators.cpp => MoveOperators/move_operators.cpp} (81%) create mode 100644 src/Transformations/MoveOperators/move_operators.h delete mode 100644 src/Transformations/SwapOperators/swap_operators.h diff --git a/CMakeLists.txt b/CMakeLists.txt index eb214e5..12e61a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,9 +207,9 @@ set(TR_EXPR_TRANSFORM src/Transformations/ExpressionSubstitution/control_flow_gr set(TR_INLINER src/Transformations/FunctionInlining/inliner.cpp src/Transformations/FunctionInlining/inliner.h) set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp - src/Transformations/RenameSymbols/rename_symbols.h) -SET(TR_SWAP_OPERATORS src/Transformations/SwapOperators/swap_operators.cpp - src/Transformations/SwapOperators/swap_operators.h) + src/Transformations/RenameSymbols/rename_symbols.h) +SET(TR_MOVE_OPERATORS src/Transformations/MoveOperators/move_operators.cpp + src/Transformations/MoveOperators/move_operators.h) set(TRANSFORMS ${TR_DEAD_CODE} @@ -233,7 +233,7 @@ set(TRANSFORMS ${TR_EXPR_TRANSFORM} ${TR_INLINER} ${TR_RENAME_SYMBOLS} - ${TR_SWAP_OPERATORS}) + ${TR_MOVE_OPERATORS}) set(CFG src/CFGraph/IR.cpp src/CFGraph/IR.h @@ -467,7 +467,7 @@ source_group (Transformations\\GlobalVariables FILES ${TR_GV}) source_group (Transformations\\ConvertToC FILES ${TR_CONV}) source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE}) source_group (Transformations\\ReplaceArraysInIO FILES ${TR_REPLACE_ARRAYS_IN_IO}) -source_group (Transformations\\SwapOperators FILES ${TR_SWAP_OPERATORS}) +source_group (Transformations\\MoveOperators FILES ${TR_MOVE_OPERATORS}) source_group (CreateIntervals FILES ${CREATE_INTER_T}) diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index 257d38d..7baa9b8 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -90,7 +90,7 @@ #include "Transformations/DeadCodeRemoving/dead_code.h" #include "Transformations/RenameSymbols/rename_symbols.h" #include "Transformations/FunctionInlining/inliner.h" -#include "Transformations/SwapOperators/swap_operators.h" +#include "Transformations/MoveOperators/move_operators.h" #include "ProjectParameters/projectParameters.h" @@ -942,8 +942,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne internalExit = err; } } - else if (curr_regime == SWAP_OPERATORS) - runSwapOperators(file, loopGraph, fullIR, countOfTransform); + else if (curr_regime == MOVE_OPERATORS) + moveOperators(file, loopGraph, fullIR, countOfTransform); else if (curr_regime == PRIVATE_REMOVING_ANALYSIS) { auto itFound = loopGraph.find(file->filename()); @@ -1041,7 +1041,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne PRIVATE_ARRAYS_EXPANSION, PRIVATE_ARRAYS_SHRINKING, REMOVE_DEAD_CODE, - SWAP_OPERATORS }; + MOVE_OPERATORS }; if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end()) { @@ -2343,7 +2343,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam case INSERT_NO_DISTR_FLAGS_FROM_GUI: case PRIVATE_REMOVING: case RENAME_INLCUDES: - case SWAP_OPERATORS: + case MOVE_OPERATORS: runAnalysis(*project, curr_regime, true, "", folderName); break; case INLINE_PROCEDURES: diff --git a/src/Sapfor.h b/src/Sapfor.h index 7c2b74c..f5dadd1 100644 --- a/src/Sapfor.h +++ b/src/Sapfor.h @@ -122,7 +122,7 @@ enum passes { CREATE_INTER_TREE, INSERT_INTER_TREE, - SWAP_OPERATORS, + MOVE_OPERATORS, SHADOW_GROUPING, INLINE_PROCEDURES, @@ -323,7 +323,7 @@ static void setPassValues() passNames[CHECK_PAR_REG_DIR] = "CHECK_PAR_REG_DIR"; passNames[CREATE_INTER_TREE] = "CREATE_INTER_TREE"; passNames[INSERT_INTER_TREE] = "INSERT_INTER_TREE"; - passNames[SWAP_OPERATORS] = "SWAP_OPERATORS"; + passNames[MOVE_OPERATORS] = "MOVE_OPERATORS"; passNames[CREATE_PARALLEL_REGIONS] = "CREATE_PARALLEL_REGIONS"; passNames[PRIVATE_REMOVING_ANALYSIS] = "PRIVATE_REMOVING_ANALYSIS"; passNames[PRIVATE_REMOVING] = "PRIVATE_REMOVING"; diff --git a/src/Transformations/SwapOperators/swap_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp similarity index 81% rename from src/Transformations/SwapOperators/swap_operators.cpp rename to src/Transformations/MoveOperators/move_operators.cpp index 8871145..00fec2d 100644 --- a/src/Transformations/SwapOperators/swap_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -12,31 +12,29 @@ #include "../../CFGraph/CFGraph.h" #include "../../CFGraph/IR.h" #include "../../GraphLoop/graph_loops.h" -#include "swap_operators.h" +#include "move_operators.h" using namespace std; -string getNameByArg(SAPFOR::Argument* arg); - -static vector findInstructionsFromOperator(SgStatement* st, vector Blocks) { +static vector findInstructionsFromOperator(SgStatement* st, const vector& Blocks) { vector result; string filename = st->fileName(); for (auto& block: Blocks) { vector instructionsInBlock = block->getInstructions(); + for (auto& instruction: instructionsInBlock) { SgStatement* curOperator = instruction->getInstruction()->getOperator(); - if (curOperator->lineNumber() == st->lineNumber()) { + if (curOperator->lineNumber() == st->lineNumber()) result.push_back(instruction); - } } } return result; } -unordered_set loop_tags = {FOR_NODE}; -unordered_set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; -unordered_set control_end_tags = {CONTROL_END}; +const unordered_set loop_tags = { FOR_NODE }; +const unordered_set control_tags = { IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE }; +const unordered_set control_end_tags = { CONTROL_END }; struct OperatorInfo { SgStatement* stmt; @@ -45,58 +43,58 @@ struct OperatorInfo { int lineNumber; bool isMovable; - OperatorInfo(SgStatement* s) : stmt(s), lineNumber(s->lineNumber()), isMovable(true) {} + OperatorInfo(SgStatement* s) : stmt(s), lineNumber(s->lineNumber()), isMovable(true) { } }; static bool isStatementEmbedded(SgStatement* stmt, SgStatement* parent) { - if (!stmt || !parent || stmt == parent) return false; + if (!stmt || !parent || stmt == parent) + return false; if (parent->variant() == LOGIF_NODE) { - if (stmt->lineNumber() == parent->lineNumber()) { + if (stmt->lineNumber() == parent->lineNumber()) return true; - } SgStatement* current = parent; SgStatement* lastNode = parent->lastNodeOfStmt(); while (current && current != lastNode) { - if (current == stmt) { + if (current == stmt) return true; - } - if (current->isIncludedInStmt(*stmt)) { + + if (current->isIncludedInStmt(*stmt)) return true; - } + current = current->lexNext(); } } - if (parent->isIncludedInStmt(*stmt)) { + if (parent->isIncludedInStmt(*stmt)) return true; - } return false; } static bool isLoopBoundary(SgStatement* stmt) { - if (!stmt) return false; + if (!stmt) + return false; - if (stmt->variant() == FOR_NODE || stmt->variant() == CONTROL_END) { + if (stmt->variant() == FOR_NODE || stmt->variant() == CONTROL_END) return true; - } return false; } static bool isPartOfNestedLoop(SgStatement* stmt, SgForStmt* loop) { - if (!stmt || !loop) return false; + if (!stmt || !loop) + return false; SgStatement* loopStart = loop->lexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); - if (!loopStart || !loopEnd) return false; - - if (stmt->lineNumber() < loopStart->lineNumber() || stmt->lineNumber() > loopEnd->lineNumber()) { + if (!loopStart || !loopEnd) + return false; + + if (stmt->lineNumber() < loopStart->lineNumber() || stmt->lineNumber() > loopEnd->lineNumber()) return false; - } SgStatement* current = loopStart; @@ -121,60 +119,58 @@ static bool isPartOfNestedLoop(SgStatement* stmt, SgForStmt* loop) { } static bool canSafelyExtract(SgStatement* stmt, SgForStmt* loop) { - if (!stmt || !loop) return false; - - if (isLoopBoundary(stmt)) { + if (!stmt || !loop) return false; - } - if (control_tags.find(stmt->variant()) != control_tags.end()) { + if (isLoopBoundary(stmt)) return false; - } - if (isPartOfNestedLoop(stmt, loop)) { + if (control_tags.find(stmt->variant()) != control_tags.end()) + return false; + + if (isPartOfNestedLoop(stmt, loop)) return false; - } SgStatement* loopStart = loop->lexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); - if (!loopStart || !loopEnd) return false; + if (!loopStart || !loopEnd) + return false; SgStatement* current = loopStart; while (current && current != loopEnd) { - if (current->variant() == LOGIF_NODE && current->lineNumber() == stmt->lineNumber()) { + if (current->variant() == LOGIF_NODE && current->lineNumber() == stmt->lineNumber()) return false; - } - if (control_tags.find(current->variant()) != control_tags.end()) { - if (isStatementEmbedded(stmt, current)) { + if (control_tags.find(current->variant()) != control_tags.end()) + if (isStatementEmbedded(stmt, current)) return false; - } - } - if (current == stmt) break; + + if (current == stmt) + break; current = current->lexNext(); } return true; } -static vector analyzeOperatorsInLoop(SgForStmt* loop, vector blocks, map>& FullIR) { +static vector analyzeOperatorsInLoop(SgForStmt* loop, const vector& blocks, + const map>& FullIR) { vector operators; SgStatement* loopStart = loop->lexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); - if (!loopStart || !loopEnd) { + if (!loopStart || !loopEnd) return operators; - } SgStatement* current = loopStart; unordered_set visited; while (current && current != loopEnd) { - if (visited.find(current) != visited.end()) { + if (visited.find(current) != visited.end()) break; - } + visited.insert(current); if (isLoopBoundary(current)) { @@ -184,11 +180,10 @@ static vector analyzeOperatorsInLoop(SgForStmt* loop, vectorvariant() == FOR_NODE && current != loop) { SgStatement* nestedEnd = current->lastNodeOfStmt(); - if (nestedEnd) { + if (nestedEnd) current = nestedEnd->lexNext(); - } else { + else current = current->lexNext(); - } continue; } @@ -197,6 +192,7 @@ static vector analyzeOperatorsInLoop(SgForStmt* loop, vectorlexNext(); continue; } + if (current->variant() != ASSIGN_STAT) { current = current->lexNext(); continue; @@ -206,27 +202,26 @@ static vector analyzeOperatorsInLoop(SgForStmt* loop, vector irBlocks = findInstructionsFromOperator(current, blocks); for (auto irBlock : irBlocks) { - if (!irBlock || !irBlock->getInstruction()) continue; - - SAPFOR::Instruction* instr = irBlock->getInstruction(); + if (!irBlock || !irBlock->getInstruction()) + continue; + const SAPFOR::Instruction* instr = irBlock->getInstruction(); if (instr->getArg1()) { string varName = getNameByArg(instr->getArg1()); - if (!varName.empty()) { + if (!varName.empty()) opInfo.usedVars.insert(varName); - } } + if (instr->getArg2()) { string varName = getNameByArg(instr->getArg2()); - if (!varName.empty()) { + if (!varName.empty()) opInfo.usedVars.insert(varName); - } } + if (instr->getResult()) { string varName = getNameByArg(instr->getResult()); - if (!varName.empty()) { + if (!varName.empty()) opInfo.definedVars.insert(varName); - } } } @@ -249,29 +244,31 @@ static map> findVariableDefinitions(SgForStmt* loop } static int calculateDistance(SgStatement* from, SgStatement* to) { - if (!from || !to) return INT_MAX; + if (!from || !to) + return INT_MAX; + return abs(to->lineNumber() - from->lineNumber()); } -static SgStatement* findBestPosition(SgStatement* operatorStmt, vector& operators, map>& varDefinitions, SgForStmt* loop) { - OperatorInfo* opInfo = nullptr; +static SgStatement* findBestPosition(SgStatement* operatorStmt, const vector& operators, + const map>& varDefinitions, SgForStmt* loop) { + const OperatorInfo* opInfo = nullptr; for (auto& op : operators) { if (op.stmt == operatorStmt) { opInfo = &op; break; } } - - if (!opInfo || !opInfo->isMovable) { + + if (!opInfo || !opInfo->isMovable) return nullptr; - } SgStatement* bestPos = nullptr; int bestLine = -1; for (const string& usedVar : opInfo->usedVars) { if (varDefinitions.find(usedVar) != varDefinitions.end()) { - for (SgStatement* defStmt : varDefinitions[usedVar]) { + for (SgStatement* defStmt : varDefinitions.at(usedVar)) { if (defStmt->lineNumber() < operatorStmt->lineNumber()) { if (defStmt->controlParent() == operatorStmt->controlParent()) { if (defStmt->lineNumber() > bestLine) { @@ -290,13 +287,11 @@ static SgStatement* findBestPosition(SgStatement* operatorStmt, vectorusedVars) { if (varDefinitions.find(usedVar) != varDefinitions.end()) { - for (SgStatement* defStmt : varDefinitions[usedVar]) { - if (defStmt == operatorStmt) { + for (SgStatement* defStmt : varDefinitions.at(usedVar)) { + if (defStmt == operatorStmt) continue; - } hasAnyDefinition = true; - if (defStmt->lineNumber() < operatorStmt->lineNumber() && defStmt->controlParent() == operatorStmt->controlParent()) { allLoopCarried = false; @@ -304,7 +299,9 @@ static SgStatement* findBestPosition(SgStatement* operatorStmt, vectorusedVars.empty())) { @@ -317,12 +314,14 @@ static SgStatement* findBestPosition(SgStatement* operatorStmt, vectorlexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); - if (!loopStart || !loopEnd) return false; + if (!loopStart || !loopEnd) + return false; if (to == loopStart) { SgStatement* fromControlParent = from->controlParent(); @@ -330,20 +329,17 @@ static bool canMoveTo(SgStatement* from, SgStatement* to, SgForStmt* loop) { return fromControlParent == loop || fromControlParent == loopStart->controlParent(); } - if (from->lineNumber() < loopStart->lineNumber() || from->lineNumber() > loopEnd->lineNumber()) { + if (from->lineNumber() < loopStart->lineNumber() || from->lineNumber() > loopEnd->lineNumber()) return false; - } - if (to->lineNumber() < loopStart->lineNumber() || to->lineNumber() > loopEnd->lineNumber()) { + + if (to->lineNumber() < loopStart->lineNumber() || to->lineNumber() > loopEnd->lineNumber()) return false; - } - if (to->lineNumber() >= from->lineNumber()) { + if (to->lineNumber() >= from->lineNumber()) return false; - } - if (from->controlParent() != to->controlParent()) { + if (from->controlParent() != to->controlParent()) return false; - } SgStatement* current = to->lexNext(); while (current && current != from && current != loopEnd) { @@ -361,16 +357,16 @@ static bool canMoveTo(SgStatement* from, SgStatement* to, SgForStmt* loop) { return true; } -static vector optimizeOperatorOrder(SgForStmt* loop, vector& operators, map>& varDefinitions) { +static vector optimizeOperatorOrder(SgForStmt* loop, + const vector& operators, + const map>& varDefinitions) { vector newOrder; - for (auto& op : operators) { + for (auto& op : operators) newOrder.push_back(op.stmt); - } - map stmtToOpInfo; - for (auto& op : operators) { + map stmtToOpInfo; + for (auto& op : operators) stmtToOpInfo[op.stmt] = &op; - } bool changed = true; int iterations = 0; @@ -381,11 +377,14 @@ static vector optimizeOperatorOrder(SgForStmt* loop, vector= 0; i--) { - if (!operators[i].isMovable) continue; + if (!operators[i].isMovable) + continue; SgStatement* stmt = operators[i].stmt; - OperatorInfo* opInfo = stmtToOpInfo[stmt]; - if (!opInfo) continue; + const OperatorInfo* opInfo = stmtToOpInfo[stmt]; + + if (!opInfo) + continue; size_t currentPos = 0; for (size_t j = 0; j < newOrder.size(); j++) { @@ -401,7 +400,7 @@ static vector optimizeOperatorOrder(SgForStmt* loop, vectordefinedVars) { if (candidateOpInfo->usedVars.find(definedVar) != candidateOpInfo->usedVars.end()) { @@ -409,7 +408,9 @@ static vector optimizeOperatorOrder(SgForStmt* loop, vector optimizeOperatorOrder(SgForStmt* loop, vectordefinedVars) { @@ -463,7 +464,7 @@ static vector optimizeOperatorOrder(SgForStmt* loop, vectorusedVars) { @@ -472,16 +473,15 @@ static vector optimizeOperatorOrder(SgForStmt* loop, vectordefinedVars) { if (candidateOpInfo->usedVars.find(definedVar) != candidateOpInfo->usedVars.end()) { @@ -489,7 +489,9 @@ static vector optimizeOperatorOrder(SgForStmt* loop, vector optimizeOperatorOrder(SgForStmt* loop, vector key = make_pair(stmt, prevStmt); - if (triedPairs.find(key) != triedPairs.end()) { + if (triedPairs.find(key) != triedPairs.end()) continue; - } bool violation = false; for (const string& definedVar : opInfo->definedVars) { @@ -539,8 +542,10 @@ static vector optimizeOperatorOrder(SgForStmt* loop, vectorusedVars) { if (betweenOpInfo->definedVars.find(usedVar) != betweenOpInfo->definedVars.end()) { @@ -548,7 +553,9 @@ static vector optimizeOperatorOrder(SgForStmt* loop, vector optimizeOperatorOrder(SgForStmt* loop, vector& newOrder) { - if (!loop || newOrder.empty()) return false; +static bool applyOperatorReordering(SgForStmt* loop, const vector& newOrder) { + if (!loop || newOrder.empty()) + return false; SgStatement* loopStart = loop->lexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); - if (!loopStart || !loopEnd) return false; + if (!loopStart || !loopEnd) + return false; vector originalOrder; SgStatement* current = loopStart; while (current && current != loopEnd) { - if (isSgExecutableStatement(current) && current->variant() == ASSIGN_STAT) { + if (isSgExecutableStatement(current) && current->variant() == ASSIGN_STAT) originalOrder.push_back(current); - } + current = current->lexNext(); } @@ -591,14 +601,13 @@ static bool applyOperatorReordering(SgForStmt* loop, vector& newOr break; } } - } else { + } + else orderChanged = true; - } - if (!orderChanged) { + if (!orderChanged) return false; - } - + vector extractedStatements; vector savedComments; unordered_set extractedSet; @@ -607,13 +616,11 @@ static bool applyOperatorReordering(SgForStmt* loop, vector& newOr for (SgStatement* stmt : newOrder) { if (stmt && stmt != loop && stmt != loopEnd && extractedSet.find(stmt) == extractedSet.end()) { - if (control_tags.find(stmt->variant()) != control_tags.end()) { + if (control_tags.find(stmt->variant()) != control_tags.end()) continue; - } - if (!canSafelyExtract(stmt, loop)) { + if (!canSafelyExtract(stmt, loop)) continue; - } bool isMoving = false; for (size_t i = 0; i < originalOrder.size(); i++) { @@ -628,9 +635,8 @@ static bool applyOperatorReordering(SgForStmt* loop, vector& newOr } } - if (!isMoving) { + if (!isMoving) continue; - } originalLineNumbers[stmt] = stmt->lineNumber(); savedComments.push_back(stmt->comments() ? strdup(stmt->comments()) : nullptr); @@ -696,16 +702,15 @@ static bool applyOperatorReordering(SgForStmt* loop, vector& newOr } } - if (commentIdx < savedComments.size() && savedComments[commentIdx]) { + if (commentIdx < savedComments.size() && savedComments[commentIdx]) stmtToInsert->setComments(savedComments[commentIdx]); - } - if (originalLineNumbers.find(stmt) != originalLineNumbers.end()) { + if (originalLineNumbers.find(stmt) != originalLineNumbers.end()) stmtToInsert->setlineNumber(originalLineNumbers[stmt]); - } SgStatement* controlParent = stmt->controlParent(); - if (!controlParent) controlParent = loop; + if (!controlParent) + controlParent = loop; insertAfter->insertStmtAfter(*stmtToInsert, *controlParent); insertedStatements[stmt] = stmtToInsert; @@ -713,17 +718,17 @@ static bool applyOperatorReordering(SgForStmt* loop, vector& newOr } for (char* comment : savedComments) { - if (comment) { + if (comment) free(comment); - } } return true; } -vector findFuncBlocksByFuncStatement(SgStatement *st, map>& FullIR) { +vector findFuncBlocksByFuncStatement(SgStatement *st, const map>& FullIR) { vector result; Statement* forSt = (Statement*)st; + for (auto& func: FullIR) { if (func.first -> funcPointer -> getCurrProcessFile() == forSt -> getCurrProcessFile() && func.first -> funcPointer -> lineNumber() == forSt -> lineNumber()) @@ -732,7 +737,7 @@ vector findFuncBlocksByFuncStatement(SgStatement *st, map> findAndAnalyzeLoops(SgStatement *st, vector blocks) { +map> findAndAnalyzeLoops(SgStatement *st, const vector& blocks) { map> result; SgStatement *lastNode = st->lastNodeOfStmt(); @@ -756,14 +761,15 @@ map> findAndAnalyzeLoops(SgStatement *st } loopBody = loopBody -> lexNext(); } - std::sort(result[forSt].begin(), result[forSt].end()); + sort(result[forSt].begin(), result[forSt].end()); } st = st -> lexNext(); } return result; } -static void processLoopRecursively(SgForStmt* loop, vector blocks, map>& FullIR) { +static void processLoopRecursively(SgForStmt* loop, const vector& blocks, + const map>& FullIR) { if (!loop) return; SgStatement* loopStart = loop->lexNext(); @@ -775,14 +781,14 @@ static void processLoopRecursively(SgForStmt* loop, vector SgForStmt* nestedLoop = (SgForStmt*)current; processLoopRecursively(nestedLoop, blocks, FullIR); SgStatement* nestedEnd = nestedLoop->lastNodeOfStmt(); - if (nestedEnd) { + + if (nestedEnd) current = nestedEnd->lexNext(); - } else { + else current = current->lexNext(); - } - } else { + } + else current = current->lexNext(); - } } } @@ -794,24 +800,24 @@ static void processLoopRecursively(SgForStmt* loop, vector } } -void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) { +void moveOperators(SgFile *file, map>& loopGraph, + const map>& FullIR, + int& countOfTransform) { countOfTransform += 1; - std::cout << "SWAP_OPERATORS Pass Started" << std::endl; + //cout << "MOVE_OPERATORS Pass Started" << endl; const int funcNum = file -> numberOfFunctions(); for (int i = 0; i < funcNum; ++i) { SgStatement *st = file -> functions(i); - vector blocks = findFuncBlocksByFuncStatement(st, FullIR); - + vector blocks = findFuncBlocksByFuncStatement(st, FullIR); map> loopsMapping = findAndAnalyzeLoops(st, blocks); - for (pair> loopForAnalyze: loopsMapping) { + for (auto& loopForAnalyze: loopsMapping) processLoopRecursively(loopForAnalyze.first, loopForAnalyze.second, FullIR); - } } - std::cout << "SWAP_OPERATORS Pass Completed" << std::endl; + //cout << "MOVE_OPERATORS Pass Completed" << endl; } \ No newline at end of file diff --git a/src/Transformations/MoveOperators/move_operators.h b/src/Transformations/MoveOperators/move_operators.h new file mode 100644 index 0000000..0bbbc9a --- /dev/null +++ b/src/Transformations/MoveOperators/move_operators.h @@ -0,0 +1,6 @@ +#pragma once + +#include "../../GraphLoop/graph_loops.h" +#include "../../CFGraph/CFGraph.h" + +void moveOperators(SgFile *file, std::map>& loopGraph, const std::map>& FullIR, int& countOfTransform); diff --git a/src/Transformations/SwapOperators/swap_operators.h b/src/Transformations/SwapOperators/swap_operators.h deleted file mode 100644 index a23add9..0000000 --- a/src/Transformations/SwapOperators/swap_operators.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "../../GraphLoop/graph_loops.h" -#include "../../CFGraph/CFGraph.h" - -void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform); diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index a9a866a..0ca232e 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -212,8 +212,6 @@ void InitPassesDependencies(map> &passDepsIn, set Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE); - list({BUILD_IR, CALL_GRAPH2}) <= Pass(SWAP_OPERATORS); - list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS); list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING); @@ -321,6 +319,8 @@ void InitPassesDependencies(map> &passDepsIn, set list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS); list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS); + list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS); + passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS, EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW, REVERSE_CREATED_NESTED_LOOPS, PREDICT_SCHEME, CALCULATE_STATS_SCHEME, REVERT_SPF_DIRS, CLEAR_SPF_DIRS, TRANSFORM_SHADOW_IF_FULL, From af8531148024fc458336899f98bfc63a9351d8f8 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Mon, 29 Dec 2025 21:22:53 +0300 Subject: [PATCH 17/20] refactored, added pass to Visualizer calls --- .../MoveOperators/move_operators.cpp | 27 ++++++++++--------- src/Utils/version.h | 2 +- src/VisualizerCalls/get_information.cpp | 9 +++++++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index 00fec2d..d310afe 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -235,11 +235,10 @@ static vector analyzeOperatorsInLoop(SgForStmt* loop, const vector static map> findVariableDefinitions(SgForStmt* loop, vector& operators) { map> varDefinitions; - for (auto& op : operators) { - for (const string& var : op.definedVars) { + for (auto& op : operators) + for (const string& var : op.definedVars) varDefinitions[var].push_back(op.stmt); - } - } + return varDefinitions; } @@ -369,12 +368,9 @@ static vector optimizeOperatorOrder(SgForStmt* loop, stmtToOpInfo[op.stmt] = &op; bool changed = true; - int iterations = 0; - const int MAX_ITERATIONS = 50; - while (changed && iterations < MAX_ITERATIONS) { + while (changed) { changed = false; - iterations++; for (int i = operators.size() - 1; i >= 0; i--) { if (!operators[i].isMovable) @@ -434,6 +430,7 @@ static vector optimizeOperatorOrder(SgForStmt* loop, break; } } + if (usesDefinedVar) { targetPos = j; break; @@ -566,6 +563,7 @@ static vector optimizeOperatorOrder(SgForStmt* loop, } } } + if (dependencyViolation) break; } @@ -656,7 +654,9 @@ static bool applyOperatorReordering(SgForStmt* loop, const vector& if (extractedSet.find(stmt) != extractedSet.end()) { SgStatement* stmtToInsert = stmtToExtracted[stmt]; - if (!stmtToInsert) continue; + + if (!stmtToInsert) + continue; SgStatement* insertAfter = loop; @@ -730,9 +730,11 @@ vector findFuncBlocksByFuncStatement(SgStatement *st, const Statement* forSt = (Statement*)st; for (auto& func: FullIR) { - if (func.first -> funcPointer -> getCurrProcessFile() == forSt -> getCurrProcessFile() - && func.first -> funcPointer -> lineNumber() == forSt -> lineNumber()) + if (func.first->funcPointer->getCurrProcessFile() == forSt->getCurrProcessFile() + && func.first->funcPointer->lineNumber() == forSt->lineNumber()) + { result = func.second; + } } return result; } @@ -770,7 +772,8 @@ map> findAndAnalyzeLoops(SgStatement *st static void processLoopRecursively(SgForStmt* loop, const vector& blocks, const map>& FullIR) { - if (!loop) return; + if (!loop) + return; SgStatement* loopStart = loop->lexNext(); SgStatement* loopEnd = loop->lastNodeOfStmt(); diff --git a/src/Utils/version.h b/src/Utils/version.h index f6ac53b..ae0ca0d 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2450" +#define VERSION_SPF "2451" diff --git a/src/VisualizerCalls/get_information.cpp b/src/VisualizerCalls/get_information.cpp index 7bdd7c3..229d49b 100644 --- a/src/VisualizerCalls/get_information.cpp +++ b/src/VisualizerCalls/get_information.cpp @@ -1802,6 +1802,13 @@ int SPF_InsertPrivateArrayDirectives(void*& context, int winHandler, short* opti return simpleTransformPass(FIND_PRIVATE_ARRAYS, options, projName, folderName, output, outputMessage); } +int SPF_MoveOperators(void*& context, int winHandler, short* options, short* projName, short* folderName, string& output, string& outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(MOVE_OPERATORS, options, projName, folderName, output, outputMessage); +} + static inline void convertBackSlash(char *str, int strL) { for (int z = 0; z < strL; ++z) @@ -2510,6 +2517,8 @@ const wstring Sapfor_RunTransformation(const char* transformName_c, const char* retCode = SPF_RenameIncludes(context, winHandler, optSh, projSh, fold, output, outputMessage); else if (whichRun == "SPF_InsertPrivateArrayDirectives") retCode = SPF_InsertPrivateArrayDirectives(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_MoveOperators") + retCode = SPF_MoveOperators(context, winHandler, optSh, projSh, fold, output, outputMessage); else if (whichRun == "SPF_CreateParallelVariant") { vector splited; From b1ef5d0b6761505b18d3245b22feedea4a822b6f Mon Sep 17 00:00:00 2001 From: ALEXks Date: Tue, 6 Jan 2026 18:35:34 +0300 Subject: [PATCH 18/20] dvm submodule updated --- projects/dvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/dvm b/projects/dvm index 4d4041a..3aad02a 160000 --- a/projects/dvm +++ b/projects/dvm @@ -1 +1 @@ -Subproject commit 4d4041a0811397add7e5e742681b5786e6c8a021 +Subproject commit 3aad02affb6675aee4fc8874e3ed6a942a07d963 From ec08e3af0eb84177d66114cc5782cdf985fb48c5 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Tue, 6 Jan 2026 18:36:07 +0300 Subject: [PATCH 19/20] version updated --- src/Utils/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/version.h b/src/Utils/version.h index ae0ca0d..2c5ca05 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2451" +#define VERSION_SPF "2452" From c36326660c8649483631d4b4418ab04eaf805470 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Tue, 6 Jan 2026 18:50:54 +0300 Subject: [PATCH 20/20] fixed submodule libpredictor --- projects/libpredictor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/libpredictor b/projects/libpredictor index d0772cd..5cf49ec 160000 --- a/projects/libpredictor +++ b/projects/libpredictor @@ -1 +1 @@ -Subproject commit d0772cdb57432b8c96ce634687641b1c8c76d21c +Subproject commit 5cf49ecbffaeb9280ea00bf375c0275e68203684