77 Commits

Author SHA1 Message Date
37ebeee97a Remove unused code and comments 2025-07-01 00:58:42 +03:00
2d47b8533b Merge branch 'master' into analyze_loops_with_IR 2025-06-29 22:10:03 +03:00
ALEXks
b8f429256f added removedUnreachableBlocks call for buildCFG 2025-06-29 16:02:37 +03:00
2fd08e79f1 Merge branch 'master' into analyze_loops_with_IR 2025-06-22 20:09:16 +03:00
ALEXks
2f53d6ae2e fixed 2025-06-22 09:22:10 +03:00
ALEXks
65237e4d63 added inductive variables and loop type to LoopGraph 2025-06-22 09:19:37 +03:00
2af6d9c140 WIP change logic of inductive variables 2025-06-19 23:01:10 +03:00
375070f959 Merge branch 'master' into analyze_loops_with_IR 2025-06-18 23:22:33 +03:00
31715a46d0 WIP: merge with master 2025-06-18 23:21:55 +03:00
ALEXks
7533739488 moved to removedUnreachableBlocks 2025-06-18 16:26:43 +03:00
c1d31b809b Merge pull request 'REMOVE_DIST_ARRAYS_FROM_IO: improve parsing of IO operators, fix substitution borders' (#63) from replace_io_arrays into master
Reviewed-on: #63
2025-06-15 17:07:00 +00:00
537f3eb6e9 version updated 2025-06-15 20:06:35 +03:00
f5f99f6e8a REMOVE_DIST_ARRAYS_FROM_IO: improve parsing of IO operators, fix substitution borders 2025-06-15 15:08:11 +03:00
ALEXks
fc47a1685c version updated 2025-06-14 21:07:24 +03:00
383d8df826 Merge pull request 'REMOVE_DIST_ARRAYS_FROM_IO: use isArrayRef' (#62) from replace_io_arrays into master
Reviewed-on: #62
2025-06-14 18:06:19 +00:00
ebc5a1cbc1 REMOVE_DIST_ARRAYS_FROM_IO: use isArrayRef 2025-06-14 20:25:23 +03:00
ALEXks
0eee799867 fixed dependencies pass order 2025-06-14 16:03:14 +03:00
ALEXks
50dd54cec1 improved 2025-06-14 15:15:51 +03:00
ALEXks
6a59bc0e09 added missing 2025-06-14 12:52:57 +03:00
ALEXks
9e777ceeab fixed shared memory parallelization, moved messages to single file 2025-06-14 12:50:04 +03:00
ALEXks
10636427ed fixed findArrayRef in loop_graph 2025-06-14 12:20:34 +03:00
ALEXks
a0704038db fixed compilation 2025-06-11 15:17:32 +03:00
623f6c0d73 Merge pull request 'dynamic parameters' (#61) from dyn_params into master
Reviewed-on: #61
2025-06-11 12:07:36 +00:00
ALEXks
622159cba6 improved 2025-06-11 15:07:06 +03:00
ALEXks
db26a2c332 merged master 2025-06-11 14:50:27 +03:00
ALEXks
8ad19cbfa5 fixed merging 2025-06-11 11:31:48 +03:00
ALEXks
1895a4b02a fixed 2025-06-06 08:15:10 +03:00
ALEXks
623898d913 added message dumping for -parse option if running from console 2025-06-05 19:04:56 +03:00
ALEXks
a96a4bcaa6 added dump messages function 2025-06-04 15:07:20 +03:00
ALEXks
a7764847c4 fixed 2025-06-04 13:55:37 +03:00
ALEXks
fca4f632e4 refactoring: removed unnecessary 2025-06-04 13:08:38 +03:00
ALEXks
f53d514a47 added VISUALIZER_DATA_PATH variable 2025-06-04 13:01:50 +03:00
ae9cc2bf3b Fix set iterators invalidation in find_parameters 2025-06-04 09:19:10 +03:00
c6a0c73287 fix UB in dom tree builder 2025-06-04 09:18:24 +03:00
ALEXks
db32a3e2b2 small fix 2025-06-04 08:32:25 +03:00
ALEXks
a0a401c42a refactored transformation: added folders for each transformation 2025-06-02 19:08:09 +03:00
8161609173 Merge pull request 'fix range stuctures' (#60) from private_arrays_fix into master 2025-06-02 05:26:21 +00:00
a2e6269508 fix range stuctures 2025-06-02 08:23:40 +03:00
ALEXks
ef6d7fb70f fixed code style 2025-05-30 18:11:18 +03:00
ALEXks
c7c46cd159 fixed code style 2025-05-30 18:09:14 +03:00
ALEXks
c842630ec2 fixed code style 2025-05-30 18:03:01 +03:00
ALEXks
2969f92013 moved code, fixed style 2025-05-30 17:33:57 +03:00
ALEXks
b13b0a0f57 Merge branch 'analyze_loops_with_IR' of http://192.168.0.176:30008/Alexander_KS/SAPFOR into analyze_loops_with_IR 2025-05-30 17:06:26 +03:00
ALEXks
06dd8848be improved CFG functions style 2025-05-30 17:06:21 +03:00
bed098b345 fixed cmake style 2025-05-30 13:02:27 +03:00
f322306344 Merge branch 'master' into analyze_loops_with_IR 2025-05-30 13:01:26 +03:00
ALEXks
72a1c1d853 fixed merge 2025-05-30 13:00:40 +03:00
f7c66f537d merged master 2025-05-30 12:54:18 +03:00
5c89299ad5 Merge pull request 'o.nikitin_private_arrays' (#58) from o.nikitin_private_arrays into master
Reviewed-on: #58
2025-05-30 09:45:49 +00:00
ALEXks
26e36bed46 fixed code style 2025-05-30 12:45:05 +03:00
ALEXks
8dcbd587ec fixed submodule 2025-05-30 12:31:19 +03:00
ALEXks
f7a78f9626 restored messages 2025-05-30 12:29:35 +03:00
fbe22fca43 Merge branch 'master' into o.nikitin_private_arrays 2025-05-30 12:21:13 +03:00
bbb9823f1d updated submodule 2025-05-30 12:20:08 +03:00
b454858647 delete zero from directive 2025-05-30 12:00:56 +03:00
ALEXks
ad99446b12 added missing 2025-05-30 11:57:39 +03:00
ALEXks
d3e8c481d2 fixed code style, moved dom tree building to IR 2025-05-30 11:34:32 +03:00
4e16638c36 Clean up 2025-05-29 09:14:12 +03:00
6742932862 Add SPF directive insertion 2025-05-29 09:14:12 +03:00
8b2e59356a Extend interprocedural analysis 2025-05-29 09:14:12 +03:00
f9d52c0c3e unparse after 2025-05-29 09:14:12 +03:00
537d60222f Add Dominator tree builder and interprocedural analysis 2025-05-29 09:14:12 +03:00
4eb057731f trivial case for local variables only 2025-05-29 09:14:12 +03:00
402ae91c33 Merge pull request 'weighted_par_regions' (#57) from weighted_par_regions into master
added weighted parallel regions (by Mikhail K)
2025-05-29 06:08:47 +00:00
ba632b29ce cleanup and replaced parseFortranDouble to strtod 2025-05-29 09:07:20 +03:00
18edf55d15 merged mastser 2025-05-28 16:31:27 +03:00
c347f56e47 Merge branch 'master' into o.nikitin_private_arrays 2025-05-28 16:24:17 +03:00
11e9fab482 change file structure 2025-05-27 02:25:39 +03:00
73d0b201f2 change passes 2025-05-19 20:59:59 +03:00
1973d095f5 made functions static 2025-05-19 20:59:59 +03:00
O. Nikitin
f679666d01 fix operator!= 2025-05-19 20:52:06 +03:00
0df1d3d5fe add dataflow solvation 2025-05-19 20:52:06 +03:00
54eb1ecc95 add Region constructor and SolveDataflow function 2025-05-19 20:52:06 +03:00
b7ebccf045 add Collapse 2025-05-19 20:52:06 +03:00
738f2c5d12 Support APPLY_FRAGMENT(WEIGHT(double)) clause: add weights to fragments of parallel regions (and use it in at loopAnalyzer) 2025-05-10 15:27:03 +03:00
ALEXks
29a8c30370 fixed Array::toJson 2025-05-07 20:16:43 +03:00
ALEXks
99f5febd58 added json for SPF_GetAllDeclaratedArrays pass 2025-05-07 19:59:54 +03:00
165 changed files with 3196 additions and 1852 deletions

1
.gitignore vendored
View File

@@ -74,6 +74,7 @@ Sapfor/Sapc++/Sapc++/x64/
Sapfor/Sapc++/x64/
/build
/cmake-build-debug
Sapfor/out/
Sapfor/_bin/*

View File

@@ -27,6 +27,13 @@ set(libpred_sources projects/libpredictor/src/)
set(libpred_include projects/libpredictor/include/)
include_directories(src)
include_directories(src/Utils)
include_directories(src/SgUtils)
include_directories(src/Distribution)
include_directories(src/GraphCall)
include_directories(src/GraphLoop)
include_directories(src/Transformations/ExpressionSubstitution)
#Sage lib includes
include_directories(${fdvm_include})
include_directories(${sage_include_1})
@@ -113,7 +120,13 @@ set(OMEGA src/SageAnalysisTool/OmegaForSage/add-assert.cpp
src/SageAnalysisTool/set.cpp)
set(PRIV src/PrivateAnalyzer/private_analyzer.cpp
src/PrivateAnalyzer/private_analyzer.h)
src/PrivateAnalyzer/private_analyzer.h
src/PrivateAnalyzer/private_arrays_search.cpp
src/PrivateAnalyzer/private_arrays_search.h
src/PrivateAnalyzer/range_structures.cpp
src/PrivateAnalyzer/range_structures.h
src/PrivateAnalyzer/region.cpp
src/PrivateAnalyzer/region.h)
set(FDVM ${fdvm_sources}/acc.cpp
${fdvm_sources}/acc_across.cpp
@@ -148,40 +161,47 @@ set(PARALLEL_REG src/ParallelizationRegions/ParRegions.cpp
src/ParallelizationRegions/resolve_par_reg_conflicts.cpp
src/ParallelizationRegions/resolve_par_reg_conflicts.h)
set(TR_DEAD_CODE src/Transformations/dead_code.cpp
src/Transformations/dead_code.h)
set(TR_CP src/Transformations/checkpoints.cpp
src/Transformations/checkpoints.h)
set(TR_VECTOR src/Transformations/array_assign_to_loop.cpp
src/Transformations/array_assign_to_loop.h)
set(TR_ENDDO_LOOP src/Transformations/enddo_loop_converter.cpp
src/Transformations/enddo_loop_converter.h)
set(TR_LOOP_NEST src/Transformations/loop_transform.cpp
src/Transformations/loop_transform.h)
set(TR_LOOP_COMB src/Transformations/loops_combiner.cpp
src/Transformations/loops_combiner.h)
set(TR_LOOP_SPLIT src/Transformations/loops_splitter.cpp
src/Transformations/loops_splitter.h)
set(TR_LOOP_UNROLL src/Transformations/loops_unrolling.cpp
src/Transformations/loops_unrolling.h)
set(TR_PRIV_BR src/Transformations/private_arrays_resizing.cpp
src/Transformations/private_arrays_resizing.h)
set(TR_PRIV_DEL src/Transformations/private_removing.cpp
src/Transformations/private_removing.h)
set(TR_SWAP_ARR_DIMS src/Transformations/swap_array_dims.cpp
src/Transformations/swap_array_dims.h)
set(TR_FUNC_DUP src/Transformations/uniq_call_chain_dup.cpp
src/Transformations/uniq_call_chain_dup.h)
set(TR_FUNC_PURE src/Transformations/function_purifying.cpp
src/Transformations/function_purifying.h)
set(TR_GV src/Transformations/fix_common_blocks.cpp
src/Transformations/fix_common_blocks.h)
set(TR_CONV src/Transformations/convert_to_c.cpp
src/Transformations/convert_to_c.h)
set(TR_IMPLICIT_NONE src/Transformations/set_implicit_none.cpp
src/Transformations/set_implicit_none.h)
set(TR_REPLACE_ARRAYS_IN_IO src/Transformations/replace_dist_arrays_in_io.cpp
src/Transformations/replace_dist_arrays_in_io.h)
set(TR_DEAD_CODE src/Transformations/DeadCodeRemoving/dead_code.cpp
src/Transformations/DeadCodeRemoving/dead_code.h)
set(TR_CP src/Transformations/CheckPoints/checkpoints.cpp
src/Transformations/CheckPoints/checkpoints.h)
set(TR_VECTOR src/Transformations/VectorAssignToLoop/array_assign_to_loop.cpp
src/Transformations/VectorAssignToLoop/array_assign_to_loop.h)
set(TR_ENDDO_LOOP src/Transformations/LoopEndDoConverter/enddo_loop_converter.cpp
src/Transformations/LoopEndDoConverter/enddo_loop_converter.h)
set(TR_LOOP_NEST src/Transformations/LoopNesting/loop_transform.cpp
src/Transformations/LoopNesting/loop_transform.h)
set(TR_LOOP_COMB src/Transformations/LoopCombining/loops_combiner.cpp
src/Transformations/LoopCombining/loops_combiner.h)
set(TR_LOOP_SPLIT src/Transformations/LoopSplitting/loops_splitter.cpp
src/Transformations/LoopSplitting/loops_splitter.h)
set(TR_LOOP_UNROLL src/Transformations/LoopUnrolling/loops_unrolling.cpp
src/Transformations/LoopUnrolling/loops_unrolling.h)
set(TR_PRIV_BR src/Transformations/PrivateArrayResizing/private_arrays_resizing.cpp
src/Transformations/PrivateArrayResizing/private_arrays_resizing.h)
set(TR_PRIV_DEL src/Transformations/PrivateArrayRemoving/private_removing.cpp
src/Transformations/PrivateArrayRemoving/private_removing.h)
set(TR_SWAP_ARR_DIMS src/Transformations/ArrayDimsSwapping/swap_array_dims.cpp
src/Transformations/ArrayDimsSwapping/swap_array_dims.h)
set(TR_FUNC_DUP src/Transformations/FunctionDuplication/uniq_call_chain_dup.cpp
src/Transformations/FunctionDuplication/uniq_call_chain_dup.h)
set(TR_FUNC_PURE src/Transformations/FunctionPurifying/function_purifying.cpp
src/Transformations/FunctionPurifying/function_purifying.h)
set(TR_GV src/Transformations/GlobalVariables/fix_common_blocks.cpp
src/Transformations/GlobalVariables/fix_common_blocks.h)
set(TR_CONV src/Transformations/ConvertToC/convert_to_c.cpp
src/Transformations/ConvertToC/convert_to_c.h)
set(TR_IMPLICIT_NONE src/Transformations/SetImplicitNone/set_implicit_none.cpp
src/Transformations/SetImplicitNone/set_implicit_none.h)
set(TR_REPLACE_ARRAYS_IN_IO src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp
src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.h)
set(TR_EXPR_TRANSFORM src/Transformations/ExpressionSubstitution/control_flow_graph_part.cpp
src/Transformations/ExpressionSubstitution/expr_transform.cpp
src/Transformations/ExpressionSubstitution/expr_transform.h)
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(TRANSFORMS
${TR_DEAD_CODE}
@@ -201,11 +221,15 @@ set(TRANSFORMS
${TR_CONV}
${TR_PRIV_DEL}
${TR_IMPLICIT_NONE}
${TR_REPLACE_ARRAYS_IN_IO})
${TR_REPLACE_ARRAYS_IN_IO}
${TR_EXPR_TRANSFORM}
${TR_INLINER}
${TR_RENAME_SYMBOLS})
set(CFG
src/CFGraph/IR.cpp
set(CFG src/CFGraph/IR.cpp
src/CFGraph/IR.h
src/CFGraph/IR_domTree.cpp
src/CFGraph/IR_domTree.h
src/CFGraph/CFGraph.cpp
src/CFGraph/CFGraph.h
src/CFGraph/RD_subst.cpp
@@ -214,16 +238,14 @@ set(CFG
src/CFGraph/live_variable_analysis.h
src/CFGraph/private_variables_analysis.cpp
src/CFGraph/private_variables_analysis.h
src/CFGraph/IRSSAForm.cpp
src/CFGraph/IRSSAForm.h
)
src/CFGraph/IR_SSAForm.cpp
src/CFGraph/IR_SSAForm.h)
set(DATA_FLOW
src/CFGraph/DataFlow/data_flow.h
src/CFGraph/DataFlow/data_flow_impl.h
src/CFGraph/DataFlow/backward_data_flow.h
src/CFGraph/DataFlow/backward_data_flow_impl.h
)
src/CFGraph/DataFlow/backward_data_flow_impl.h)
set(CREATE_INTER_T src/CreateInterTree/CreateInterTree.cpp
src/CreateInterTree/CreateInterTree.h)
@@ -285,10 +307,6 @@ set(DYNA src/DynamicAnalysis/createParallelRegions.cpp
src/DynamicAnalysis/gcov_info.h
src/DynamicAnalysis/gCov_parser.cpp
src/DynamicAnalysis/gCov_parser_func.h)
set(EXPR_TRANSFORM src/ExpressionTransform/control_flow_graph_part.cpp
src/ExpressionTransform/expr_transform.cpp
src/ExpressionTransform/expr_transform.h)
set(GR_CALL src/GraphCall/graph_calls.cpp
src/GraphCall/graph_calls.h
@@ -300,17 +318,12 @@ set(GR_LOOP src/GraphLoop/graph_loops_base.cpp
src/GraphLoop/graph_loops.h
src/GraphLoop/graph_loops_func.h)
set(INLINER src/Inliner/inliner.cpp
src/Inliner/inliner.h)
set(LOOP_ANALYZER src/LoopAnalyzer/allocations_prepoc.cpp
src/LoopAnalyzer/dep_analyzer.cpp
src/LoopAnalyzer/loop_analyzer.cpp
src/LoopAnalyzer/loop_analyzer.h)
set(RENAME_SYMBOLS src/RenameSymbols/rename_symbols.cpp
src/RenameSymbols/rename_symbols.h)
src/LoopAnalyzer/loop_analyzer.h
src/LoopAnalyzer/implicit_loops_analyzer.cpp
src/LoopAnalyzer/implicit_loops_analyzer.h)
set(MAIN src/Sapfor.cpp
src/Sapfor.h
@@ -401,12 +414,9 @@ set(SOURCE_EXE
${DISTR}
${DVMH_REG}
${DYNA}
${EXPR_TRANSFORM}
${GR_CALL}
${GR_LOOP}
${INLINER}
${LOOP_ANALYZER}
${RENAME_SYMBOLS}
${TRANSFORMS}
${PARALLEL_REG}
${PRIV}
@@ -430,7 +440,7 @@ source_group (CFGraph FILES ${CFG})
source_group (CFGraph\\DataFlow FILES ${DATA_FLOW})
source_group (Transformations\\DeadCodeRemoving FILES ${TR_DEAD_CODE})
source_group (Transformations\\ExpressionSubstitution FILES ${EXPR_TRANSFORM})
source_group (Transformations\\ExpressionSubstitution FILES ${TR_EXPR_TRANSFORM})
source_group (Transformations\\CheckPoints FILES ${TR_CP})
source_group (Transformations\\LoopEndDoConverter FILES ${TR_ENDDO_LOOP})
source_group (Transformations\\LoopNesting FILES ${TR_LOOP_NEST})
@@ -438,13 +448,13 @@ source_group (Transformations\\LoopCombining FILES ${TR_LOOP_COMB})
source_group (Transformations\\LoopSplitting FILES ${TR_LOOP_SPLIT})
source_group (Transformations\\LoopUnrolling FILES ${TR_LOOP_UNROLL})
source_group (Transformations\\FunctionDuplication FILES ${TR_FUNC_DUP})
source_group (Transformations\\FunctionInlining FILES ${INLINER})
source_group (Transformations\\FunctionInlining FILES ${TR_INLINER})
source_group (Transformations\\FunctionPurifying FILES ${TR_FUNC_PURE})
source_group (Transformations\\ArrayDimsSwapping FILES ${TR_SWAP_ARR_DIMS})
source_group (Transformations\\PrivateArrayResizing FILES ${TR_PRIV_BR})
source_group (Transformations\\PrivateArrayRemoving FILES ${TR_PRIV_DEL})
source_group (Transformations\\VectorAssignToLoop FILES ${TR_VECTOR})
source_group (Transformations\\RenameSymbols FILES ${RENAME_SYMBOLS})
source_group (Transformations\\RenameSymbols FILES ${TR_RENAME_SYMBOLS})
source_group (Transformations\\GlobalVariables FILES ${TR_GV})
source_group (Transformations\\ConvertToC FILES ${TR_CONV})
source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE})

View File

@@ -1,5 +1,5 @@
#define _LEAK_
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <stdlib.h>
#include <stdio.h>
@@ -8,9 +8,9 @@
#include <chrono>
#include <functional>
#include "../Utils/SgUtils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "SgUtils.h"
#include "CommonBlock.h"
#include "graph_calls.h"
#include "dvm.h"
#include "IR.h"
@@ -50,27 +50,28 @@ BBlock::BasicBlock(const BBlock& copyFrom)
prev = copyFrom.prev;
}
void BBlock::addInstruction(IR_Block* item)
void BBlock::addInstruction(IR_Block* item, bool pushFront)
{
instructions.push_back(item);
if (pushFront)
instructions.insert(instructions.begin(), item);
else
instructions.push_back(item);
item->setBasicBlock(this);
}
void BBlock::addInstructionInFront(IR_Block* item)
void BBlock::addInstructionBefore(IR_Block* item, Instruction* before)
{
instructions.insert(instructions.begin(), item);
item->setBasicBlock(this);
}
checkNull(before, convertFileName(__FILE__).c_str(), __LINE__);
checkNull(item, convertFileName(__FILE__).c_str(), __LINE__);
void BBlock::addInstructionBeforeInstruction(IR_Block* item, Instruction* instruction)
{
for (auto it = instructions.begin(); it != instructions.end(); ++it) {
if ((*it)->getInstruction() == instruction) {
if ((*it)->getInstruction() == before) {
instructions.insert(it, item);
item->setBasicBlock(this);
return;
}
}
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
int BBlock::removePrev(BBlock* removed)
@@ -529,7 +530,7 @@ static int buildReachingDefs(const vector<BBlock*>& CFG, const FuncInfo* currF,
return iter;
}
//Kosaraju<EFBFBD>Sharir algorithm
//Kosaraju-Sharir algorithm
static vector<int> getStronglyConnectedComps(vector<vector<int>>& g) {
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
auto size = g.size();
@@ -1166,9 +1167,22 @@ map<FuncInfo*, vector<BBlock*>> buildCFG(const map<string, CommonBlock*>& common
if (settings.withRD)
buildReachingDefs(result, settings);
if (settings.withDominators)
{
auto t = high_resolution_clock::now();
for (auto& [func, bblocks] : result)
SAPFOR::buildDominatorTree(bblocks);
auto msec = duration_cast<milliseconds>(high_resolution_clock::now() - t).count();
__spf_print(1, " dominator build time is %.3f sec\n", msec / 1000.);
}
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& [func, blocks] : result)
removedUnreachableBlocks(blocks);
return result;
}
@@ -1243,4 +1257,49 @@ map<FuncInfo*, vector<SAPFOR::BasicBlock*>>
fileFuncInfoMap[callFrom->fileName].push_back(callFrom);
return buildCFG(commonBlocks, fileFuncInfoMap, settings);
}
void removedUnreachableBlocks(vector<SAPFOR::BasicBlock*>& blocks)
{
set<SAPFOR::BasicBlock*> reachable;
for (auto& b : blocks)
if (b->getInstructions().front()->isHeader() ||
b->getInstructions().front()->getInstruction()->getOperation() == SAPFOR::CFG_OP::ENTRY)
reachable.insert(b);
set<SAPFOR::BasicBlock*> worklist = reachable;
while (worklist.size() != 0)
{
set<SAPFOR::BasicBlock*> to_insert;
for (auto& b : worklist)
for (auto& next : b->getNext())
if (reachable.insert(next).second)
to_insert.insert(next);
worklist = to_insert;
}
auto remove_unreachable_it = remove_if(blocks.begin(), blocks.end(),
[&reachable](SAPFOR::BasicBlock* b)
{
if (reachable.find(b) == reachable.end())
{
for (auto& next : b->getNext())
if (reachable.find(next) != reachable.end())
next->removePrev(b);
delete b;
return true;
}
return false;
}
);
reachable.clear();
blocks.erase(remove_unreachable_it, blocks.end());
}

View File

@@ -6,6 +6,11 @@
#include <vector>
#include "IR.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "IR_domTree.h"
namespace SAPFOR
{
@@ -24,7 +29,7 @@ namespace SAPFOR
std::vector<BasicBlock*> next;
std::vector<BasicBlock*> prev;
BasicBlock* directDominator = NULL;
//reaching definition
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
@@ -34,16 +39,17 @@ namespace SAPFOR
bool addLive(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add, bool in);
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLive(bool in) const;
bool removeLive(SAPFOR::Argument* to_remove, bool in);
public:
BasicBlock() { num = lastNumBlock++; }
BasicBlock(IR_Block* item);
BasicBlock(const BasicBlock& copyFrom);
void addInstructionBeforeInstruction(IR_Block* item, Instruction* istruction);
void addInstructionInFront(IR_Block* item);
void addInstruction(IR_Block* item);
void addInstructionBefore(IR_Block* item, Instruction* istruction);
void addInstruction(IR_Block* item, bool pushFront = false);
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
void addNext(BasicBlock* next_) { next.push_back(next_); }
void setDom(BasicBlock* dom) { directDominator = dom; }
int removePrev(BasicBlock* removed);
int removeNext(BasicBlock* removed);
@@ -71,7 +77,11 @@ namespace SAPFOR
const std::vector<IR_Block*>& getInstructions() const { return instructions; }
const std::vector<BasicBlock*>& getNext() const { return next; }
const std::vector<BasicBlock*>& getPrev() const { return prev; }
BasicBlock* getDom() const
{
return directDominator;
}
/*
* FOR LIVE ANALYSIS
*/
@@ -107,13 +117,15 @@ namespace SAPFOR
bool withDVM = false;
bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock
bool withCallFrom = true;
bool withDominators = true;
explicit CFG_Settings(int) { }
explicit CFG_Settings(bool atLeastOneIterInLoop = false, bool withRD = true, bool withRegisters = false,
bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false, bool withCallFrom = true) :
bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false,
bool withCallFrom = true, bool withDominators = true) :
atLeastOneIterInLoop(atLeastOneIterInLoop), withRD(withRD), withRegisters(withRegisters), withDVM(withDVM), withSPF(withSPF),
withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom)
withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom), withDominators(withDominators)
{ }
};
}
@@ -148,4 +160,6 @@ static inline void deleteCFG(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*
byFunc.second.clear();
}
cfg.clear();
}
}
void removedUnreachableBlocks(std::vector<SAPFOR::BasicBlock*>& blocks);

View File

@@ -5,7 +5,7 @@
#include <set>
#include <algorithm>
#include "../../Utils/SgUtils.h"
#include "SgUtils.h"
#include "../CFGraph.h"
#include "../IR.h"

View File

@@ -5,7 +5,7 @@
#include <set>
#include <algorithm>
#include "../../Utils/SgUtils.h"
#include "SgUtils.h"
#include "../CFGraph.h"
#include "../IR.h"
#include "../RD_subst.h"

View File

@@ -2,7 +2,7 @@
#include<vector>
#include<set>
#include "../../Utils/SgUtils.h"
#include "SgUtils.h"
#include "../CFGraph.h"
#include "../IR.h"

View File

@@ -4,7 +4,7 @@
#include<vector>
#include<set>
#include "../../Utils/SgUtils.h"
#include "SgUtils.h"
#include "../CFGraph.h"
#include "../IR.h"

View File

@@ -1,14 +1,14 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <set>
#include "../Utils/SgUtils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "../ExpressionTransform/expr_transform.h"
#include "SgUtils.h"
#include "CommonBlock.h"
#include "graph_calls.h"
#include "expr_transform.h"
#include "dvm.h"
#include "IR.h"
@@ -395,7 +395,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector<IR_Block*>&
if (ex)
{
const int var = ex->variant();
if ((var == VAR_REF || var == CONST_REF || var == LABEL_REF) && !ex->lhs() && !ex->rhs()) // обращение к переменной
if ((var == VAR_REF || var == CONST_REF || var == LABEL_REF) && !ex->lhs() && !ex->rhs()) // variable reference
{
if (var == CONST_REF)
{
@@ -450,7 +450,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector<IR_Block*>&
return arg1;
auto reg = isLeft ? NULL : createRegister();
Instruction* instr = new Instruction(isLeft ? CFG_OP::STORE : CFG_OP::LOAD, arg1, createConstArg(numArgs), isLeft ? isLeft : reg);
Instruction* instr = new Instruction(isLeft ? CFG_OP::STORE : CFG_OP::LOAD, arg1, createConstArg(numArgs), isLeft ? isLeft : reg, NULL, ex);
blocks.push_back(new IR_Block(instr));
return reg;
}
@@ -485,7 +485,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector<IR_Block*>&
auto arg1 = arrayRef ? arrayRef : createArrayArg(ref, blocks, func, numArgs, commonVars);
auto reg = isLeft ? NULL : createRegister();
instr = new Instruction(isLeft ? CFG_OP::STORE : CFG_OP::LOAD, arg1, createConstArg(1), isLeft ? isLeft : reg);
instr = new Instruction(isLeft ? CFG_OP::STORE : CFG_OP::LOAD, arg1, createConstArg(1), isLeft ? isLeft : reg, NULL, ex);
blocks.push_back(new IR_Block(instr));
return reg;
}
@@ -602,7 +602,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector<IR_Block*>&
{
if (returnReg == NULL)
{
Instruction* instr = new Instruction(CFG_OP::LOAD, arg, NULL, reg);
Instruction* instr = new Instruction(CFG_OP::LOAD, arg, NULL, reg, NULL, ex);
blocks.push_back(new IR_Block(instr));
}
else
@@ -1572,7 +1572,7 @@ vector<IR_Block*> buildIR(SgStatement* function, const FuncInfo* func, const vec
else
findReturn(0, blocks.size(), blocks, blocks.back()->getNumber());
// добавление связей по GOTO и переходам
// adding links by GOTO and jumps
for (int z = 0; z < blocks.size(); ++z)
{
auto op = blocks[z]->getInstruction()->getOperation();
@@ -1592,7 +1592,7 @@ vector<IR_Block*> buildIR(SgStatement* function, const FuncInfo* func, const vec
blocks[z]->setJump(it->second);
// заменим метку на номер инструкции
// replacing the label with the instruction number
arg->setValue(to_string(it->second->getNumber()));
arg->setType(CFG_ARG_TYPE::INSTR);
}
@@ -1613,429 +1613,3 @@ vector<IR_Block*> buildIR(SgStatement* function, const FuncInfo* func, const vec
return blocks;
}
enum VisitState { UNVISITED = 0, VISITING = 1, VISITED = 2 };
void dfs(SAPFOR::BasicBlock* block, map<int, int>& visit, vector<pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>>& startAndEnd, SAPFOR::BasicBlock* prev) {
if (!block) return;
if (visit[block->getNumber()] == VISITED) {
cout << "error";
return;
}
if (visit[block->getNumber()] == VISITING) {
visit[block->getNumber()] = VISITED;
startAndEnd.push_back(make_pair(prev, block));
return;
}
visit[block->getNumber()] = VISITING;
for (auto i : block->getNext()) {
dfs(i, visit, startAndEnd, block);
}
}
static void printBlock(SAPFOR::BasicBlock* block) {
cout << "block - " << block->getNumber() << endl;
cout << "next -";
for (auto i : block->getNext())
{
cout << " " << i->getNumber();
}
cout << endl << "prev -";
for (auto i : block->getPrev())
{
cout << " " << i->getNumber();
}
cout << endl;
for (auto i : block->getInstructions())
{
string resValue = "";
string arg1Value = "";
string arg2Value = "";
if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == CFG_ARG_TYPE::VAR) {
resValue = i->getInstruction()->getResult()->getValue();
i->getInstruction()->getResult()->setValue(i->getInstruction()->getResult()->getValue() + to_string(i->getInstruction()->getResult()->getNumber()));
}
if (i->getInstruction()->getArg1() != nullptr && i->getInstruction()->getArg1()->getType() == CFG_ARG_TYPE::VAR) {
arg1Value = i->getInstruction()->getArg1()->getValue();
i->getInstruction()->getArg1()->setValue(i->getInstruction()->getArg1()->getValue() + to_string(i->getInstruction()->getArg1()->getNumber()));
}
if (i->getInstruction()->getArg2() != nullptr && i->getInstruction()->getArg2()->getType() == CFG_ARG_TYPE::VAR) {
arg2Value = i->getInstruction()->getArg2()->getValue();
i->getInstruction()->getArg2()->setValue(i->getInstruction()->getArg2()->getValue() + to_string(i->getInstruction()->getArg2()->getNumber()));
}
cout << i->getNumber() << " " << i->getInstruction()->dump() << endl;
if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == CFG_ARG_TYPE::VAR) {
i->getInstruction()->getResult()->setValue(resValue);
}
if (i->getInstruction()->getArg1() != nullptr && i->getInstruction()->getArg1()->getType() == CFG_ARG_TYPE::VAR) {
i->getInstruction()->getArg1()->setValue(arg1Value);
}
if (i->getInstruction()->getArg2() != nullptr && i->getInstruction()->getArg2()->getType() == CFG_ARG_TYPE::VAR) {
i->getInstruction()->getArg2()->setValue(arg2Value);
}
}
cout << endl;
}
void getLoopBody(SAPFOR::BasicBlock* loopHeader, const std::set<SAPFOR::BasicBlock*>& loopExits, std::vector<SAPFOR::BasicBlock*>& loopBody) {
std::set<SAPFOR::BasicBlock*> visited;
std::stack<SAPFOR::BasicBlock*> stack;
stack.push(loopHeader);
while (!stack.empty()) {
auto block = stack.top();
stack.pop();
if (visited.count(block)) continue;
visited.insert(block);
for (auto succ : block->getNext()) {
if (loopExits.count(succ)) continue;
if (!visited.count(succ)) {
stack.push(succ);
}
}
}
std::set<SAPFOR::BasicBlock*> backReachable;
std::stack<SAPFOR::BasicBlock*> reverseStack;
reverseStack.push(loopHeader);
while (!reverseStack.empty()) {
auto block = reverseStack.top();
reverseStack.pop();
if (backReachable.count(block)) continue;
backReachable.insert(block);
for (auto pred : block->getPrev()) {
if (visited.count(pred) && !backReachable.count(pred)) {
reverseStack.push(pred);
}
}
}
for (auto block : visited) {
if (backReachable.count(block)) {
loopBody.push_back(block);
}
}
}
set<SAPFOR::Argument*> findRegisterSourceVariables(const std::vector<SAPFOR::BasicBlock*>& blocks, SAPFOR::Argument* var) {
std::set<SAPFOR::Argument*> result;
std::set<SAPFOR::Argument*> visited;
std::stack<SAPFOR::Argument*> workStack;
workStack.push(var);
auto isBinaryOp = [](SAPFOR::CFG_OP op) {
return op == SAPFOR::CFG_OP::ADD || op == SAPFOR::CFG_OP::SUBT ||
op == SAPFOR::CFG_OP::MULT || op == SAPFOR::CFG_OP::DIV ||
op == SAPFOR::CFG_OP::POW ||
op == SAPFOR::CFG_OP::GE || op == SAPFOR::CFG_OP::LE ||
op == SAPFOR::CFG_OP::GT || op == SAPFOR::CFG_OP::LT ||
op == SAPFOR::CFG_OP::EQ || op == SAPFOR::CFG_OP::NEQV ||
op == SAPFOR::CFG_OP::EQV || op == SAPFOR::CFG_OP::EMPTY ||
op == SAPFOR::CFG_OP::OR || op == SAPFOR::CFG_OP::AND;
};
auto isUnaryOp = [](SAPFOR::CFG_OP op) {
return op == SAPFOR::CFG_OP::UN_ADD || op == SAPFOR::CFG_OP::UN_MINUS ||
op == SAPFOR::CFG_OP::NOT || op == SAPFOR::CFG_OP::ASSIGN;
};
while (!workStack.empty()) {
auto variable = workStack.top();
workStack.pop();
if (!variable || visited.count(variable))
continue;
visited.insert(variable);
for (auto block : blocks) {
for (auto instrWrapper : block->getInstructions()) {
auto instr = instrWrapper->getInstruction();
if (!instr || instr->getResult() != variable)
continue;
auto op = instr->getOperation();
auto arg1 = instr->getArg1();
auto arg2 = instr->getArg2();
if (isBinaryOp(op) && arg1 && arg2) {
if (arg1->getType() == CFG_ARG_TYPE::VAR)
result.insert(arg1);
else if (arg1->getType() == CFG_ARG_TYPE::REG)
workStack.push(arg1);
if (arg2->getType() == CFG_ARG_TYPE::VAR)
result.insert(arg2);
else if (arg2->getType() == CFG_ARG_TYPE::REG)
workStack.push(arg2);
}
else if (isUnaryOp(op) && arg1) {
if (arg1->getType() == CFG_ARG_TYPE::VAR)
result.insert(arg1);
else if (arg1->getType() == CFG_ARG_TYPE::REG)
workStack.push(arg1);
}
}
}
}
return result;
}
std::vector<SAPFOR::Instruction*> getPhiArguments(SAPFOR::BasicBlock* block, SAPFOR::Instruction* phiInstr) {
std::vector<SAPFOR::Instruction*> result;
auto& instructions = block->getInstructions();
bool collecting = false;
for (int i = instructions.size() - 1; i >= 0; --i) {
auto instr = instructions[i]->getInstruction();
if (collecting) {
if (instr->getOperation() == SAPFOR::CFG_OP::PARAM) {
auto arg = instr->getArg1();
if (arg) {
result.push_back(instr);
}
}
else {
break;
}
}
if (!instr) continue;
if (instr == phiInstr) {
collecting = true;
continue;
}
}
std::reverse(result.begin(), result.end());
return result;
}
SAPFOR::BasicBlock* findInstructionBlock(SAPFOR::Instruction* targetInstr, const std::vector<SAPFOR::BasicBlock*>& blocks) {
for (auto block : blocks) {
for (auto instrWrapper : block->getInstructions()) {
auto instr = instrWrapper->getInstruction();
if (instr == targetInstr) {
return block;
}
}
}
return nullptr;
}
SAPFOR::BasicBlock* findInstructionBlockByNumber(int number, const std::vector<SAPFOR::BasicBlock*>& blocks) {
for (auto block : blocks) {
for (auto instrWrapper : block->getInstructions()) {
auto instr = instrWrapper->getInstruction();
if (instr->getNumber() == number) {
return block;
}
}
}
return nullptr;
}
void findInductiveVars(const std::vector<SAPFOR::BasicBlock*>& blocks, const std::vector<SAPFOR::BasicBlock*>& Loopblocks, SAPFOR::BasicBlock* loopHeader, const std::set<SAPFOR::BasicBlock*>& loopExits) {
std::set<string> inductiveVars;
std::set<SAPFOR::BasicBlock*> relevantBlocks = { loopHeader };
for (auto block : relevantBlocks) {
for (auto instrWrapper : block->getInstructions()) {
auto instr = instrWrapper->getInstruction();
if (!instr) continue;
auto op = instr->getOperation();
auto res = instr->getResult();
auto arg1 = instr->getArg1();
auto arg2 = instr->getArg2();
if (op == CFG_OP::JUMP_IF) {
if (arg1 && arg1->getType() == CFG_ARG_TYPE::VAR) {
inductiveVars.insert(arg1->getValue());
}
if (arg1 && arg1->getType() == CFG_ARG_TYPE::REG) {
auto foundVariables = findRegisterSourceVariables(blocks, arg1);
for (auto var : foundVariables) {
inductiveVars.insert(var->getValue());
}
}
}
}
}
std::set<string> finalInductiveVars;
for (auto instrWrapper : loopHeader->getInstructions()) {
auto instr = instrWrapper->getInstruction();
if (!instr || instr->getOperation() != SAPFOR::CFG_OP::F_CALL || !instr->getArg1() || instr->getArg1()->getValue() != "FI_FUNCTION") continue;
auto phiRes = instr->getResult();
if (!phiRes || !inductiveVars.count(phiRes->getValue())) continue;
auto currentBlock = findInstructionBlock(instr, blocks);
if (!currentBlock) continue;
auto phiArgs = getPhiArguments(currentBlock, instr);
bool hasInLoopDefinition = false;
for (const auto& argInstr : phiArgs) {
if (!argInstr) continue;
int definitionInstrNumber = stoi(argInstr->getArg1()->getValue());
if (definitionInstrNumber == -1) continue;
auto phiBlock = findInstructionBlockByNumber(definitionInstrNumber, blocks);
if (!phiBlock) continue;
if (std::find(Loopblocks.begin(), Loopblocks.end(), phiBlock) != Loopblocks.end()) {
hasInLoopDefinition = true;
}
}
if (hasInLoopDefinition) {
finalInductiveVars.insert(phiRes->getValue());
}
}
for (auto i : finalInductiveVars) {
std::cout << "Confirmed inductive variable: " << i << std::endl;
}
if (finalInductiveVars.empty()) {
std::cout << "No confirmed inductive variables found." << std::endl;
}
}
Instruction* findInstructionAfterLoop(const std::vector<SAPFOR::BasicBlock*>& loopBody) {
std::set<SAPFOR::BasicBlock*> loopSet(loopBody.begin(), loopBody.end());
for (auto block : loopBody) {
for (auto succ : block->getNext()) {
if (!loopSet.count(succ)) {
// Нашли выход из цикла — возьмём первую инструкцию
auto instructions = succ->getInstructions();
for (auto wrapper : instructions) {
if (auto instr = wrapper->getInstruction()) {
return instr;
}
}
}
}
}
return nullptr; // не нашли
}
bool isEqual(const char* cstr, const std::string& str) {
return str == cstr;
}
void exploreLoops(map<FuncInfo*, vector<SAPFOR::BasicBlock*>>* fullIR, const char* fileName) {
for (auto& i : *fullIR)
{
//for (auto j : i.second)
// printblock(j);
if (!isEqual(fileName, i.first->fileName))
continue;
map<int, int> visited;
for (auto i : i.second)
visited[i->getNumber()] = UNVISITED;
//vector<int> visited(i.second.size(), UNVISITED);
vector<pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>> startAndEnd;
dfs(i.second[0], visited, startAndEnd, NULL);
vector<LoopGraph*> loops;
for (auto& [tail, header] : startAndEnd) {
set<SAPFOR::BasicBlock*> loopExits;
for (auto succ : tail->getNext()) {
if (succ != header) {
loopExits.insert(succ);
}
}
vector<SAPFOR::BasicBlock*> loopBody;
getLoopBody(header, loopExits, loopBody);
cout << "LOOP DETECTED:" << endl;
cout << " Header: " << header->getNumber() << endl;
cout << " Tail: " << tail->getNumber() << endl;
cout << " Body blocks: ";
for (auto block : loopBody) {
cout << block->getNumber() << " ";
}
cout << endl;
findInductiveVars(i.second, loopBody, header, loopExits);
Instruction* instructionAfterLoop = findInstructionAfterLoop(loopBody);
if (instructionAfterLoop == NULL) {
cout << "Warning: instruction after loop not found!" << endl;
continue;
}
auto firstInstruction = header->getInstructions()[0]->getInstruction();
auto lastInstruction = tail->getInstructions().back()->getInstruction();
cout << "first - " << firstInstruction->getNumber() << " last - " << lastInstruction->getNumber() << " after - " << instructionAfterLoop->getNumber() << endl;
auto x = firstInstruction->getOperator();
auto tmpLoop = new LoopGraph();
tmpLoop->isFor = true;
tmpLoop->lineNum = firstInstruction->getOperator()->lineNumber();
tmpLoop->lineNumAfterLoop = instructionAfterLoop->getOperator()->lineNumber();
if (firstInstruction->getOperator()->variant() == FOR_NODE) {
SgForStmt* stmt = isSgForStmt(firstInstruction->getOperator());
cout << "for loop" << endl;// << stmt->sunparse() << endl;
}
else if (firstInstruction->getOperator()->variant() == WHILE_NODE) {
SgWhileStmt* stmt = isSgWhileStmt(firstInstruction->getOperator());
cout << (stmt->conditional() == NULL ? "infinit" : "") << "while loop" << endl;//<< stmt->sunparse() << endl;
}
else if (firstInstruction->getOperator()->variant() == DO_WHILE_NODE) {
SgWhileStmt* stmt = isSgDoWhileStmt(firstInstruction->getOperator());
cout << "do while loop" << endl;// << stmt->sunparse() << endl;
}
else if (firstInstruction->getOperator()->variant() == LOOP_NODE) {
cout << "not known loop" << endl;// << firstInstruction->getOperator()->sunparse() << endl;
}
else {
cout << "goto loop" << endl;// firstInstruction->getOperator()->sunparse() << endl;
}
cout << "loop start line " << tmpLoop->lineNum << endl;
cout << "after loop line " << tmpLoop->lineNumAfterLoop << endl << endl;
loops.push_back(tmpLoop);
}
}
}

View File

@@ -6,7 +6,7 @@
#include <algorithm>
#include "CFGraph.h"
#include "../Utils/CommonBlock.h"
#include "CommonBlock.h"
namespace SAPFOR
{
@@ -52,10 +52,7 @@ namespace SAPFOR
}
}
Argument(const Argument& other)
: number(other.number),
type(other.type),
mType(other.mType),
value(other.value)
: number(other.number), type(other.type), mType(other.mType), value(other.value)
{ }
void setType(CFG_ARG_TYPE newType) { type = newType; }
@@ -137,7 +134,7 @@ namespace SAPFOR
{
if (arg == NULL)
return "";
return arg->getValue();
return arg->getValue();
}
public:
@@ -205,7 +202,7 @@ namespace SAPFOR
{
std::string res = "";
std::string resultVal = getArgValue(result);
std::string resultVal = getArgValue(result);
std::string arg1Val = getArgValue(arg1);
std::string arg2Val = getArgValue(arg2);
@@ -350,6 +347,4 @@ std::vector<SAPFOR::IR_Block*> buildIR(SgStatement* function, const FuncInfo* fu
SAPFOR::Instruction* getInstructionByNumber(const std::vector<SAPFOR::IR_Block*>& blocks, int num);
std::pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*> getInstructionAndBlockByNumber(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph, int num);
std::pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*> getInstructionAndBlockByStatement(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt);
int getParamIndex(SAPFOR::Argument* func_param, int max_index);
void exploreLoops(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>* fullIR, const char* fileName);
int getParamIndex(SAPFOR::Argument* func_param, int max_index);

View File

@@ -1,633 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <set>
#include "../Utils/SgUtils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "../ExpressionTransform/expr_transform.h"
#include "dvm.h"
#include "IR.h"
#include "CFGraph.h"
using namespace std;
using namespace SAPFOR;
typedef SAPFOR::BasicBlock BBlock;
typedef SAPFOR::Argument BArgument;
static void printBlock(BBlock* block) {
cout << "block - " << block->getNumber() << endl;
cout << "next -";
for (auto i : block->getNext())
{
cout << " " << i->getNumber();
}
cout << endl << "prev -";
for (auto i : block->getPrev())
{
cout << " " << i->getNumber();
}
cout << endl;
for (auto i : block->getInstructions())
{
string resValue = "";
string arg1Value = "";
string arg2Value = "";
if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == CFG_ARG_TYPE::VAR) {
resValue = i->getInstruction()->getResult()->getValue();
i->getInstruction()->getResult()->setValue(i->getInstruction()->getResult()->getValue() + to_string(i->getInstruction()->getResult()->getNumber()));
}
if (i->getInstruction()->getArg1() != nullptr && i->getInstruction()->getArg1()->getType() == CFG_ARG_TYPE::VAR) {
arg1Value = i->getInstruction()->getArg1()->getValue();
i->getInstruction()->getArg1()->setValue(i->getInstruction()->getArg1()->getValue() + to_string(i->getInstruction()->getArg1()->getNumber()));
}
if (i->getInstruction()->getArg2() != nullptr && i->getInstruction()->getArg2()->getType() == CFG_ARG_TYPE::VAR) {
arg2Value = i->getInstruction()->getArg2()->getValue();
i->getInstruction()->getArg2()->setValue(i->getInstruction()->getArg2()->getValue() + to_string(i->getInstruction()->getArg2()->getNumber()));
}
cout << i->getNumber() << " " << i->getInstruction()->dump() << endl;
if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == CFG_ARG_TYPE::VAR) {
i->getInstruction()->getResult()->setValue(resValue);
}
if (i->getInstruction()->getArg1() != nullptr && i->getInstruction()->getArg1()->getType() == CFG_ARG_TYPE::VAR) {
i->getInstruction()->getArg1()->setValue(arg1Value);
}
if (i->getInstruction()->getArg2() != nullptr && i->getInstruction()->getArg2()->getType() == CFG_ARG_TYPE::VAR) {
i->getInstruction()->getArg2()->setValue(arg2Value);
}
}
cout << endl;
}
template <typename T>
static bool compareVectors(const vector<T>* vec1, const vector<T>* vec2) {
if (vec1 == vec2) {
return true;
}
if (!vec1 || !vec2) {
return false;
}
vector<T> sortedVec1 = *vec1;
vector<T> sortedVec2 = *vec2;
sort(sortedVec1.begin(), sortedVec1.end());
sort(sortedVec2.begin(), sortedVec2.end());
return sortedVec1 == sortedVec2;
}
template <typename T>
static vector<T>* getCommonElements(const vector<vector<T>>* vectors) {
if (!vectors || vectors->empty()) {
return new vector<T>(); // Return an empty vector if input is null or empty
}
// Start with the first vector
vector<T>* commonElements = new vector<T>((*vectors)[0]);
for (size_t i = 1; i < vectors->size(); ++i) {
vector<T> tempCommon;
// Sort the current vector and common result for intersection
vector<T> sortedVec = (*vectors)[i];
sort(commonElements->begin(), commonElements->end());
sort(sortedVec.begin(), sortedVec.end());
// Find the intersection
set_intersection(
commonElements->begin(), commonElements->end(),
sortedVec.begin(), sortedVec.end(),
back_inserter(tempCommon)
);
// Update common result
*commonElements = tempCommon;
// If no common elements left, break early
if (commonElements->empty()) {
break;
}
}
return commonElements;
}
static map<BBlock*, vector<BBlock*>> findDominators(vector<BBlock*> blocks) {
map<BBlock*, vector<BBlock*>> result;
bool changed = true;
while (changed) {
changed = false;
for (auto currentBlock : blocks) {
auto pred = currentBlock->getPrev();
auto prevDominators = new vector<vector<BBlock*>>();
for (auto predBlock : pred)
prevDominators->push_back(result.find(predBlock) != result.end() ? result[predBlock] : blocks);
auto currentBlockResult = getCommonElements(prevDominators);
currentBlockResult->push_back(currentBlock);
if (result.find(currentBlock) == result.end() || !compareVectors(currentBlockResult, &result[currentBlock])) {
result[currentBlock] = *currentBlockResult;
changed = true;
}
}
}
return result;
}
static void RenumberBlocks(BBlock* current, int* n, map<int, int>* res, set<BBlock*>* visited) {
if (visited->find(current) != visited->end()) {
return;
}
visited->insert(current);
vector<BBlock*> nextBlocks = current->getNext();
sort(nextBlocks.begin(), nextBlocks.end(), [](BBlock* a, BBlock* b) {
return a->getInstructions()[0]->getInstruction()->getOperator()->lineNumber() > b->getInstructions()[0]->getInstruction()->getOperator()->lineNumber();
});
for (auto i : nextBlocks) {
RenumberBlocks(i, n, res, visited);
}
(*res)[current->getNumber()] = *n;
*n -= 1;
}
static map<BBlock*, vector<BBlock*>> findDominatorBorders(vector<BBlock*>& blocks, map<BBlock*, BBlock*>& iDominators) {
map<BBlock*, vector<BBlock*>> result;
for (auto block : blocks) {
result[block] = *(new vector<BBlock*>());
}
for (auto block : blocks) {
if (block->getPrev().size() > 1) {
for (auto prev : block->getPrev()) {
auto tmpBlock = prev;
auto test = iDominators[block];
auto test2 = iDominators[prev];
while (tmpBlock != iDominators[block]) {
result[tmpBlock].push_back(block);
tmpBlock = iDominators[tmpBlock];
}
}
}
}
return result;
}
static BBlock* findImmediateDominatorsDfsHelper(BBlock* block, BBlock* currentBlock, BBlock* currentImmediateDominator, vector<BBlock*> &visited, map<BBlock*, vector<BBlock*>>& dominators) {
if (block == currentBlock) {
return currentImmediateDominator;
}
if (find(visited.begin(), visited.end(), currentBlock) != visited.end()) {
return nullptr;
}
visited.push_back(currentBlock);
if (find(dominators[block].begin(), dominators[block].end(), currentBlock) != dominators[block].end()) {
currentImmediateDominator = currentBlock;
}
for (auto nextBlock : currentBlock->getNext()) {
auto result = findImmediateDominatorsDfsHelper(block, nextBlock, currentImmediateDominator, visited, dominators);
if (result) {
return result;
}
}
return nullptr;
}
static map<BBlock*, BBlock*> findImmediateDominators1(const map<BBlock*, vector<BBlock*>>& dominators, BBlock* entry) {
map<BBlock*, BBlock*> iDom;
for (const auto& pair : dominators) {
BBlock* b = pair.first;
if (b == entry) continue;
const auto& doms = pair.second;
BBlock* candidate = nullptr;
for (auto d : doms) {
if (d == b) continue;
bool isImmediate = true;
for (auto other : doms) {
if (other == b || other == d) continue;
const auto& domsOfOther = dominators.at(other);
if (std::find(domsOfOther.begin(), domsOfOther.end(), d) != domsOfOther.end()) {
isImmediate = false;
break;
}
}
if (isImmediate) {
candidate = d;
break;
}
}
if (candidate) {
iDom[b] = candidate;
}
}
return iDom;
}
static map<BBlock*, BBlock*> findImmediateDominators(map<BBlock*, vector<BBlock*>>& dominators, BBlock* fistBlock) {
map<BBlock*, BBlock*> iDominators;
for (const auto& domPair : dominators) {
BBlock* block = domPair.first;
const vector<BBlock*>& domBlocks = domPair.second;
vector<BBlock*> visited;
if (block == fistBlock) {
continue;
}
iDominators[block] = findImmediateDominatorsDfsHelper(block, fistBlock, fistBlock, visited, dominators);
}
return iDominators;
}
static vector<BArgument*> getDefForBlock(const BBlock& block) {
vector<BArgument*> def;
const auto& instructions = block.getInstructions();
for (const auto& irBlock : instructions) {
if (irBlock) {
Instruction* instr = irBlock->getInstruction();
if (instr) {
BArgument* result = instr->getResult();
if (result) {
def.push_back(result);
}
}
}
}
return def;
}
static pair<set<BArgument*>, map<BArgument*, set<BBlock*>>> getGlobalsAndVarBlocks(vector<BBlock*> blocks) {
set<BArgument*> globals;
map<BArgument*, set<BBlock*>> varBlocks;
for (auto block : blocks) {
set<BArgument*> def;
const auto& instructions = block->getInstructions();
for (const auto& irBlock : instructions) {
if (irBlock) {
Instruction* instr = irBlock->getInstruction();
if (instr) {
auto arg1 = instr->getArg1();
auto arg2 = instr->getArg2();
auto res = instr->getResult();
if (arg1 && arg1->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg1) == def.end()) {
globals.insert(arg1);
}
if (arg2 && arg2->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg2) == def.end()) {
globals.insert(arg2);
}
if (res && res->getType() == CFG_ARG_TYPE::VAR) {
def.insert(res);
varBlocks[res].insert(block);
}
}
}
}
}
return make_pair(globals, varBlocks);
}
static void getBlocksWithFiFunctions(vector<BBlock*> blocks, set<BArgument*> globals, map<BArgument*, set<BBlock*>> varBlocks, map<BBlock*, vector<BBlock*>> dominatorBorders) {
vector<BBlock*> blocksWithFiFunctions;
auto fiFunc = new BArgument(CFG_ARG_TYPE::FUNC, CFG_MEM_TYPE::NONE_, "FI_FUNCTION");
auto paramCount = new BArgument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::LOCAL_, "0");
for (auto var : globals) {
auto worklist = varBlocks[var];
set<BBlock*> hasFiFunction;
while (!worklist.empty()) {
auto block = *worklist.begin();
worklist.erase(block);
for (auto dfBlock : dominatorBorders[block]) {
if (hasFiFunction.find(dfBlock) == hasFiFunction.end()) {
hasFiFunction.insert(dfBlock);
Instruction* phiInstruction = new Instruction(CFG_OP::F_CALL, new BArgument(*fiFunc), new BArgument(*paramCount), var, dfBlock->getInstructions()[0]->getInstruction()->getOperator());
IR_Block* phiBlock = new IR_Block(phiInstruction);
dfBlock->addInstructionInFront(phiBlock);
//blocksWithFiFunctions.push_back(dfBlock);
}
}
}
}
//return blocksWithFiFunctions;
}
string ToString(CFG_ARG_TYPE type) {
switch (type) {
case CFG_ARG_TYPE::NONE: return "NONE";
case CFG_ARG_TYPE::REG: return "REG";
case CFG_ARG_TYPE::VAR: return "VAR";
case CFG_ARG_TYPE::ARRAY: return "ARRAY";
case CFG_ARG_TYPE::CONST: return "CONST";
case CFG_ARG_TYPE::FUNC: return "FUNC";
case CFG_ARG_TYPE::LAB: return "LAB";
case CFG_ARG_TYPE::INSTR: return "INSTR";
case CFG_ARG_TYPE::CONST_STR: return "CONST_STR";
case CFG_ARG_TYPE::RECORD: return "RECORD";
case CFG_ARG_TYPE::CONSTR_REF: return "CONSTR_REF";
default: return "UNKNOWN";
}
}
void restoreConnections(const vector<BBlock*>& originalBlocks, vector<BBlock*>& copiedBlocks) {
// Создаем отображение оригинальных блоков в их копии
map<BBlock*, BBlock*> blockMapping;
for (size_t i = 0; i < originalBlocks.size(); ++i) {
blockMapping[originalBlocks[i]] = copiedBlocks[i];
}
// Восстанавливаем связи между копиями
for (size_t i = 0; i < originalBlocks.size(); ++i) {
BBlock* originalBlock = originalBlocks[i];
BBlock* copiedBlock = copiedBlocks[i];
auto prevCopy = copiedBlock->getPrev();
for (auto j : prevCopy) {
copiedBlock->removePrev(j);
}
// Копируем, затем удаляем next связи
auto nextCopy = copiedBlock->getNext();
for (auto j : nextCopy) {
copiedBlock->removeNext(j);
}
// Восстанавливаем связи succ (следующих блоков)
for (auto* succ : originalBlock->getNext()) {
copiedBlock->addNext(blockMapping[succ]);
}
// Восстанавливаем связи prev (предыдущих блоков)
for (auto* prev : originalBlock->getPrev()) {
copiedBlock->addPrev(blockMapping[prev]);
}
}
}
BArgument* NewName(BArgument* var, map<string, int>& counter, map<string, stack<BArgument*>>& stack, int number) {
//int index = counter[var->getValue()];
counter[var->getValue()]++;
BArgument* newName = new BArgument(var->getType(), var->getMemType(), var->getValue(), number);
stack[var->getValue()].push(newName);
return newName;
}
void RenameFiFunctionResultVar(BBlock* block, map<string, int>& counter, map<string, stack<BArgument*>>& stack) {
for (auto irBlock : block->getInstructions()) {
auto instruction = irBlock->getInstruction();
if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != nullptr && instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != nullptr) {
instruction->setResult(NewName(instruction->getResult(), counter, stack, instruction->getNumber()));
}
}
}
void RenameInstructionVars(BBlock* block, map<string, int>& counter, map<string, stack<BArgument*>>& stack) {
for (auto irBlock : block->getInstructions()) {
auto instruction = irBlock->getInstruction();
if (instruction->getArg1() != nullptr && instruction->getArg1()->getType() == CFG_ARG_TYPE::VAR) {
instruction->setArg1(stack[instruction->getArg1()->getValue()].top());
}
if (instruction->getArg2() != nullptr && instruction->getArg2()->getType() == CFG_ARG_TYPE::VAR) {
instruction->setArg2(stack[instruction->getArg2()->getValue()].top());
}
if (instruction->getResult() != nullptr && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR) {
instruction->setResult(NewName(instruction->getResult(), counter, stack, instruction->getNumber()));
}
}
}
void RenameFiFunctionArgsVar(BBlock* block, map<string, stack<BArgument*>>& stack) {
auto size = block->getInstructions().size();
auto& instructions = block->getInstructions();
for (auto i = 0; i < size; i++) {
auto irBlock = instructions[i];
auto instruction = irBlock->getInstruction();
if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != nullptr && instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != nullptr && instruction->getArg2() != nullptr) {
Instruction* paramInstruction;
if (stack[instruction->getResult()->getValue()].size() > 0) {
BArgument* tmp = new BArgument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, to_string(stack[instruction->getResult()->getValue()].top()->getNumber()));
paramInstruction = new Instruction(CFG_OP::PARAM, tmp);
}
else {
BArgument* tmp = new BArgument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1");
paramInstruction = new Instruction(CFG_OP::PARAM, tmp);
}
paramInstruction->setOperator(block->getInstructions()[0]->getInstruction()->getOperator());
block->addInstructionBeforeInstruction(new IR_Block(paramInstruction), instruction);
instruction->getArg2()->setValue(to_string(stoi(instruction->getArg2()->getValue()) + 1));
i++;
}
}
}
vector<BBlock*> findBlocksWithValue(map<BBlock*, BBlock*>& iDominators, BBlock* x) {
vector<BBlock*> result;
// Проходим по всем элементам map
for (auto& pair : iDominators) {
// Если значение равно x, добавляем ключ в результат
if (pair.second == x) {
result.push_back(pair.first);
}
}
return result;
}
void RenameIR(BBlock* block, map<BBlock*, BBlock*>& iDominators, map<string, int>& counter, map<string, stack<BArgument*>>& stack) {
RenameFiFunctionResultVar(block, counter, stack);
RenameInstructionVars(block, counter, stack);
for (auto* successor : block->getNext()) {
RenameFiFunctionArgsVar(successor, stack);
}
for (auto* child : findBlocksWithValue(iDominators, block)) {
RenameIR(child, iDominators, counter, stack);
}
for (auto& irBlock : block->getInstructions()) {
auto instruction = irBlock->getInstruction();
if (instruction->getResult() != nullptr && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR) {
string varName = instruction->getResult()->getValue();
stack[varName].pop();
}
}
for (auto& irBlock : block->getInstructions()) {
auto instruction = irBlock->getInstruction();
if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != nullptr && instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != nullptr) {
string varName = instruction->getResult()->getValue();
stack[varName].pop();
}
}
}
void buildIRSSAForm(map<FuncInfo*, vector<BBlock*>> fullIR, map<FuncInfo*, vector<BBlock*>>* result) {
for (auto item : fullIR) {
auto funcinfo = item.first;
auto funcIRConst = item.second;
cout << "Testing " << item.first->funcName << endl;
vector<BBlock*> funcIR;
for (auto i : funcIRConst) {
funcIR.push_back(new BBlock(*i));
}
restoreConnections(funcIRConst, funcIR);
for (auto i : funcIR) {
//printBlock(i);
}
auto dominators = findDominators(funcIR);
/*cout << endl << endl << endl << "DOMINATORS" << endl << endl << endl;
for (auto i : dominators) {
cout << "block - " << i.first->getNumber() << endl;
for (auto j : i.second) {
cout << "dominators - " << j->getNumber() << endl;
}
cout << endl;
}*/
auto iDominators = findImmediateDominators1(dominators, funcIR[0]);
/*for (auto i : iDominators) {
cout << "block - " << i.first->getNumber() << endl;
cout << "Idominators - " << i.second->getNumber() << endl;
cout << endl;
}
*/
auto dominatorBorders = findDominatorBorders(funcIR, iDominators);
/*for (auto i : dominatorBorders) {
cout << "block - " << i.first->getNumber() << endl;
for (auto j : i.second) {
cout << "border - " << j->getNumber() << endl;
}
cout << endl;
}*/
auto globalsAndVarBlocks = getGlobalsAndVarBlocks(funcIR);
auto globals = globalsAndVarBlocks.first;
auto varBlocks = globalsAndVarBlocks.second;
/*for (auto i : globals) {
cout << i->getValue() << " " << ToString(i->getType()) << " " << i->getNumber() << endl;
}
cout << endl;
for (auto i : varBlocks) {
cout << i.first->getValue() << " - ";
for (auto j : i.second) {
cout << j->getNumber() << ", ";
}
cout << endl;
}
cout << endl;
*/
getBlocksWithFiFunctions(funcIR, globals, varBlocks, dominatorBorders);
map<string, int> count;
map<string, stack<BArgument*>> varStack;
for (auto var : globals) {
count[var->getValue()] = 0;
stack<BArgument*> tmp;
BArgument* tmpArgument = new BArgument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1");
tmp.push(tmpArgument);
varStack[var->getValue()] = tmp;
}
RenameIR(funcIR[0], iDominators, count, varStack);
for (auto i : funcIR) {
//printBlock(i);
}
//cout << endl << endl << endl << endl << endl;
//for (auto i : funcIRConst) {
// printBlock(i);
//}
(*result)[funcinfo] = funcIR;
}
}

View File

@@ -1,6 +0,0 @@
#pragma once
#include "CFGraph.h"
#include "IR.h"
void buildIRSSAForm(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>> fullIR, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>* result);

386
src/CFGraph/IR_SSAForm.cpp Normal file
View File

@@ -0,0 +1,386 @@
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <set>
#include "../Utils/SgUtils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "dvm.h"
#include "IR.h"
#include "CFGraph.h"
using namespace std;
using namespace SAPFOR;
static const SAPFOR::Argument CONST_UNDEFINED_ARG(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1");
template <typename T> static bool compareVectors(const vector<T>* vec1, const vector<T>* vec2)
{
if (vec1 == vec2)
return true;
if (!vec1 || !vec2)
return false;
vector<T> sortedVec1 = *vec1;
vector<T> sortedVec2 = *vec2;
sort(sortedVec1.begin(), sortedVec1.end());
sort(sortedVec2.begin(), sortedVec2.end());
return sortedVec1 == sortedVec2;
}
template <typename T> static vector<T>* getCommonElements(const vector<vector<T>>* vectors)
{
if (!vectors || vectors->empty())
return new vector<T>();
vector<T>* commonElements = new vector<T>((*vectors)[0]);
for (size_t i = 1; i < vectors->size(); ++i)
{
vector<T> tempCommon;
vector<T> sortedVec = (*vectors)[i];
sort(commonElements->begin(), commonElements->end());
sort(sortedVec.begin(), sortedVec.end());
set_intersection(
commonElements->begin(), commonElements->end(),
sortedVec.begin(), sortedVec.end(),
back_inserter(tempCommon)
);
*commonElements = tempCommon;
if (commonElements->empty())
break;
}
return commonElements;
}
static map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>> findDominators(const vector<SAPFOR::BasicBlock*>& blocks)
{
map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>> result;
bool changed = true;
while (changed)
{
changed = false;
for (auto& currentBlock : blocks)
{
auto pred = currentBlock->getPrev();
auto prevDominators = new vector<vector<SAPFOR::BasicBlock*>>();
for (auto predBlock : pred)
prevDominators->push_back(result.find(predBlock) != result.end() ? result[predBlock] : blocks);
auto currentBlockResult = getCommonElements(prevDominators);
currentBlockResult->push_back(currentBlock);
if (result.find(currentBlock) == result.end() || !compareVectors(currentBlockResult, &result[currentBlock]))
{
result[currentBlock] = *currentBlockResult;
changed = true;
}
}
}
return result;
}
static map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>> findDominatorBorders(const vector<SAPFOR::BasicBlock*>& blocks)
{
map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>> result;
for (auto& block : blocks)
result[block] = *(new vector<SAPFOR::BasicBlock*>());
for (auto& block : blocks)
{
if (block->getPrev().size() > 1)
{
for (auto prev : block->getPrev())
{
auto tmpBlock = prev;
while (tmpBlock != block->getDom())
{
result[tmpBlock].push_back(block);
tmpBlock = tmpBlock->getDom();
}
}
}
}
return result;
}
static pair<set<SAPFOR::Argument*>, map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>>> getGlobalsAndVarBlocks(const vector<SAPFOR::BasicBlock*>& blocks)
{
set<SAPFOR::Argument*> globals;
map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>> varBlocks;
for (auto& block : blocks)
{
set<SAPFOR::Argument*> def;
const auto& instructions = block->getInstructions();
for (const auto& irBlock : instructions)
{
if (irBlock)
{
Instruction* instr = irBlock->getInstruction();
if (instr)
{
auto arg1 = instr->getArg1();
auto arg2 = instr->getArg2();
auto res = instr->getResult();
if (arg1 && arg1->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg1) == def.end())
globals.insert(arg1);
if (arg2 && arg2->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg2) == def.end())
globals.insert(arg2);
if (res && res->getType() == CFG_ARG_TYPE::VAR)
{
def.insert(res);
varBlocks[res].insert(block);
}
}
}
}
}
return make_pair(globals, varBlocks);
}
static void getBlocksWithFiFunctions(const vector<SAPFOR::BasicBlock*> blocks, set<SAPFOR::Argument*>& globals,
map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>>& varBlocks,
map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>>& dominatorBorders)
{
vector<SAPFOR::BasicBlock*> blocksWithFiFunctions;
auto fiFunc = new SAPFOR::Argument(CFG_ARG_TYPE::FUNC, CFG_MEM_TYPE::NONE_, "FI_FUNCTION");
auto paramCount = new SAPFOR::Argument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::LOCAL_, "0");
for (auto& var : globals)
{
auto worklist = varBlocks[var];
set<SAPFOR::BasicBlock*> hasFiFunction;
while (!worklist.empty())
{
auto block = *worklist.begin();
worklist.erase(block);
for (auto& dfBlock : dominatorBorders[block])
{
if (hasFiFunction.find(dfBlock) == hasFiFunction.end())
{
hasFiFunction.insert(dfBlock);
Instruction* phiInstruction = new Instruction(CFG_OP::F_CALL, new SAPFOR::Argument(*fiFunc), new SAPFOR::Argument(*paramCount), var, dfBlock->getInstructions()[0]->getInstruction()->getOperator());
IR_Block* phiBlock = new IR_Block(phiInstruction);
dfBlock->addInstruction(phiBlock, true);
}
}
}
}
}
static void restoreConnections(const vector<SAPFOR::BasicBlock*>& originalBlocks, vector<SAPFOR::BasicBlock*>& copiedBlocks)
{
map<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*> blockMapping;
for (size_t i = 0; i < originalBlocks.size(); ++i)
blockMapping[originalBlocks[i]] = copiedBlocks[i];
for (size_t i = 0; i < originalBlocks.size(); ++i)
{
SAPFOR::BasicBlock* originalBlock = originalBlocks[i];
SAPFOR::BasicBlock* copiedBlock = copiedBlocks[i];
auto prevCopy = copiedBlock->getPrev();
for (auto j : prevCopy)
copiedBlock->removePrev(j);
auto nextCopy = copiedBlock->getNext();
for (auto j : nextCopy)
copiedBlock->removeNext(j);
for (auto* succ : originalBlock->getNext())
copiedBlock->addNext(blockMapping[succ]);
for (auto* prev : originalBlock->getPrev())
copiedBlock->addPrev(blockMapping[prev]);
}
}
static SAPFOR::Argument* newName(SAPFOR::Argument* var, map<string, int>& counter, map<string, stack<SAPFOR::Argument*>>& stack, int number) {
counter[var->getValue()]++;
SAPFOR::Argument* newName = new SAPFOR::Argument(var->getType(), var->getMemType(), var->getValue(), number);
stack[var->getValue()].push(newName);
return newName;
}
static void renameFiFunctionResultVar(SAPFOR::BasicBlock* block, map<string, int>& counter, map<string, stack<SAPFOR::Argument*>>& stack) {
for (auto& irBlock : block->getInstructions())
{
auto instruction = irBlock->getInstruction();
if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != NULL &&
instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL)
{
instruction->setResult(newName(instruction->getResult(), counter, stack, instruction->getNumber()));
}
}
}
static void renameInstructionVars(SAPFOR::BasicBlock* block, map<string, int>& counter, map<string, stack<SAPFOR::Argument*>>& stack)
{
for (auto& irBlock : block->getInstructions())
{
auto instruction = irBlock->getInstruction();
if (instruction->getArg1() != NULL && instruction->getArg1()->getType() == CFG_ARG_TYPE::VAR)
instruction->setArg1(stack[instruction->getArg1()->getValue()].top());
if (instruction->getArg2() != NULL && instruction->getArg2()->getType() == CFG_ARG_TYPE::VAR)
instruction->setArg2(stack[instruction->getArg2()->getValue()].top());
if (instruction->getResult() != NULL && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR)
instruction->setResult(newName(instruction->getResult(), counter, stack, instruction->getNumber()));
}
}
static void renameFiFunctionArgsVar(SAPFOR::BasicBlock* block, map<string, stack<SAPFOR::Argument*>>& stack)
{
auto size = block->getInstructions().size();
auto& instructions = block->getInstructions();
for (size_t i = 0; i < size; ++i)
{
auto irBlock = instructions[i];
auto instruction = irBlock->getInstruction();
if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != NULL &&
instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL &&
instruction->getArg2() != NULL)
{
Instruction* paramInstruction;
if (stack[instruction->getResult()->getValue()].size() > 0)
{
SAPFOR::Argument* tmp = new SAPFOR::Argument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, to_string(stack[instruction->getResult()->getValue()].top()->getNumber()));
paramInstruction = new Instruction(CFG_OP::PARAM, tmp);
}
else
{
SAPFOR::Argument* tmp = new SAPFOR::Argument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1");
paramInstruction = new Instruction(CFG_OP::PARAM, tmp);
}
paramInstruction->setOperator(block->getInstructions()[0]->getInstruction()->getOperator());
block->addInstructionBefore(new IR_Block(paramInstruction), instruction);
instruction->getArg2()->setValue(to_string(stoi(instruction->getArg2()->getValue()) + 1));
i++;
}
}
}
static vector<SAPFOR::BasicBlock*> findBlocksWithValue(vector<SAPFOR::BasicBlock*>& blocks, SAPFOR::BasicBlock* x)
{
vector<SAPFOR::BasicBlock*> result;
for (auto& block : blocks)
if (block->getDom() == x)
result.push_back(block);
return result;
}
static void renameIR(SAPFOR::BasicBlock* block, vector<SAPFOR::BasicBlock*>& blocks, map<string, int>& counter, map<string, stack<SAPFOR::Argument*>>& stack)
{
renameFiFunctionResultVar(block, counter, stack);
renameInstructionVars(block, counter, stack);
for (auto& successor : block->getNext())
renameFiFunctionArgsVar(successor, stack);
for (auto& child : findBlocksWithValue(blocks, block))
renameIR(child, blocks, counter, stack);
for (auto& irBlock : block->getInstructions())
{
auto instruction = irBlock->getInstruction();
if (instruction->getResult() != NULL && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR)
{
string varName = instruction->getResult()->getValue();
stack[varName].pop();
}
}
for (auto& irBlock : block->getInstructions())
{
auto instruction = irBlock->getInstruction();
if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != NULL &&
instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL)
{
string varName = instruction->getResult()->getValue();
stack[varName].pop();
}
}
}
void buildFuncIRSSAForm(FuncInfo* funcInfo, const std::vector<SAPFOR::BasicBlock*>& funcIRConst, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& result)
{
vector<SAPFOR::BasicBlock*> funcIR;
for (auto& i : funcIRConst)
funcIR.push_back(new SAPFOR::BasicBlock(*i));
restoreConnections(funcIRConst, funcIR);
SAPFOR::buildDominatorTree(funcIR);
auto dominatorBorders = findDominatorBorders(funcIR);
auto globalsAndVarBlocks = getGlobalsAndVarBlocks(funcIR);
auto globals = globalsAndVarBlocks.first;
auto varBlocks = globalsAndVarBlocks.second;
getBlocksWithFiFunctions(funcIR, globals, varBlocks, dominatorBorders);
map<string, int> count;
map<string, stack<SAPFOR::Argument*>> varStack;
for (auto& var : globals)
{
count[var->getValue()] = 0;
stack<SAPFOR::Argument*> tmp;
tmp.push(new SAPFOR::Argument(CONST_UNDEFINED_ARG));
varStack[var->getValue()] = tmp;
}
renameIR(funcIR[0], funcIR, count, varStack);
result[funcInfo] = funcIR;
}
FuncInfo* getIRByFilename(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR, const char* filename)
{
for (auto ir : fullIR)
if (ir.first->fileName == filename)
return ir.first;
return nullptr;
}

8
src/CFGraph/IR_SSAForm.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
#include "CFGraph.h"
#include "IR.h"
void buildFuncIRSSAForm(FuncInfo* funcInfo, const std::vector<SAPFOR::BasicBlock*>& fullIR, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& result);
FuncInfo* getIRByFilename(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR, const char* filename);

102
src/CFGraph/IR_domTree.cpp Normal file
View File

@@ -0,0 +1,102 @@
#include "dvm.h"
#include "IR_domTree.h"
namespace SAPFOR {
void DominatorFinder::DFS(BasicBlock* v, int parent_num) {
dfs_num[v] = n;
vertex[n] = n;
semi[n] = n;
label[n] = n;
ancestor[n] = -1;
parent[n] = parent_num;
vertices[n++] = v;
for (const auto& w : v->getNext()) {
if (dfs_num[w] == -1)
DFS(w, dfs_num[v]);
}
}
void DominatorFinder::Compress(int v) {
if (ancestor[ancestor[v]] != -1) {
Compress(ancestor[v]);
if (semi[label[ancestor[v]]] < semi[label[v]])
label[v] = label[ancestor[v]];
ancestor[v] = ancestor[ancestor[v]];
}
}
int DominatorFinder::Eval(int v) {
if (ancestor[v] == -1)
return v;
Compress(v);
return label[v];
}
void DominatorFinder::Link(int v, int w) {
ancestor[w] = v;
}
DominatorFinder::DominatorFinder(std::vector<BasicBlock*>& blocks) {
if (blocks.empty())
return;
entry = blocks[0];
n = 0;
for (auto block : blocks)
dfs_num[block] = -1;
int max_size = blocks.size();
vertices.resize(max_size);
parent.assign(max_size, -1);
semi.assign(max_size, -1);
vertex.assign(max_size, -1);
ancestor.assign(max_size, -1);
label.assign(max_size, -1);
bucket.resize(max_size);
DFS(entry, -1);
for (int i = n - 1; i > 0; --i) {
int w = vertex[i];
for (BasicBlock* v : vertices[w]->getPrev()) {
if (dfs_num[v] == -1)
continue;
int u = Eval(dfs_num[v]);
if (semi[u] < semi[w])
semi[w] = semi[u];
}
bucket[vertex[semi[w]]].push_back(w);
Link(parent[w], w);
for (int v : bucket[parent[w]])
{
int u = Eval(v);
if (semi[u] < semi[v])
vertices[v]->setDom(vertices[u]);
else
vertices[v]->setDom(vertices[parent[w]]);
}
bucket[parent[w]].clear();
}
for (int i = 1; i < n; ++i) {
int w = vertex[i];
if (vertices[w]->getDom() != vertices[vertex[semi[w]]])
vertices[w]->setDom(vertices[w]->getDom()->getDom());
}
entry->setDom(nullptr);
}
void buildDominatorTree(std::vector<BasicBlock*>& blocks) {
DominatorFinder finder(blocks);
}
}

35
src/CFGraph/IR_domTree.h Normal file
View File

@@ -0,0 +1,35 @@
#pragma once
#include <vector>
#include <map>
#include <unordered_map>
#include "CFGraph.h"
// Lengauer, Thomas. A fast algorithm for finding dominators in a flowgraph / Thomas Lengauer, Robert Endre Tarjan
// ACM Transactions on Programming Languages and Systems (TOPLAS). <20> 1979. <20> Vol. 1, no. 1. <20> Pp. 121<32>141.
namespace SAPFOR {
class BasicBlock;
class DominatorFinder {
private:
BasicBlock* entry;
std::vector<BasicBlock*> vertices;
std::unordered_map<BasicBlock*, int> dfs_num;
std::vector<int> parent, semi, vertex, ancestor, label;
std::vector<std::vector<int>> bucket;
int n;
void DFS(BasicBlock* v, int parent_num);
void Compress(int v);
int Eval(int v);
void Link(int v, int w);
public:
DominatorFinder(std::vector<BasicBlock*>& blocks);
};
void buildDominatorTree(std::vector<BasicBlock*>& blocks);
}

View File

@@ -8,10 +8,10 @@
#include <unordered_map>
#include <unordered_set>
#include "../Utils/SgUtils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "../ExpressionTransform/expr_transform.h"
#include "SgUtils.h"
#include "CommonBlock.h"
#include "graph_calls.h"
#include "expr_transform.h"
#define PRINT_PROF_INFO 0
#define DEBUG_CHECKS 0

View File

@@ -2,9 +2,9 @@
#include<unordered_map>
#include "../Utils/SgUtils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "SgUtils.h"
#include "CommonBlock.h"
#include "graph_calls.h"
#include "CFGraph.h"
#include "IR.h"

View File

@@ -1,6 +1,6 @@
#pragma once
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
#include "CFGraph.h"
namespace LIVE_VARIABLES

View File

@@ -1,6 +1,6 @@
#include "../Utils/errors.h"
#include "errors.h"
#include "private_variables_analysis.h"
#include "../GraphLoop/graph_loops.h"
#include "graph_loops.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../SageAnalysisTool/depGraph.h"
#include "../DirectiveProcessing/directive_parser.h"
@@ -250,7 +250,7 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
const map<string, SgSymbol*>& commonArgs, FuncInfo* func,
map<string, vector<Messages>>& messages)
{
if (!loop->isFor)
if (!loop->isFor())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //should be called only with FOR loops
SgStatement* loop_operator = loop->loop->GetOriginal();
@@ -450,7 +450,7 @@ static void recAnalyzeLoop(LoopGraph* loop, const set<SAPFOR::BasicBlock*>& bloc
const map<string, SgSymbol*>& commonArgs,
FuncInfo* func, map<string, vector<Messages>>& messages)
{
const auto& loop_body = loop->isFor ? analyzeLoop(loop, blocks, commonVars, commonArgs, func, messages) : blocks;
const auto& loop_body = loop->isFor() ? analyzeLoop(loop, blocks, commonVars, commonArgs, func, messages) : blocks;
for (const auto& inner_loop : loop->children)
recAnalyzeLoop(inner_loop, loop_body, commonVars, commonArgs, func, messages);

View File

@@ -1,5 +1,5 @@
#include "../Utils/SgUtils.h"
#include "../GraphLoop/graph_loops.h"
#include "SgUtils.h"
#include "graph_loops.h"
#include "CFGraph.h"
#include <string>

View File

@@ -1,7 +1,7 @@
#include "CreateInterTree.h"
#include "../Utils/SgUtils.h"
#include "../Utils/utils.h"
#include "../GraphCall/graph_calls_func.h"
#include "SgUtils.h"
#include "utils.h"
#include "graph_calls_func.h"
using std::string;
using std::wstring;

View File

@@ -8,7 +8,7 @@
#include "dvm.h"
#include "../GraphLoop/graph_loops_func.h"
#include "graph_loops_func.h"
struct SpfInterval
{

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -16,9 +16,9 @@
#include <assert.h>
#include "../Distribution/DvmhDirective.h"
#include "../GraphLoop/graph_loops.h"
#include "graph_loops.h"
#include "directive_analyzer.h"
#include "../Utils/utils.h"
#include "utils.h"
using std::vector;
using std::map;

View File

@@ -1,6 +1,6 @@
#pragma once
#include <vector>
#include "../GraphLoop/graph_loops.h"
#include "graph_loops.h"
void UniteNestedDirectives(std::vector<LoopGraph*> &loopGraph);

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -15,18 +15,18 @@
#include "../Distribution/Distribution.h"
#include "../Distribution/DvmhDirective_func.h"
#include "../Utils/errors.h"
#include "errors.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "directive_parser.h"
#include "directive_creator.h"
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
#include "../Sapfor.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../Transformations/loop_transform.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../GraphCall/graph_calls_func.h"
#include "graph_loops_func.h"
#include "../Transformations/LoopNesting/loop_transform.h"
#include "expr_transform.h"
#include "graph_calls_func.h"
#include "../Utils/AstWrapper.h"
#include "AstWrapper.h"
#define PRINT_DIR_RESULT 0

View File

@@ -1,9 +1,9 @@
#pragma once
#include "../Distribution/Distribution.h"
#include "../Utils/errors.h"
#include "../GraphLoop/graph_loops.h"
#include "../Utils/types.h"
#include "errors.h"
#include "graph_loops.h"
#include "types.h"
void createParallelDirectives(const std::map<LoopGraph*, std::map<DIST::Array*, ArrayInfo*>> &loopInfo,
const std::vector<ParallelRegion*>& regions,

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -10,9 +10,9 @@
#include "../ParallelizationRegions/ParRegions.h"
#include "../Distribution/Arrays.h"
#include "../Transformations/loop_transform.h"
#include "../Transformations/LoopNesting/loop_transform.h"
#include "../Utils/errors.h"
#include "errors.h"
#include "directive_parser.h"
#include "directive_creator.h"
@@ -75,7 +75,7 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai
}
}
directive->parallel.push_back(currentLoop->loopSymbol);
directive->parallel.push_back(currentLoop->loopSymbol());
directive->arrayRef = mainArray.arrayRef;
DIST::Array *tmp = mainArray.arrayRef;
@@ -84,7 +84,7 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai
for (int i = 0; i < tmp->GetDimSize(); ++i)
{
if (i == pos)
directive->on.push_back(make_pair(currentLoop->loopSymbol, mainAccess));
directive->on.push_back(make_pair(currentLoop->loopSymbol(), mainAccess));
else
directive->on.push_back(make_pair("*", make_pair(0, 0)));
}
@@ -808,7 +808,7 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
for (int i = 0; i < mainArrayOfLoop->GetDimSize(); ++i)
{
if (i == dimPos)
parDir->on2.push_back(make_pair(currLoop->loopSymbol, mainAccess));
parDir->on2.push_back(make_pair(currLoop->loopSymbol(), mainAccess));
else
parDir->on2.push_back(make_pair("*", make_pair(0, 0)));
}
@@ -1100,7 +1100,7 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
LoopGraph* tmpL = loop;
for (int z = 0; z < nested; ++z)
{
deprecateToMatch.insert(tmpL->loopSymbol);
deprecateToMatch.insert(tmpL->loopSymbol());
if (tmpL->children.size())
tmpL = tmpL->children[0];
else if (z != nested - 1)
@@ -1113,7 +1113,7 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
tmpL = loop->parent;
while (tmpL)
{
if (!tmpL->isFor) // TODO: need to add all inductive variables!
if (tmpL->isWhile()) // TODO: need to add all inductive variables!
{
SgWhileStmt* dow = isSgWhileStmt(tmpL->loop->GetOriginal());
if (dow->conditional())
@@ -1124,7 +1124,7 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
}
}
else
deprecateToMatch.insert(tmpL->loopSymbol);
deprecateToMatch.insert(tmpL->loopSymbol());
tmpL = tmpL->parent;
}

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -9,7 +9,7 @@
#include "directive_omp_parser.h"
#include "directive_parser.h"
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
using std::vector;
using std::map;

View File

@@ -4,7 +4,7 @@
#include <map>
#include <vector>
#include "../Utils/errors.h"
#include "errors.h"
#define SPF_USER_DIR 777
#define SPF_USER_DIR_COPY 999

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstring>
@@ -12,10 +12,10 @@
#include <assert.h>
#include "directive_parser.h"
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../Utils/AstWrapper.h"
#include "../Utils/errors.h"
#include "AstWrapper.h"
#include "errors.h"
using std::string;
using std::vector;

View File

@@ -4,8 +4,8 @@
#include <set>
#include <map>
#include "../Utils/AstWrapper.h"
#include "../GraphLoop/graph_loops.h"
#include "AstWrapper.h"
#include "graph_loops.h"
#include "../Distribution/DvmhDirective.h"
struct DvmDirective

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -16,13 +16,13 @@
#include "../Distribution/Arrays.h"
#include "../Distribution/Distribution.h"
#include "../Distribution/DvmhDirective_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../GraphCall/graph_calls_func.h"
#include "graph_loops_func.h"
#include "graph_calls_func.h"
#include "../Utils/errors.h"
#include "errors.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "directive_parser.h"
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
#include "../Sapfor.h"
#include "directive_creator.h"
#include "insert_directive.h"

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -18,13 +18,13 @@
#include "dvm.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../Utils/types.h"
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "types.h"
#include "errors.h"
#include "SgUtils.h"
#include "../Distribution/Arrays.h"
#include "../GraphCall/graph_calls.h"
#include "../GraphCall/graph_calls_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "graph_calls.h"
#include "graph_calls_func.h"
#include "graph_loops_func.h"
#include "remote_access.h"
using std::vector;

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -17,8 +17,8 @@
#include <assert.h>
#include "../Distribution/Arrays.h"
#include "../GraphCall/graph_calls.h"
#include "../GraphLoop/graph_loops.h"
#include "graph_calls.h"
#include "graph_loops.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "remote_access.h"

View File

@@ -1,19 +1,19 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <set>
#include <map>
#include <string>
#include <vector>
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../GraphCall/graph_calls.h"
#include "../GraphCall/graph_calls_func.h"
#include "errors.h"
#include "utils.h"
#include "graph_loops_func.h"
#include "graph_calls.h"
#include "graph_calls_func.h"
#include "directive_parser.h"
#include "../Distribution/DvmhDirective_func.h"
#include "../Utils/SgUtils.h"
#include "../ExpressionTransform/expr_transform.h"
#include "SgUtils.h"
#include "expr_transform.h"
#include "../CFGraph/CFGraph.h"

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -12,13 +12,13 @@
#include "dvm.h"
#include "../Sapfor.h"
#include "../GraphLoop/graph_loops.h"
#include "../GraphCall/graph_calls_func.h"
#include "graph_loops.h"
#include "graph_calls_func.h"
#include "../SageAnalysisTool/depInterfaceExt.h"
#include "../Utils/SgUtils.h"
#include "../Utils/errors.h"
#include "SgUtils.h"
#include "errors.h"
#include "directive_parser.h"
#include "../ExpressionTransform/expr_transform.h"
#include "expr_transform.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../DirectiveProcessing/directive_omp_parser.h"

View File

@@ -1,7 +1,7 @@
#include "Array.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../GraphCall/graph_calls.h"
#include "errors.h"
#include "utils.h"
#include "graph_calls.h"
using namespace std;

View File

@@ -7,9 +7,9 @@
#include <algorithm>
#include <climits>
#include "DvmhDirectiveBase.h"
#include "../Utils/utils.h"
#include "../Utils/errors.h"
#include "../Utils/json.hpp"
#include "utils.h"
#include "errors.h"
#include "json.hpp"
class Symbol;
class Expression;
@@ -827,4 +827,4 @@ namespace Distribution
#undef PAIR
#undef MAP
#undef SET
#undef TO_STR
#undef TO_STR

View File

@@ -1,8 +1,8 @@
#include "Array.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../GraphCall/graph_calls.h"
#include "../Utils/SgUtils.h"
#include "errors.h"
#include "utils.h"
#include "graph_calls.h"
#include "SgUtils.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
#include "../LoopAnalyzer/loop_analyzer.h"

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <stdio.h>
#include <stdlib.h>
@@ -14,9 +14,9 @@
#include "GraphCSR.h"
#include "Arrays.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../GraphLoop/graph_loops.h"
#include "errors.h"
#include "utils.h"
#include "graph_loops.h"
using std::vector;
using std::set;

View File

@@ -1,7 +1,7 @@
#pragma once
#include "../GraphLoop/graph_loops.h"
#include "../Utils/errors.h"
#include "graph_loops.h"
#include "errors.h"
void createDistributionDirs(DIST::GraphCSR<int, double, attrType> &reducedG, DIST::Arrays<int> &allArrays,
DataDirective &dataDirectives, std::map<std::string, std::vector<Messages>> &allMessages,

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <vector>
#include <algorithm>

View File

@@ -3,7 +3,7 @@
#include <vector>
#include <algorithm>
#include "../Utils/types.h"
#include "types.h"
namespace Distribution
{

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -30,9 +30,9 @@ using namespace std::chrono;
#include "Arrays.h"
#include "Array.h"
#include "Distribution.h"
#include "../Utils/utils.h"
#include "../Utils/errors.h"
#include "../Utils/types.h"
#include "utils.h"
#include "errors.h"
#include "types.h"
#include "../Distribution/Cycle.h"
#include "../VisualizerCalls/get_information.h"
#include "../VisualizerCalls/SendMessage.h"
@@ -455,15 +455,7 @@ namespace Distribution
}
if (needPrint)
{
#if _WIN32
wstring treeM = L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring(k + 1) + L"/" + std::to_wstring(AllCycles.size());
#else
wstring treeM = L"conflict resolution, processing group " + std::to_wstring(k + 1) + L"/" + std::to_wstring(AllCycles.size());
#endif
sendMessage_2lvl(treeM);
}
sendMessage_2lvl(4, k, (int)AllCycles.size());
auto timeR = steady_clock::now();
if (countConflicts != 0)
@@ -516,7 +508,7 @@ namespace Distribution
}
if (needPrint)
sendMessage_2lvl(L"");
sendMessage_2lvl(2);
return make_pair(allOnlySecondType, globalSum);
}
@@ -572,13 +564,7 @@ namespace Distribution
for (int z = 0; z < arraysV.size(); ++z)
{
const DIST::Array *array = arraysV[z];
#ifdef _WIN32
wstring treeM = L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring(z + 1) + L"/" + std::to_wstring(arrays.size());
#else
wstring treeM = L"conflict resolution, processing array " + std::to_wstring(z + 1) + L"/" + std::to_wstring(arrays.size());
#endif
sendMessage_2lvl(treeM);
sendMessage_2lvl(5, z, (int)arrays.size());
vector<vType> verts;
@@ -605,7 +591,7 @@ namespace Distribution
}
}
}
sendMessage_2lvl(L"");
sendMessage_2lvl(2);
}
else
{

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <stdio.h>
#include <stdlib.h>
@@ -7,12 +7,12 @@
#include <string>
#include <algorithm>
#include "../Utils/types.h"
#include "types.h"
#include "DvmhDirective.h"
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "errors.h"
#include "SgUtils.h"
#include "../Sapfor.h"
#include "../GraphCall/graph_calls_func.h"
#include "graph_calls_func.h"
#include "dvm.h"
@@ -346,7 +346,7 @@ static vector<SgExpression*>
{
needToAdd = true;
dim_found = true;
subs[i] = new SgVarRefExp(findSymbolOrCreate(file, currLoop->loopSymbol));
subs[i] = new SgVarRefExp(findSymbolOrCreate(file, currLoop->loopSymbol()));
break;
}
}

View File

@@ -7,9 +7,9 @@
#include "Array.h"
#include "DvmhDirectiveBase.h"
#include "../Utils/AstWrapper.h"
#include "../Utils/types.h"
#include "../Utils/utils.h"
#include "AstWrapper.h"
#include "types.h"
#include "utils.h"
extern int sharedMemoryParallelization;

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <stdio.h>
#include <stdlib.h>
@@ -10,11 +10,11 @@
#include "../Distribution/Array.h"
#include "../Distribution/Arrays.h"
#include "../Distribution/GraphCSR.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../Utils/json.hpp"
#include "errors.h"
#include "utils.h"
#include "json.hpp"
#include "../GraphCall/graph_calls_func.h"
#include "graph_calls_func.h"
using std::vector;
using std::tuple;

View File

@@ -3,7 +3,7 @@
#include <vector>
#include <string>
#include "../Utils/json.hpp"
#include "json.hpp"
typedef enum lang : int { LANG_C, LANG_F } language;
typedef enum dist : int { BLOCK, NONE } distType;

View File

@@ -4,7 +4,7 @@
#include <string>
#include <set>
#include "dvm.h"
#include "../Utils/types.h"
#include "types.h"
SgExpression* createAndSetNext(const int side, const int variant, SgExpression *p);
std::vector<SgExpression*> genSubscripts(const std::vector<std::pair<int, int>> &shadowRenew, const std::vector<std::pair<int, int>> &shadowRenewShifts);

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <algorithm>
#include <string>
@@ -19,8 +19,8 @@ extern int passDone;
#include "Cycle.h"
#include "Arrays.h"
#include "Array.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "errors.h"
#include "utils.h"
#include "../VisualizerCalls/get_information.h"
#include "../VisualizerCalls/SendMessage.h"
@@ -830,13 +830,13 @@ namespace Distribution
color[k] = WHITE;
findFrom = currentV;
#ifdef _WIN32
/*#ifdef _WIN32
if (needPrint)
{
wstring vertexM = std::to_wstring(k + 1) + L"/" + std::to_wstring(vertByTrees[t].size());
sendMessage_2lvl(wstring(L"<22><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ") + wstring(treeM.begin(), treeM.end()) + L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + wstring(vertexM.begin(), vertexM.end()));
}
#endif
#endif*/
__spf_print(PRINT_TIMES && needPrint, "v (tree %d) = %d (with neighb %d) ", t, i, neighbors[i + 1] - neighbors[i]);
activeV[activeCounter++] = currentV;
FindLoop(cyclesTmp[t], currentV, currentV, numbers);
@@ -847,8 +847,8 @@ namespace Distribution
maxLoopDim = wasMaxLoopDim;
}
if (needPrint)
sendMessage_2lvl(L"");
/*if (needPrint)
sendMessage_2lvl(2);*/
}
catch (int code)
{

View File

@@ -5,7 +5,7 @@
#include <set>
#include <tuple>
#include "../Utils/RationalNum.h"
#include "RationalNum.h"
typedef enum links { RR_link, WR_link, WW_link } LinkType;

View File

@@ -1,6 +1,6 @@
#pragma once
#include "../GraphLoop/graph_loops_func.h"
#include "graph_loops_func.h"
#include <string>

View File

@@ -11,7 +11,7 @@
#include "DvmhRegionInserter.h"
#include "DvmhRegions/RegionsMerger.h"
#include "../VerificationCode/verifications.h"
#include "../Transformations/function_purifying.h"
#include "../Transformations/FunctionPurifying/function_purifying.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../DirectiveProcessing/directive_parser.h"

View File

@@ -1,10 +1,10 @@
#pragma once
#include "../GraphCall/graph_calls_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "graph_calls_func.h"
#include "graph_loops_func.h"
#include "expr_transform.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
#include "ReadWriteAnalyzer.h"
#include "DvmhRegion.h"

View File

@@ -1,7 +1,7 @@
#pragma once
#include "../GraphLoop/graph_loops_func.h"
#include "../GraphCall/graph_calls_func.h"
#include "graph_loops_func.h"
#include "graph_calls_func.h"
#include <vector>
#include <string>

View File

@@ -1,7 +1,7 @@
#pragma once
#include "dvm.h"
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
#include "VarUsages.h"
#include <set>
#include <tuple>

View File

@@ -1,7 +1,7 @@
#pragma once
#include "dvm.h"
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
#include <string>
enum class VAR_TYPE { VAR_ARR, VAR_DISTR_ARR, VAR_SCALAR, VAR_ANY, VAR_UNDEFINED };

View File

@@ -5,10 +5,10 @@
#include "./createParallelRegions.h"
#include "../CreateInterTree/CreateInterTree.h"
#include "../GraphCall/graph_calls.h"
#include "graph_calls.h"
#include "./gcov_info.h"
#include "./gCov_parser_func.h"
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <map>
#include <vector>

View File

@@ -1,10 +1,10 @@
#pragma once
#include "../Utils/utils.h"
#include "utils.h"
#include "./gcov_info.h"
#include "../CreateInterTree/CreateInterTree.h"
#include "../GraphCall/graph_calls.h"
#include "graph_calls.h"
#include <map>
#include <vector>

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <stdio.h>
#include <fstream>
@@ -8,7 +8,7 @@
#include "dvm.h"
#include "gCov_parser_func.h"
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
using namespace std;

View File

@@ -5,7 +5,7 @@
#include <vector>
#include "dvm.h"
#include "../Utils/errors.h"
#include "errors.h"
#include "gcov_info.h"
#include "../CreateInterTree/CreateInterTree.h"

View File

@@ -1,10 +1,10 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <iostream>
#include <map>
#include <algorithm>
#include "../Utils/errors.h"
#include "errors.h"
#include "gcov_info.h"

View File

@@ -5,7 +5,7 @@
#include <map>
#include <stdint.h>
#include "../Utils/utils.h"
#include "utils.h"
//make 'class' - need friend for Gcov_info
struct Perform

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -15,13 +15,13 @@
#include "graph_calls_func.h"
#include "../CFGraph/CFGraph.h"
#include "../GraphLoop/graph_loops_func.h"
#include "graph_loops_func.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../Utils/SgUtils.h"
#include "../Utils/json.hpp"
#include "SgUtils.h"
#include "json.hpp"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "expr_transform.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../VerificationCode/verifications.h"

View File

@@ -3,10 +3,10 @@
#include <string>
#include <set>
#include "../Utils/AstWrapper.h"
#include "../Utils/utils.h"
#include "AstWrapper.h"
#include "utils.h"
#include "../DirectiveProcessing/shadow.h"
#include "../GraphLoop/graph_loops.h"
#include "graph_loops.h"
static const char* paramNames[] =
{ "NONE_T", "ARRAY_T", "STRING_ARRAY_T", "STRING_T", "SCALAR_CHAR_T", "SCALAR_BOOL_T", "SCALAR_SHORT_T", "SCALAR_INT_T", "SCALAR_LONG_INT_T",

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -10,10 +10,10 @@
#include <set>
#include <string>
#include "../Utils/errors.h"
#include "errors.h"
#include "graph_calls.h"
#include "../Distribution/Distribution.h"
#include "../Utils/utils.h"
#include "utils.h"
#include "../ParallelizationRegions/ParRegions.h"
using std::vector;

View File

@@ -5,7 +5,7 @@
#include <set>
#include "graph_calls.h"
#include "../GraphLoop/graph_loops.h"
#include "graph_loops.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "Utils/json.hpp"

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -12,26 +12,26 @@
#include "dvm.h"
#include "../Sapfor.h"
#include "../GraphCall/graph_calls_func.h"
#include "graph_calls_func.h"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "expr_transform.h"
#include "../Distribution/GraphCSR.h"
#include "../Distribution/Arrays.h"
#include "../Distribution/Distribution.h"
#include "graph_loops.h"
#include "../Utils/utils.h"
#include "../Utils/SgUtils.h"
#include "utils.h"
#include "SgUtils.h"
#include "../Utils/errors.h"
#include "../Utils/AstWrapper.h"
#include "../Utils/json.hpp"
#include "errors.h"
#include "AstWrapper.h"
#include "json.hpp"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "../Transformations/array_assign_to_loop.h"
#include "../Transformations/VectorAssignToLoop/array_assign_to_loop.h"
using std::vector;
using std::map;
@@ -520,7 +520,7 @@ static void findArrayRef(SgExpression *exp, bool isWirte, set<DIST::Array*>& use
{
if (exp)
{
if (exp->variant() == ARRAY_REF)
if (isArrayRef(exp))
{
DIST::Array *arrayRef = NULL;
SgSymbol *symbS = OriginalSymbol(exp->symbol());
@@ -699,7 +699,12 @@ void loopGraphAnalyzer(SgFile *file, vector<LoopGraph*> &loopGraph, const vector
newLoop->hasPrints = hasThisIds(st, newLoop->linesOfIO, { WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT, PRINT_STAT } ); // FORMAT_STAT
newLoop->hasStops = hasThisIds(st, newLoop->linesOfStop, { STOP_STAT, PAUSE_NODE });
newLoop->hasDvmIntervals = hasThisIds(st, tmpLines, { DVM_INTERVAL_DIR, DVM_ENDINTERVAL_DIR, DVM_EXIT_INTERVAL_DIR });
newLoop->isFor = isSgForStmt(st) ? true : false;
if (isSgForStmt(st))
newLoop->loopType = LoopType::FOR;
else if (isSgWhileStmt(st))
newLoop->loopType = LoopType::WHILE;
else
newLoop->loopType = LoopType::NONE;
newLoop->inCanonicalFrom = isSgForStmt(st) ? true : false;
newLoop->hasSubstringRefs = hasSubstringRef(st);
@@ -777,7 +782,7 @@ void loopGraphAnalyzer(SgFile *file, vector<LoopGraph*> &loopGraph, const vector
newLoop->startEndExpr = std::make_pair((Expression*)NULL, (Expression*)NULL);
newLoop->loop = new Statement(st);
newLoop->loopSymbol = st->symbol() ? st->symbol()->identifier() : "unknown";
newLoop->loopSymbols.addMainVar(st->symbol() ? st->symbol()->identifier() : "unknown");
findArrayRefs(newLoop);
SgStatement *lexPrev = st->lexPrev();

View File

@@ -5,8 +5,8 @@
#include <map>
#include <set>
#include "../Utils/errors.h"
#include "../Utils/types.h"
#include "errors.h"
#include "types.h"
#include "../Distribution/DvmhDirective.h"
#include "../Distribution/Distribution.h"
@@ -25,6 +25,33 @@ namespace DIST = Distribution;
void getRealArrayRefs(DIST::Array* addTo, DIST::Array* curr, std::set<DIST::Array*>& realArrayRefs, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
void getAllArrayRefs(DIST::Array* addTo, DIST::Array* curr, std::set<DIST::Array*>& realArrayRefs, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
enum class LoopType { NONE, FOR, WHILE, IMPLICIT };
struct InductiveVariables
{
private:
std::string mainVar;
std::set<std::string> allVars;
public:
InductiveVariables() { }
explicit InductiveVariables(const std::string& mainVar, const std::set<std::string>& allVars) : mainVar(mainVar), allVars(allVars) { };
std::string getMainVar() const { return mainVar; }
std::set<std::string> getAllVars() const { return allVars; }
void addVar(const std::string& var) { allVars.insert(var); }
void addMainVar(const std::string& var) { mainVar = var; allVars.insert(var); }
void replaceMainVar(const std::string& var)
{
allVars.erase(mainVar);
addMainVar(var);
}
};
struct LoopGraph
{
private:
@@ -70,7 +97,7 @@ public:
calculatedCountOfIters = 0;
executionTimeInSec = -1.0;
inDvmhRegion = 0;
isFor = false;
loopType = LoopType::NONE;
inCanonicalFrom = false;
hasAccessToSubArray = false;
hasSubstringRefs = false;
@@ -113,21 +140,24 @@ public:
{
return hasUnknownArrayDep || hasUnknownScalarDep || hasGoto || hasPrints || (hasConflicts.size() != 0) || hasStops || hasNonPureProcedures ||
hasUnknownArrayAssigns || hasNonRectangularBounds || hasIndirectAccess || hasWritesToNonDistribute || hasDifferentAlignRules || hasDvmIntervals ||
!isFor || lastprivateScalars.size() || hasAccessToSubArray || hasSubstringRefs;
!isFor() || lastprivateScalars.size() || hasAccessToSubArray || hasSubstringRefs;
}
bool hasLimitsToSplit() const
{
return hasGoto || hasStops || !isFor || hasPrints;
return hasGoto || hasStops || !isFor() || hasPrints;
}
bool hasLimitsToCombine() const
{
return hasGoto || hasStops || !isFor || hasPrints || linesOfCycle.size();
return hasGoto || hasStops || !isFor() || hasPrints || linesOfCycle.size();
}
void addConflictMessages(std::vector<Messages> *messages)
{
if (messages == NULL)
return;
const int line = altLineNum > 0 ? altLineNum : lineNum;
if (hasUnknownArrayDep)
messages->push_back(Messages(NOTE, line, R113, L"unknown array dependency prevents parallelization of this loop", 3006));
@@ -168,7 +198,7 @@ public:
if (hasDvmIntervals)
messages->push_back(Messages(NOTE, line, R145, L"DVM intervals prevent parallelization of this loop", 3006));
if (!isFor || !inCanonicalFrom)
if (!isFor() || !inCanonicalFrom)
messages->push_back(Messages(NOTE, line, R178, L"This type of loop is not supported by the system", 3006));
if (lastprivateScalars.size())
@@ -393,6 +423,14 @@ public:
void* getRealStat(const char* file) const;
bool isFor() const { return loopType == LoopType::FOR; }
bool isWhile() const { return loopType == LoopType::WHILE; }
bool isImplicit() const { return loopType == LoopType::IMPLICIT; }
std::string loopSymbol() const { return loopSymbols.getMainVar(); }
public:
int lineNum;
int altLineNum;
@@ -407,7 +445,7 @@ public:
int startVal, endVal, stepVal;
std::tuple<Expression*, Expression*, Expression*> startEndStepVals;
std::string loopSymbol;
InductiveVariables loopSymbols;
std::pair<Expression*, Expression*> startEndExpr;
bool hasGoto;
@@ -448,7 +486,7 @@ public:
bool hasSubstringRefs;
bool isFor;
LoopType loopType;
bool inCanonicalFrom;

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -23,8 +23,8 @@ using std::make_pair;
using std::get;
#include "graph_loops.h"
#include "../GraphCall/graph_calls_func.h"
#include "../Utils/errors.h"
#include "graph_calls_func.h"
#include "errors.h"
#include "../Distribution/Distribution.h"
#include "../Distribution/CreateDistributionDirs.h"
#include "../ParallelizationRegions/ParRegions.h"
@@ -551,7 +551,7 @@ void addToDistributionGraph(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>
continue;
}
if (!loopAccess.first->isFor)
if (!loopAccess.first->isFor())
continue;
DIST::GraphCSR<int, double, attrType>& G = currReg->GetGraphToModify();
@@ -775,7 +775,7 @@ static void isAllOk(const vector<LoopGraph*> &loops, vector<Messages> &currMessa
{
if (loops[i]->region)
{
if (loops[i]->countOfIters == 0 && loops[i]->region && loops[i]->isFor)
if (loops[i]->countOfIters == 0 && loops[i]->region && loops[i]->isFor())
{
wstring bufE, bufR;
__spf_printToLongBuf(bufE, L" Can not calculate count of iterations for this loop, information about iterations in all loops in parallel regions '%s' will be ignored",

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -8,8 +8,8 @@
#include <set>
#include "dvm.h"
#include "../Utils/SgUtils.h"
#include "../Utils/errors.h"
#include "SgUtils.h"
#include "errors.h"
using std::set;
using std::pair;

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -20,8 +20,8 @@
#include "dvm.h"
#include "loop_analyzer.h"
#include "../Utils/utils.h"
#include "../Utils/SgUtils.h"
#include "utils.h"
#include "SgUtils.h"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../SageAnalysisTool/depGraph.h"
#include "../SageAnalysisTool/OmegaForSage/include/lang-interf.h"

View File

@@ -0,0 +1,281 @@
#include <map>
#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <stack>
#include "../CFGraph/IR.h"
#include "GraphCall/graph_calls.h"
#include "implicit_loops_analyzer.h"
using namespace std;
using namespace SAPFOR;
using std::map;
using std::set;
using std::vector;
using std::pair;
using std::string;
using std::cout;
using std::endl;
using std::make_pair;
using std::to_string;
enum VisitState { UNVISITED = 0, VISITING = 1, VISITED = 2 };
void dfs(SAPFOR::BasicBlock* block,
std::map<int, int>& visit,
std::vector<std::pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>>& startAndEnd,
SAPFOR::BasicBlock* prev)
{
if (!block)
return;
int id = block->getNumber();
if (visit[id] == VISITING) {
startAndEnd.emplace_back(prev, block);
return;
}
if (visit[id] == VISITED)
return;
visit[id] = VISITING;
for (auto next : block->getNext())
dfs(next, visit, startAndEnd, block);
visit[id] = VISITED;
}
void getLoopBody(SAPFOR::BasicBlock* loopHeader, const std::set<SAPFOR::BasicBlock*>& loopExits, std::vector<SAPFOR::BasicBlock*>& loopBody)
{
std::set<SAPFOR::BasicBlock*> visited;
std::stack<SAPFOR::BasicBlock*> stack;
stack.push(loopHeader);
while (!stack.empty())
{
auto block = stack.top();
stack.pop();
if (visited.count(block))
continue;
visited.insert(block);
for (auto succ : block->getNext())
{
if (loopExits.count(succ))
continue;
if (!visited.count(succ))
stack.push(succ);
}
}
std::set<SAPFOR::BasicBlock*> backReachable;
std::stack<SAPFOR::BasicBlock*> reverseStack;
reverseStack.push(loopHeader);
while (!reverseStack.empty())
{
auto block = reverseStack.top();
reverseStack.pop();
if (backReachable.count(block))
continue;
backReachable.insert(block);
for (auto pred : block->getPrev())
if (visited.count(pred) && !backReachable.count(pred))
reverseStack.push(pred);
}
for (auto block : visited)
if (backReachable.count(block))
loopBody.push_back(block);
}
SAPFOR::Instruction* findDef(const SAPFOR::Argument* arg,
const std::vector<SAPFOR::BasicBlock*>& blocks)
{
if (!arg)
return nullptr;
std::string argName = arg->getValue();
for (auto block : blocks) {
for (auto instrWrapper : block->getInstructions()) {
auto instr = instrWrapper->getInstruction();
if (!instr)
continue;
auto res = instr->getResult();
if (!res)
continue;
if (res->getValue() == argName)
return instr;
}
}
return nullptr;
}
const SAPFOR::Argument* getBaseSource(const SAPFOR::Argument* arg, const std::vector<SAPFOR::BasicBlock*>& blocks)
{
while (arg && arg->getType() == CFG_ARG_TYPE::REG)
{
auto defInstr = findDef(arg, blocks);
if (!defInstr)
break;
auto defOp = defInstr->getOperation();
if (defOp == CFG_OP::ASSIGN)
arg = defInstr->getArg1();
else
break;
}
return arg;
}
void findInductiveVars(const std::vector<SAPFOR::BasicBlock*>& Loopblocks, const std::vector<SAPFOR::BasicBlock*>& blocks)
{
std::set<std::string> inductiveVars;
for (auto block : Loopblocks)
{
for (auto instrWrapper : block->getInstructions())
{
auto instr = instrWrapper->getInstruction();
if (!instr)
continue;
auto res = instr->getResult();
if (!res || res->getType() != SAPFOR::CFG_ARG_TYPE::VAR)
continue;
while (instr && instr->getOperation() == CFG_OP::ASSIGN)
instr = findDef(instr->getArg1(), blocks);
if (!instr || instr->getOperation() != CFG_OP::ADD && instr->getOperation() != CFG_OP::SUBT)
continue;
auto arg1 = getBaseSource(instr->getArg1(), blocks);
auto arg2 = getBaseSource(instr->getArg2(), blocks);
bool ok = false;
if (res->getValue() == arg1->getValue() && arg2->getType() == CFG_ARG_TYPE::CONST)
ok = true;
else if (res->getValue() == arg2->getValue() && arg1->getType() == CFG_ARG_TYPE::CONST)
ok = true;
if (ok)
inductiveVars.insert(res->getValue());
}
}
if (inductiveVars.empty())
std::cout << "No inductive variables found." << std::endl;
else
for (const auto& var : inductiveVars)
std::cout << "Inductive variable: " << var << std::endl;
}
Instruction* findInstructionAfterLoop(const std::vector<SAPFOR::BasicBlock*>& loopBody)
{
std::set<SAPFOR::BasicBlock*> loopSet(loopBody.begin(), loopBody.end());
for (auto block : loopBody)
{
for (auto succ : block->getNext())
{
if (!loopSet.count(succ))
{
auto instructions = succ->getInstructions();
if (instructions.empty())
std::cout << "Exit block has no instructions." << std::endl;
for (auto wrapper : instructions)
if (auto instr = wrapper->getInstruction())
return instr;
}
}
}
return nullptr;
}
void findImplicitLoops(const std::vector<SAPFOR::BasicBlock*>& irSSA, const std::vector<LoopGraph*> loopGraph)
{
map<int, int> visited;
for (auto i : irSSA)
visited[i->getNumber()] = UNVISITED;
vector<pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>> startAndEnd;
dfs(irSSA[0], visited, startAndEnd, NULL);
vector<LoopGraph*> loops;
for (auto& [tail, header] : startAndEnd)
{
set<SAPFOR::BasicBlock*> loopExits;
for (auto succ : tail->getNext())
if (succ != header)
loopExits.insert(succ);
vector<SAPFOR::BasicBlock*> loopBody;
getLoopBody(header, loopExits, loopBody);
findInductiveVars(loopBody, irSSA);
Instruction* instructionAfterLoop = findInstructionAfterLoop(loopBody);
if (instructionAfterLoop == NULL)
{
cout << "Warning: instruction after loop not found!" << endl;
continue;
}
auto firstInstruction = header->getInstructions()[0]->getInstruction();
auto lastInstruction = tail->getInstructions().back()->getInstruction();
auto tmpLoop = new LoopGraph();
tmpLoop->lineNum = firstInstruction->getOperator()->lineNumber();
tmpLoop->lineNumAfterLoop = instructionAfterLoop->getOperator()->lineNumber();
if (firstInstruction->getOperator()->variant() == FOR_NODE)
{
SgForStmt* stmt = isSgForStmt(firstInstruction->getOperator());
cout << "for loop" << endl;
}
else if (firstInstruction->getOperator()->variant() == WHILE_NODE)
{
SgWhileStmt* stmt = isSgWhileStmt(firstInstruction->getOperator());
cout << (stmt->conditional() == NULL ? "infinit" : "") << "while loop" << endl;
}
else if (firstInstruction->getOperator()->variant() == DO_WHILE_NODE)
{
SgWhileStmt* stmt = isSgDoWhileStmt(firstInstruction->getOperator());
cout << "do while loop" << endl;
}
else if (firstInstruction->getOperator()->variant() == LOOP_NODE)
{
cout << "not known loop" << endl;
}
else
{
cout << "goto loop" << endl;
}
cout << "loop start line " << tmpLoop->lineNum << endl;
cout << "after loop line " << tmpLoop->lineNumAfterLoop << endl << endl;
loops.push_back(tmpLoop);
}
}

View File

@@ -0,0 +1,7 @@
#pragma once
#include <map>
#include "../CFGraph/CFGraph.h"
#include "../GraphCall/graph_calls.h"
void findImplicitLoops(const std::vector<SAPFOR::BasicBlock*>& fullIR_SSA, const std::vector<LoopGraph*> loopGraph);

View File

@@ -18,7 +18,7 @@
#include <tuple>
#include <stack>
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#if _WIN32 && NDEBUG && __BOOST
#include <boost/thread.hpp>
@@ -30,25 +30,25 @@ extern int passDone;
#include "../Distribution/Arrays.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "../Utils/errors.h"
#include "errors.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DirectiveProcessing/directive_creator.h"
#include "../Utils/SgUtils.h"
#include "../Utils/AstWrapper.h"
#include "SgUtils.h"
#include "AstWrapper.h"
#include "../GraphCall/graph_calls_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "graph_calls_func.h"
#include "graph_loops_func.h"
#include "../ParallelizationRegions/ParRegions_func.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "expr_transform.h"
#include "../SageAnalysisTool/depInterfaceExt.h"
#include "../VisualizerCalls/get_information.h"
#include "../VisualizerCalls/SendMessage.h"
#include "../Transformations/enddo_loop_converter.h"
#include "../Transformations/LoopEndDoConverter/enddo_loop_converter.h"
#include "../DirectiveProcessing/remote_access.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
@@ -1633,17 +1633,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
createNeededException();
string fName = file->functions(i)->symbol()->identifier();
#if _WIN32
if (file->functions(i)->variant() != MODULE_STMT)
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(fName.begin(), fName.end()) + L"'");
else
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(fName.begin(), fName.end()) + L"'");
#else
if (file->functions(i)->variant() != MODULE_STMT)
sendMessage_2lvl(wstring(L"processing function '") + wstring(fName.begin(), fName.end()) + L"'");
else
sendMessage_2lvl(wstring(L"processing module '") + wstring(fName.begin(), fName.end()) + L"'");
#endif
sendMessage_2lvl(0, (file->functions(i)->variant() != MODULE_STMT), fName);
set<SgSymbol*> delcsSymbViewed;
set<SgStatement*> delcsStatViewed;
@@ -1710,7 +1700,10 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
map<string, pair<SgSymbol*, SgStatement*>> notMappedDistributedArrays;
set<string> mappedDistrbutedArrays;
const ParallelRegionLines* prevParLines = NULL;
double prevLinesWeight = 1.0;
double currentWeight = 1.0;
while (st != lastNode)
{
createNeededException();
@@ -1733,13 +1726,31 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
}
const int currentLine = st->lineNumber() < -1 ? st->localLineNumber() : st->lineNumber();
ParallelRegion *currReg = getRegionByLine(regions, st->fileName(), currentLine);
auto regAndLines = getRegionAndLinesByLine(regions, st->fileName(), currentLine);
auto *currReg = regAndLines.first;
auto *parLines = regAndLines.second;
if (currReg == NULL)
{
st = st->lexNext();
continue;
}
if (parLines != prevParLines)
{
prevParLines = parLines;
auto newParLinesWeight = parLines ? parLines->weight : 1.0;
if (prevParLines)
currentWeight /= prevLinesWeight;
if (parLines)
currentWeight *= newParLinesWeight;
prevLinesWeight = newParLinesWeight;
prevParLines = parLines;
}
if (isSgExecutableStatement(st) == NULL)
delcsStatViewed.insert(st);
else if (!sharedMemoryParallelization &&
@@ -2167,11 +2178,8 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
if (!skipDeps)
{
string fName = file->functions(i)->symbol()->identifier();
#ifdef _WIN32
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
#else
sendMessage_2lvl(wstring(L"processing loop ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
#endif
sendMessage_2lvl(1, idx, (int)convertedLoopInfo.size());
tryToFindDependencies(loop.first, allLoops, funcWasInit, file, regions, currMessages, collection, funcByName, defUseByPlace);
}
}
@@ -2191,7 +2199,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
LoopGraph *tmpLoop = new LoopGraph();
tmpLoop->region = reg;
tmpLoop->isFor = true;
tmpLoop->loopType = LoopType::FOR;
tmpLoops.push_back(tmpLoop);
@@ -2319,7 +2327,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> &regions, map<tuple<int,
if (parallizeFreeLoops)
selectFreeLoopsForParallelization(loopsForFunction, funcName, (regime == DATA_DISTR), regions, messagesForFile);
}
sendMessage_2lvl(L"");
sendMessage_2lvl(2);
}
else if (regime == COMP_DISTR)
{

View File

@@ -5,12 +5,12 @@
#include <tuple>
#include <vector>
#include <set>
#include "../GraphLoop/graph_loops.h"
#include "../GraphCall/graph_calls.h"
#include "graph_loops.h"
#include "graph_calls.h"
#include "../ParallelizationRegions/ParRegions.h"
#include "../SageAnalysisTool/depInterfaceExt.h"
#include "../Utils/AstWrapper.h"
#include "../Utils/SgUtils.h"
#include "AstWrapper.h"
#include "SgUtils.h"
#include "dvm.h"

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <stdio.h>
#include <stdlib.h>
@@ -10,12 +10,12 @@
#include "dvm.h"
#include "ParRegions.h"
#include "../Utils/utils.h"
#include "../Utils/SgUtils.h"
#include "../GraphCall/graph_calls_func.h"
#include "../GraphLoop/graph_loops.h"
#include "utils.h"
#include "SgUtils.h"
#include "graph_calls_func.h"
#include "graph_loops.h"
#include "../Distribution/Distribution.h"
#include "../ExpressionTransform/expr_transform.h"
#include "expr_transform.h"
using std::vector;
using std::string;
@@ -93,8 +93,10 @@ static inline SgStatement* getParentStat(SgStatement *st)
return iterator;
}
static void updateRegionInfo(SgStatement *st, map<string, pair<Statement*, Statement*>> &startEnd, map<string, pair<int, int>> &lines_,
set<string> &funcCallFromReg, const map<string, FuncInfo*> &mapFuncs)
static void updateRegionInfo(SgStatement *st, map<string, pair<Statement*, Statement*>> &startEnd,
map<string, pair<int, int>> &lines_,
map<string, map<string, set<int>>> &funcCallFromReg,
const map<string, FuncInfo*> &mapFuncs)
{
string containsPrefix = "";
SgStatement *st_ps = getParentStat(st);
@@ -103,17 +105,26 @@ static void updateRegionInfo(SgStatement *st, map<string, pair<Statement*, State
containsPrefix = st_ps->symbol()->identifier() + string(".");
extendRegionInfo(st, startEnd, lines_);
set<string> callsFromStatement;
if (st->variant() == PROC_STAT)
{
string fullName = st->symbol()->identifier();
//check contains
if (mapFuncs.find(containsPrefix + fullName) != mapFuncs.end())
fullName = containsPrefix + fullName;
funcCallFromReg.insert(fullName);
callsFromStatement.insert(fullName);
}
for (int z = 0; z < 3; ++z)
findFuncCalls(st->expr(z), funcCallFromReg, containsPrefix, mapFuncs);
findFuncCalls(st->expr(z), callsFromStatement, containsPrefix, mapFuncs);
string filename = st->fileName();
int line = st->lineNumber();
for (const auto &func_name : callsFromStatement)
funcCallFromReg[func_name][filename].insert(line);
}
static void fillArrayNamesInReg(set<string> &usedArrayInRegion, SgExpression *exp)
@@ -318,8 +329,9 @@ void fillRegionLines(SgFile *file, vector<ParallelRegion*> &regions, vector<Mess
string regionName = "";
map<string, pair<Statement*, Statement*>> startEnd;
map<string, pair<int, int>> lines_;
set<string> funcCallFromReg;
map<string, map<string, set<int>>> funcCallFromReg;
bool regionStarted = false;
double fragmentWeight = 1.0;
vector<SgStatement*> toDel;
for (int i = 0; i < funcNum; ++i)
@@ -368,6 +380,33 @@ void fillRegionLines(SgFile *file, vector<ParallelRegion*> &regions, vector<Mess
itFunc->second->callRegions.insert(0);
}
}
// parse SPF_APPLY_FRAGMENT clause
auto *apply_fragment = data->expr(1);
fragmentWeight = 1.0;
while (apply_fragment)
{
auto *curr = apply_fragment->lhs();
if (curr)
{
__spf_print(1, "%s %d\n", curr->unparse(), curr->variant());
if (curr->variant() == SPF_WEIGHT_OP)
{
if (curr->lhs() &&
isSgValueExp(curr->lhs()) &&
isSgValueExp(curr->lhs())->doubleValue())
{
fragmentWeight = strtod(isSgValueExp(curr->lhs())->doubleValue(), NULL);
__spf_print(1, "->> %lf\n", fragmentWeight);
}
else
__spf_print(1, "WEIGHT clause without double argument\n");
}
}
apply_fragment = apply_fragment->rhs();
}
}
if (next && next->variant() == SPF_END_PARALLEL_REG_DIR)
@@ -400,10 +439,12 @@ void fillRegionLines(SgFile *file, vector<ParallelRegion*> &regions, vector<Mess
extendRegionInfo(st, startEnd, lines_, true);
for (auto itRegInfo = startEnd.begin(); itRegInfo != startEnd.end(); ++itRegInfo)
currReg->AddLines(lines_[itRegInfo->first], itRegInfo->first, &itRegInfo->second);
currReg->AddLines(lines_[itRegInfo->first], itRegInfo->first, &itRegInfo->second, fragmentWeight);
for (auto &func : funcCallFromReg)
currReg->AddFuncCalls(func);
for (auto &by_func : funcCallFromReg)
for (auto &by_file : by_func.second)
for(auto &by_line : by_file.second)
currReg->AddFuncCalls(by_func.first, by_file.first, by_line);
filterUserDirectives(currReg, usedArrayInRegion, userDvmRedistrDirs, userDvmRealignDirs, userDvmShadowDirs);
currReg->AddUserDirectives(userDvmRealignDirs, DVM_REALIGN_DIR);
@@ -496,34 +537,48 @@ void fillRegionLinesStep2(vector<ParallelRegion*> &regions, const map<string, ve
{
if (regions[i]->GetName() != "DEFAULT")
for (auto &func : regions[i]->GetFuncCalls())
setExplicitFlag(func, funcMap);
setExplicitFlag(func.first, funcMap);
}
for (int i = 0; i < regions.size(); ++i)
{
if (regions[i]->GetName() != "DEFAULT")
{
set<string> uniqFuncCalls;
for (auto &elem : regions[i]->GetFuncCalls())
uniqFuncCalls.insert(elem);
map<string, double> uniqFuncCalls;
map<string, map<string, set<int>>> callPlaces;
for (auto &elem : regions[i]->GetFuncCalls())
{
double max_weight = 0;
for (auto* fragment : elem.second)
if (fragment->weight > max_weight)
max_weight = fragment->weight;
uniqFuncCalls[elem.first] = max_weight;
}
bool wasChanged = true;
auto funcsBefore = uniqFuncCalls;
bool wasChanged = 1;
while (wasChanged)
{
wasChanged = 0;
wasChanged = false;
auto updated = uniqFuncCalls;
for (auto &uniqF : uniqFuncCalls)
{
auto func = funcMap.find(uniqF);
auto func = funcMap.find(uniqF.first);
if (func != funcMap.end())
{
for (auto &calls : func->second->callsFrom)
for (auto &call : func->second->callsFromDetailed)
{
auto it = uniqFuncCalls.find(calls);
if (it == uniqFuncCalls.end())
{
uniqFuncCalls.insert(it, calls);
wasChanged = 1;
}
auto it = updated.find(call.detailCallsFrom.first);
if (it == updated.end())
updated.insert({call.detailCallsFrom.first, uniqF.second});
else
it->second = std::max(it->second, uniqF.second);
callPlaces[call.detailCallsFrom.first][func->second->fileName].insert(call.detailCallsFrom.second);
}
}
}
@@ -532,21 +587,27 @@ void fillRegionLinesStep2(vector<ParallelRegion*> &regions, const map<string, ve
string toPrint = "";
for (auto &elem : uniqFuncCalls)
{
auto it = funcMap.find(elem);
auto it = funcMap.find(elem.first);
if (it != funcMap.end())
{
regions[i]->AddLines(it->second->linesNum, it->second->fileName);
regions[i]->AddFuncCallsToAllCalls(it->second);
regions[i]->AddLines(it->second->linesNum, it->second->fileName, NULL, elem.second);
if (it->second->inRegion == 0)
it->second->inRegion = 2;
it->second->callRegions.insert(i);
toPrint += elem + " ";
toPrint += elem.first + " ";
}
}
for (auto &elem : callPlaces)
{
for (const auto &byFile : elem.second)
for (auto byLine : byFile.second)
regions[i]->AddFuncCalls(elem.first, byFile.first, byLine);
}
if (toPrint != "")
__spf_print(1, "[%s]: funcs: %s\n", regions[i]->GetName().c_str(), toPrint.c_str());
}

View File

@@ -9,17 +9,17 @@
#include "../Distribution/DvmhDirective.h"
#include "../Distribution/GraphCSR.h"
#include "../Distribution/Distribution.h"
#include "../Utils/AstWrapper.h"
#include "AstWrapper.h"
#include "../Utils/json.hpp"
#include "json.hpp"
#if __SPF
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
#endif
struct ParallelRegionLines
{
ParallelRegionLines()
ParallelRegionLines(double weight = 1.0) : weight(weight)
{
lines = std::make_pair(-1, -1);
stats = std::make_pair<Statement*, Statement*>(NULL, NULL);
@@ -27,14 +27,15 @@ struct ParallelRegionLines
intervalAfter = std::make_pair<Statement*, Statement*>(NULL, NULL);
}
ParallelRegionLines(const std::pair<int, int> &lines) : lines(lines)
ParallelRegionLines(const std::pair<int, int> &lines, double weight = 1.0) : lines(lines), weight(weight)
{
stats = std::make_pair<Statement*, Statement*>(NULL, NULL);
intervalBefore = std::make_pair<Statement*, Statement*>(NULL, NULL);
intervalAfter = std::make_pair<Statement*, Statement*>(NULL, NULL);
}
ParallelRegionLines(const std::pair<int, int> &lines, const std::pair<Statement*, Statement*> stats) : lines(lines), stats(stats)
ParallelRegionLines(const std::pair<int, int> &lines, const std::pair<Statement*, Statement*> stats, double weight = 1.0)
: lines(lines), stats(stats), weight(weight)
{
intervalBefore = std::make_pair<Statement*, Statement*>(NULL, NULL);
intervalAfter = std::make_pair<Statement*, Statement*>(NULL, NULL);
@@ -62,6 +63,8 @@ struct ParallelRegionLines
// <start, end> interval
std::pair<Statement*, Statement*> intervalBefore;
std::pair<Statement*, Statement*> intervalAfter;
double weight; // weight of the fragment among all fragments of this region
};
#if __SPF
@@ -116,7 +119,7 @@ public:
currentVariant = copy.currentVariant;
}
int AddLines(const std::pair<int, int> &linesToAdd, const std::string &file, const std::pair<Statement*, Statement*> *startEnd = NULL)
int AddLines(const std::pair<int, int> &linesToAdd, const std::string &file, const std::pair<Statement*, Statement*> *startEnd = NULL, double weight = 1.0)
{
if (linesToAdd.first > linesToAdd.second)
return -1;
@@ -126,17 +129,29 @@ public:
it = lines.insert(it, make_pair(file, std::vector<ParallelRegionLines>()));
if (startEnd)
it->second.push_back(ParallelRegionLines(linesToAdd, *startEnd));
it->second.push_back(ParallelRegionLines(linesToAdd, *startEnd, weight));
else
it->second.push_back(ParallelRegionLines(linesToAdd));
it->second.push_back(ParallelRegionLines(linesToAdd, weight));
return 0;
}
void AddFuncCalls(const std::string &func) { functionsCall.insert(func); }
void AddFuncCalls(const std::string &func, const std::string &file, const int line)
{
auto *found_lines = GetLinesByLine(file, line);
if (found_lines)
functionsCall[func].insert(found_lines);
}
#if __SPF
void AddFuncCallsToAllCalls(FuncInfo *func) { allFunctionsCall.insert(func); }
void AddFuncCallsToAllCalls(FuncInfo *func, const std::string &file, const int line)
{
auto *found_lines = GetLinesByLine(file, line);
if (found_lines)
allFunctionsCall[func].insert(found_lines);
}
#endif
uint64_t GetId() const { return regionId; }
@@ -176,10 +191,10 @@ public:
const DataDirective& GetDataDir() const { return dataDirectives; }
DataDirective& GetDataDirToModify() { return dataDirectives; }
const std::set<std::string>& GetFuncCalls() const { return functionsCall; }
const std::map<std::string, std::set<const ParallelRegionLines*>>& GetFuncCalls() const { return functionsCall; }
#if __SPF
const std::set<FuncInfo*>& GetAllFuncCalls() const { return allFunctionsCall; }
const std::map<FuncInfo*, std::set<const ParallelRegionLines*>>& GetAllFuncCalls() const { return allFunctionsCall; }
const std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>>& GetUsedLocalArrays() const { return usedLocalArrays; }
const std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>>& GetUsedCommonArrays() const { return usedCommonArrays; }
@@ -218,7 +233,7 @@ public:
}
#endif
bool HasThisLine(const int line, const std::string &file) const
bool HasThisLine(const int line, const std::string &file, const ParallelRegionLines** found = nullptr) const
{
bool retVal = false;
auto it = lines.find(file);
@@ -229,6 +244,9 @@ public:
if (it->second[i].lines.first <= line && it->second[i].lines.second >= line)
{
retVal = true;
if (found)
*found = &(it->second[i]);
break;
}
}
@@ -292,7 +310,7 @@ public:
fprintf(fileOut, " originalName '%s'\n", originalName.c_str());
fprintf(fileOut, " functions call from %d:\n", (int)functionsCall.size());
for (auto &func : functionsCall)
fprintf(fileOut, " '%s'\n", func.c_str());
fprintf(fileOut, " '%s'\n", func.first.c_str());
fprintf(fileOut, " total lines %d:\n", (int)lines.size());
for (auto &line : lines)
{
@@ -362,11 +380,11 @@ private:
std::string originalName;
// file -> lines info
std::map<std::string, std::vector<ParallelRegionLines>> lines;
std::set<std::string> functionsCall;
std::map<std::string, std::set<const ParallelRegionLines*>> functionsCall; // func name -> fragments with calls
#if __SPF
// for RESOLVE_PAR_REGIONS
std::set<FuncInfo*> allFunctionsCall;
std::map<FuncInfo*, std::set<const ParallelRegionLines*>> allFunctionsCall; // function -> fragments with calls
std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>> usedLocalArrays; // func -> array -> lines
std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>> usedCommonArrays; // func -> array -> lines
//
@@ -408,4 +426,5 @@ private:
ParallelRegion* getRegionById(const std::vector<ParallelRegion*>& regions, const uint64_t regionId);
ParallelRegion* getRegionByName(const std::vector<ParallelRegion*>& regions, const std::string& regionName);
ParallelRegion* getRegionByLine(const std::vector<ParallelRegion*>& regions, const std::string& file, const int line);
std::pair<ParallelRegion*, const ParallelRegionLines*> getRegionAndLinesByLine(const std::vector<ParallelRegion*>& regions, const std::string& file, const int line);
std::set<ParallelRegion*> getAllRegionsByLine(const std::vector<ParallelRegion*>& regions, const std::string& file, const int line);

View File

@@ -1,8 +1,8 @@
#pragma once
#include "ParRegions.h"
#include "../GraphCall/graph_calls.h"
#include "../GraphLoop/graph_loops.h"
#include "graph_calls.h"
#include "graph_loops.h"
void fillRegionLines(SgFile *file, std::vector<ParallelRegion*> &regions, std::vector<Messages>& messagesForFile, std::vector<LoopGraph*> *loops = NULL, std::vector<FuncInfo*> *funcs = NULL);
void fillRegionLinesStep2(std::vector<ParallelRegion*> &regions, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, std::map<std::string, std::vector<LoopGraph*>> *loopGraph = NULL);

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <map>
#include <string>

View File

@@ -1,7 +1,7 @@
#pragma once
#include "ParRegions.h"
#include "../Utils/SgUtils.h"
#include "../Utils/errors.h"
#include "SgUtils.h"
#include "errors.h"
bool expandExtractReg(const std::string &fileName, const int startLine, const int endLine, const std::vector<ParallelRegion*> &regions, std::vector<Messages> &messagesForFile, const bool toDelete = false);

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <string>
#include <vector>
@@ -11,14 +11,14 @@
#include "ParRegions_func.h"
#include "resolve_par_reg_conflicts.h"
#include "../GraphCall/graph_calls_func.h"
#include "../GraphLoop/graph_loops_func.h"
#include "graph_calls_func.h"
#include "graph_loops_func.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../DirectiveProcessing/directive_creator.h"
#include "../DirectiveProcessing/insert_directive.h"
#include "../Utils/SgUtils.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../Transformations/function_purifying.h"
#include "SgUtils.h"
#include "expr_transform.h"
#include "../Transformations/FunctionPurifying/function_purifying.h"
using std::map;
using std::pair;

View File

@@ -1,9 +1,9 @@
#pragma once
#include "ParRegions.h"
#include "../Utils/SgUtils.h"
#include "../Utils/errors.h"
#include "../GraphCall/graph_calls.h"
#include "SgUtils.h"
#include "errors.h"
#include "graph_calls.h"
void fillRegionIntervals(std::vector<ParallelRegion*> &regions);
void fillRegionArrays(std::vector<ParallelRegion*> &regions, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo, const std::map<std::string, CommonBlock*> &commonBlocks);

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -16,11 +16,11 @@
#include "../DynamicAnalysis/gcov_info.h"
#include "../DynamicAnalysis/gCov_parser_func.h"
#include "PredictScheme.h"
#include "../Utils/SgUtils.h"
#include "SgUtils.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../Distribution/DvmhDirective.h"
#include "../GraphLoop/graph_loops_func.h"
#include "../ExpressionTransform/expr_transform.h"
#include "graph_loops_func.h"
#include "expr_transform.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../CFGraph/CFGraph.h"

View File

@@ -1,8 +1,8 @@
#pragma once
#include <vector>
#include "dvm.h"
#include "../GraphCall/graph_calls.h"
#include "../Utils/json.hpp"
#include "graph_calls.h"
#include "json.hpp"
class ParallelStats
{

View File

@@ -1,5 +1,5 @@
#define _LEAK_
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstring>
@@ -9,7 +9,7 @@
#include <vector>
#include <fstream>
#include "../GraphCall/graph_calls.h"
#include "graph_calls.h"
#include "private_analyzer.h"
#include "dvm.h"
#include "../CFGraph/CFGraph.h"

View File

@@ -3,7 +3,7 @@
#include <vector>
#include "dvm.h"
#include "../GraphCall/graph_calls.h"
#include "graph_calls.h"
extern void Private_Vars_Analyzer(SgStatement* start);
void PrivateAnalyzer(SgFile *file, std::vector<FuncInfo*> &funcs);

View File

@@ -0,0 +1,141 @@
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <vector>
#include <queue>
#include <numeric>
#include <iostream>
#include "private_arrays_search.h"
#include "range_structures.h"
#include "region.h"
#include "SgUtils.h"
#include "graph_loops.h"
#include "../CFGraph/CFGraph.h"
using namespace std;
void Collapse(Region* region)
{
if (region->getBasickBlocks().empty())
return;
for (auto& [arrayName, arrayRanges] : region->getHeader()->array_out)
{
for (Region* byBlock : region->getBasickBlocks())
{
AccessingSet intersection = byBlock->array_def[arrayName].Intersect(arrayRanges);
region->array_def[arrayName] = region->array_def[arrayName].Union(intersection);
}
}
for (auto& byBlock : region->getBasickBlocks())
{
for (auto& [arrayName, arrayRanges] : byBlock->array_use)
{
AccessingSet diff = byBlock->array_use[arrayName].Diff(byBlock->array_in[arrayName]);
region->array_use[arrayName] = region->array_use[arrayName].Union(diff);
}
}
ArrayAccessingIndexes useUnion;
for (auto& byBlock : region->getBasickBlocks())
for (auto& [arrayName, arrayRanges] : byBlock->array_use)
useUnion[arrayName] = useUnion[arrayName].Union(byBlock->array_use[arrayName]);
for (auto& [arrayName, arrayRanges] : useUnion)
region->array_priv[arrayName] = useUnion[arrayName].Diff(region->array_use[arrayName]);
for (Region* prevBlock : region->getHeader()->getPrevRegions())
prevBlock->replaceInNextRegions(region, region->getHeader());
for (Region* nextBlock : region->getHeader()->getNextRegions())
nextBlock->replaceInPrevRegions(region, region->getHeader());
}
static void SolveDataFlowIteratively(Region* DFG)
{
unordered_set<Region*> worklist(DFG->getBasickBlocks());
do
{
Region* b = *worklist.begin();
ArrayAccessingIndexes newIn;
bool flagFirst = true;
for (Region* prevBlock : b->getPrevRegions())
{
if (flagFirst)
{
newIn = prevBlock->array_out;
flagFirst = false;
}
else
{
if (prevBlock->array_out.empty())
{
newIn.clear();
continue;
}
for (const auto& [arrayName, accessSet] : prevBlock->array_out)
{
if (newIn.find(arrayName) != newIn.end())
newIn[arrayName] = newIn[arrayName].Intersect(accessSet);
else
newIn[arrayName] = AccessingSet();
}
}
}
b->array_in = move(newIn);
ArrayAccessingIndexes newOut;
if (b->array_def.empty())
newOut = b->array_in;
else if (b->array_in.empty())
newOut = b->array_def;
else
{
for (auto& [arrayName, accessSet] : b->array_def)
{
if (newOut.find(arrayName) != newOut.end())
newOut[arrayName] = b->array_def[arrayName].Union(b->array_in[arrayName]);
else
newOut[arrayName] = accessSet;
}
}
/* can not differ */
if (newOut != b->array_out)
b->array_out = newOut;
else
worklist.erase(b);
}
while (!worklist.empty());
}
static void SolveDataFlow(Region* DFG)
{
if (!DFG)
return;
SolveDataFlowIteratively(DFG);
for (Region* subRegion : DFG->getSubRegions())
SolveDataFlow(subRegion);
Collapse(DFG);
}
map<LoopGraph*, ArrayAccessingIndexes> findPrivateArrays(map<string, vector<LoopGraph*>> &loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
{
map<LoopGraph*, ArrayAccessingIndexes> result;
for (const auto& [loopName, loops] : loopGraph)
{
for (const auto& loop : loops)
{
for (const auto& [funcInfo, blocks]: FullIR)
{
Region* loopRegion = new Region(loop, blocks);
SolveDataFlow(loopRegion);
result[loop] = loopRegion->array_priv;
delete(loopRegion);
}
}
}
return result;
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include <vector>
#include <map>
#include <unordered_set>
#include "range_structures.h"
#include "region.h"
#include "graph_loops.h"
#include "../CFGraph/CFGraph.h"
void Collapse(Region* region);
std::map<LoopGraph*, ArrayAccessingIndexes> findPrivateArrays(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR);
std::pair<SAPFOR::BasicBlock*, std::unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const std::vector<SAPFOR::BasicBlock*> blocks);

View File

@@ -0,0 +1,293 @@
#include <vector>
#include <map>
#include <unordered_set>
#include <string>
#include "utils.h"
#include "range_structures.h"
using namespace std;
static vector<uint64_t> FindParticularSolution(const ArrayDimension& dim1, const ArrayDimension& dim2)
{
for (uint64_t i = 0; i < dim1.tripCount; i++)
{
uint64_t leftPart = dim1.start + i * dim1.step;
for (uint64_t j = 0; j < dim2.tripCount; j++)
{
uint64_t rightPart = dim2.start + j * dim2.step;
if (leftPart == rightPart)
return { i, j };
}
}
return {};
}
/* dim1 /\ dim2 */
static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const ArrayDimension& dim2)
{
vector<uint64_t> partSolution = FindParticularSolution(dim1, dim2);
if (partSolution.empty())
return NULL;
int64_t x0 = partSolution[0], y0 = partSolution[1];
/* x = x_0 + c * t */
/* y = y_0 + d * t */
int64_t c = dim2.step / gcd(dim1.step, dim2.step);
int64_t d = dim1.step / gcd(dim1.step, dim2.step);
int64_t tXMin, tXMax, tYMin, tYMax;
tXMin = -x0 / c;
tXMax = (dim1.tripCount - 1 - x0) / c;
tYMin = -y0 / d;
tYMax = (dim2.tripCount - 1 - y0) / d;
int64_t tMin = max(tXMin, tYMin);
uint64_t tMax = min(tXMax, tYMax);
if (tMin > tMax)
return NULL;
uint64_t start3 = dim1.start + x0 * dim1.step;
uint64_t step3 = c * dim1.step;
ArrayDimension* result = new(ArrayDimension){ start3, step3, tMax + 1 };
return result;
}
/* dim1 / dim2 */
static vector<ArrayDimension> DimensionDifference(const ArrayDimension& dim1, const ArrayDimension& dim2)
{
ArrayDimension* intersection = DimensionIntersection(dim1, dim2);
if (!intersection)
return { dim1 };
vector<ArrayDimension> result;
/* add the part before intersection */
if (dim1.start < intersection->start)
result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step });
/* add the parts between intersection steps */
uint64_t start = (intersection->start - dim1.start) / dim1.step;
uint64_t interValue = intersection->start;
for (int64_t i = start; dim1.start + i * dim1.step <= intersection->start + intersection->step * (intersection->tripCount - 1); i++)
{
uint64_t centerValue = dim1.start + i * dim1.step;
if (centerValue == interValue)
{
if (i - start > 1)
{
result.push_back({ dim1.start + (start + 1) * dim1.step, dim1.step, i - start - 1 });
start = i;
}
interValue += intersection->step;
}
}
/* add the part after intersection */
if (intersection->start + intersection->step * (intersection->tripCount - 1) < dim1.start + dim1.step * (dim1.tripCount - 1))
{
/* first value after intersection */
uint64_t right_start = intersection->start + intersection->step * (intersection->tripCount - 1) + dim1.step;
uint64_t tripCount = (dim1.start + dim1.step * dim1.tripCount - right_start) / dim1.step;
result.push_back({ right_start, dim1.step, tripCount });
}
delete(intersection);
return result;
}
static vector<ArrayDimension> DimensionUnion(const ArrayDimension& dim1, const ArrayDimension& dim2)
{
vector<ArrayDimension> res;
ArrayDimension* inter = DimensionIntersection(dim1, dim2);
if (!inter)
return { dim1, dim2 };
res.push_back(*inter);
delete(inter);
vector<ArrayDimension> diff1, diff2;
diff1 = DimensionDifference(dim1, dim2);
diff2 = DimensionDifference(dim2, dim1);
res.insert(res.end(), diff1.begin(), diff1.end());
res.insert(res.end(), diff2.begin(), diff2.end());
return res;
}
static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>& firstElement, const vector<ArrayDimension>& secondElement)
{
if (firstElement.empty() || secondElement.empty())
return {};
size_t dimAmount = firstElement.size();
/* check if there is no intersecction */
for (size_t i = 0; i < dimAmount; i++)
if (FindParticularSolution(firstElement[i], secondElement[i]).empty())
return {};
vector<ArrayDimension> result(dimAmount);
for (size_t i = 0; i < dimAmount; i++)
{
ArrayDimension* resPtr = DimensionIntersection(firstElement[i], secondElement[i]);
if (resPtr)
result[i] = *resPtr;
else
return {};
}
return result;
}
static vector<vector<ArrayDimension>> ElementsDifference(const vector<ArrayDimension>& firstElement,
const vector<ArrayDimension>& secondElement)
{
if (firstElement.empty() || secondElement.empty())
return {};
vector<ArrayDimension> intersection = ElementsIntersection(firstElement, secondElement);
vector<vector<ArrayDimension>> result;
if (intersection.empty())
return { firstElement };
for (int i = 0; i < firstElement.size(); i++)
{
auto dimDiff = DimensionDifference(firstElement[i], secondElement[i]);
if (!dimDiff.empty())
{
vector<ArrayDimension> firstCopy = firstElement;
for (const auto& range : dimDiff)
{
firstCopy[i] = range;
result.push_back(firstCopy);
}
}
}
return result;
}
static void ElementsUnion(const vector<ArrayDimension>& firstElement, const vector<ArrayDimension>& secondElement,
vector<vector<ArrayDimension>>& lc, vector<vector<ArrayDimension>>& rc,
vector<ArrayDimension>& intersection)
{
/* lc(rc) is a set of ranges, which only exist in first(second) element*/
intersection = ElementsIntersection(firstElement, secondElement);
lc = ElementsDifference(firstElement, intersection);
rc = ElementsDifference(secondElement, intersection);
}
void AccessingSet::FindUncovered(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const {
vector<vector<ArrayDimension>> newTails;
result.push_back(element);
for (const auto& currentElement : allElements)
{
for (const auto& tailLoc : result)
{
auto intersection = ElementsIntersection(tailLoc, currentElement);
auto diff = ElementsDifference(tailLoc, intersection);
if (!diff.empty()) {
newTails.insert(newTails.end(), diff.begin(), diff.end());
}
}
result = newTails;
newTails.clear();
}
}
bool AccessingSet::ContainsElement(const vector<ArrayDimension>& element) const
{
vector<vector<ArrayDimension>> tails;
FindUncovered(element, tails);
return !tails.empty();
}
void AccessingSet::FindCoveredBy(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const
{
for (const auto& currentElement : allElements)
{
auto intersection = ElementsIntersection(element, currentElement);
if (!intersection.empty())
result.push_back(intersection);
}
}
vector<vector<ArrayDimension>> AccessingSet::GetElements() const { return allElements; }
void AccessingSet::Insert(const vector<ArrayDimension>& element)
{
vector<vector<ArrayDimension>> tails;
FindUncovered(element, tails);
allElements.insert(allElements.end(), tails.begin(), tails.end());
}
AccessingSet AccessingSet::Union(const AccessingSet& source) {
AccessingSet result;
for (auto& element : source.GetElements())
result.Insert(element);
for (auto& element : allElements)
result.Insert(element);
return result;
}
AccessingSet AccessingSet::Intersect(const AccessingSet& secondSet) const
{
vector<vector<ArrayDimension>> result;
if (secondSet.GetElements().empty() || this->allElements.empty())
return AccessingSet(result);
for (const auto& element : allElements)
{
if (secondSet.ContainsElement(element))
result.push_back(element);
else
{
vector<vector<ArrayDimension>> coveredBy;
secondSet.FindCoveredBy(element, coveredBy);
if (!coveredBy.empty())
result.insert(result.end(), coveredBy.begin(), coveredBy.end());
}
}
return AccessingSet(result);
}
AccessingSet AccessingSet::Diff(const AccessingSet& secondSet) const
{
if (secondSet.GetElements().empty() || allElements.empty())
return *this;
AccessingSet intersection = this->Intersect(secondSet);
AccessingSet uncovered = *this;
vector<vector<ArrayDimension>> result;
for (const auto& element : intersection.GetElements())
{
vector<vector<ArrayDimension>> current_uncovered;
uncovered.FindUncovered(element, current_uncovered);
uncovered = AccessingSet(current_uncovered);
}
return uncovered;
}
bool operator!=(const ArrayDimension& lhs, const ArrayDimension& rhs)
{
return !(lhs.start == rhs.start && lhs.step == rhs.step && lhs.tripCount == rhs.tripCount);
}
bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs)
{
for (size_t i = 0; i < lhs.allElements.size(); i++)
for (size_t j = 0; j < lhs.allElements[i].size(); j++)
if (lhs.allElements[i][j] != rhs.allElements[i][j])
return true;
return false;
}
bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs)
{
if (lhs.size() != rhs.size())
return true;
for (auto& [key, value] : lhs)
if (rhs.find(key) == rhs.end())
return true;
return false;
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include <vector>
#include <map>
#include <unordered_set>
#include <string>
#include <cstdint>
struct ArrayDimension
{
uint64_t start, step, tripCount;
};
class AccessingSet {
private:
std::vector<std::vector<ArrayDimension>> allElements;
public:
AccessingSet(std::vector<std::vector<ArrayDimension>> input) : allElements(input) {};
AccessingSet() {};
AccessingSet(const AccessingSet& a) { allElements = a.GetElements(); };
std::vector<std::vector<ArrayDimension>> GetElements() const;
void Insert(const std::vector<ArrayDimension>& element);
AccessingSet Union(const AccessingSet& source);
AccessingSet Intersect(const AccessingSet& secondSet) const;
AccessingSet Diff(const AccessingSet& secondSet) const;
bool ContainsElement(const std::vector<ArrayDimension>& element) const;
void FindCoveredBy(const std::vector<ArrayDimension>& element, std::vector<std::vector<ArrayDimension>>& result) const;
void FindUncovered(const std::vector<ArrayDimension>& element, std::vector<std::vector<ArrayDimension>>& result) const;
friend bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs);
};
using ArrayAccessingIndexes = std::map<std::string, AccessingSet>;
bool operator!=(const ArrayDimension& lhs, const ArrayDimension& rhs);
bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs);
bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs);

View File

@@ -0,0 +1,251 @@
#include<vector>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<string>
#include <numeric>
#include "range_structures.h"
#include "region.h"
#include "SgUtils.h"
using namespace std;
static bool isParentStmt(SgStatement* stmt, SgStatement* parent)
{
for (; stmt; stmt = stmt->controlParent())
if (stmt == parent)
return true;
return false;
}
/*returns head block and loop*/
pair<SAPFOR::BasicBlock*, unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const vector<SAPFOR::BasicBlock*> blocks)
{
unordered_set<SAPFOR::BasicBlock*> block_loop;
SAPFOR::BasicBlock* head_block = nullptr;
auto loop_operator = loop->loop->GetOriginal();
for (const auto& block : blocks)
{
if (!block || (block->getInstructions().size() == 0))
continue;
SgStatement* first = block->getInstructions().front()->getInstruction()->getOperator();
SgStatement* last = block->getInstructions().back()->getInstruction()->getOperator();
if (isParentStmt(first, loop_operator) && isParentStmt(last, loop_operator))
{
block_loop.insert(block);
if ((!head_block) && (first == loop_operator) && (last == loop_operator) &&
(block->getInstructions().size() == 2) &&
(block->getInstructions().back()->getInstruction()->getOperation() == SAPFOR::CFG_OP::JUMP_IF))
{
head_block = block;
}
}
}
return { head_block, block_loop };
}
static void BuildLoopIndex(map<string, LoopGraph*>& loopForIndex, LoopGraph* loop) {
string index = loop->loopSymbol();
loopForIndex[index] = loop;
for (const auto& childLoop : loop->children)
BuildLoopIndex(loopForIndex, childLoop);
}
static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, LoopGraph*>& loopForIndex) {
unordered_set<SAPFOR::Argument*> args = { block->getInstructions()[pos]->getInstruction()->getArg1() };
for (int i = pos - 1; i >= 0; i--)
{
SAPFOR::Argument* res = block->getInstructions()[i]->getInstruction()->getResult();
if (res && args.find(res) != args.end())
{
SAPFOR::Argument* arg1 = block->getInstructions()[i]->getInstruction()->getArg1();
SAPFOR::Argument* arg2 = block->getInstructions()[i]->getInstruction()->getArg2();
if (arg1)
{
string name = arg1->getValue();
int idx = name.find('%');
if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end())
return name.substr(idx + 1);
else
args.insert(arg1);
}
if (arg2)
{
string name = arg2->getValue();
int idx = name.find('%');
if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end())
return name.substr(idx + 1);
else
args.insert(arg2);
}
}
}
return "";
}
static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use) {
auto instructions = block->getInstructions();
map<string, LoopGraph*> loopForIndex;
BuildLoopIndex(loopForIndex, loop);
for (int i = 0; i < instructions.size(); i++)
{
auto instruction = instructions[i];
if (!instruction->getInstruction()->getArg1())
continue;
auto operation = instruction->getInstruction()->getOperation();
auto type = instruction->getInstruction()->getArg1()->getType();
if ((operation == SAPFOR::CFG_OP::STORE || operation == SAPFOR::CFG_OP::LOAD) && type == SAPFOR::CFG_ARG_TYPE::ARRAY)
{
vector<SAPFOR::Argument*> index_vars;
vector<int> refPos;
string array_name;
if (operation == SAPFOR::CFG_OP::STORE)
array_name = instruction->getInstruction()->getArg1()->getValue();
else
array_name = instruction->getInstruction()->getArg2()->getValue();
int j = i - 1;
while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF)
{
index_vars.push_back(instructions[j]->getInstruction()->getArg1());
refPos.push_back(j);
j--;
}
/*to choose correct dimension*/
int n = index_vars.size();
vector<ArrayDimension> accessPoint(n);
auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression());
vector<pair<int, int>> coefsForDims;
for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i)
{
const vector<int*>& coefs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
if (coefs.size() == 1)
{
const pair<int, int> coef(coefs[0][0], coefs[0][1]);
coefsForDims.push_back(coef);
}
}
if(coefsForDims.empty())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
while (!index_vars.empty())
{
auto var = index_vars.back();
int currentVarPos = refPos.back();
pair<int, int> currentCoefs = coefsForDims.back();
ArrayDimension current_dim;
if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST)
current_dim = { stoul(var->getValue()), 1, 1 };
else
{
string name, full_name = var->getValue();
int pos = full_name.find('%');
LoopGraph* currentLoop;
if (pos != -1)
{
name = full_name.substr(pos + 1);
if (loopForIndex.find(name) != loopForIndex.end())
currentLoop = loopForIndex[name];
else
return -1;
}
else
{
name = FindIndexName(currentVarPos, block, loopForIndex);
if (name == "")
return -1;
if (loopForIndex.find(name) != loopForIndex.end())
currentLoop = loopForIndex[name];
else
return -1;
}
uint64_t start = currentLoop->startVal * currentCoefs.first + currentCoefs.second;
uint64_t step = currentCoefs.first;
current_dim = { start, step, (uint64_t)currentLoop->calculatedCountOfIters };
}
accessPoint[n - index_vars.size()] = current_dim;
index_vars.pop_back();
refPos.pop_back();
coefsForDims.pop_back();
}
if (operation == SAPFOR::CFG_OP::STORE)
def[array_name].Insert(accessPoint);
else
use[array_name].Insert(accessPoint);
}
}
return 0;
}
static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet)
{
for (SAPFOR::BasicBlock* block : blockSet)
{
for (SAPFOR::BasicBlock* nextBlock : block->getNext())
if (bbToRegion.find(nextBlock) != bbToRegion.end())
bbToRegion[block]->addNextRegion(bbToRegion[nextBlock]);
for (SAPFOR::BasicBlock* prevBlock : block->getPrev())
if (bbToRegion.find(prevBlock) != bbToRegion.end())
bbToRegion[block]->addPrevRegion(bbToRegion[prevBlock]);
}
}
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, const unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
{
Region* region = new Region;
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks);
if (bbToRegion.find(header) != bbToRegion.end())
region->setHeader(bbToRegion.at(header));
else
{
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return NULL;
}
for (SAPFOR::BasicBlock* block : blockSet)
if (bbToRegion.find(block) != bbToRegion.end())
region->addBasickBlocks(bbToRegion.at(block));
for (LoopGraph* childLoop : loop->children)
region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion));
return region;
}
Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks)
{
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks);
unordered_map<SAPFOR::BasicBlock*, Region*> bbToRegion;
for (auto poiner : blockSet)
{
bbToRegion[poiner] = new Region(*poiner);
this->basickBlocks.insert(bbToRegion[poiner]);
GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use);
}
this->header = bbToRegion[header];
SetConnections(bbToRegion, blockSet);
//create subRegions
for (LoopGraph* childLoop : loop->children)
subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion));
}

View File

@@ -0,0 +1,60 @@
#pragma once
#include <vector>
#include <map>
#include <unordered_set>
#include <string>
#include "graph_loops.h"
#include "../CFGraph/CFGraph.h"
class Region : public SAPFOR::BasicBlock {
public:
Region() { header = nullptr; }
Region(SAPFOR::BasicBlock block) : SAPFOR::BasicBlock::BasicBlock(block) { header = nullptr; }
Region(LoopGraph* loop, const std::vector<SAPFOR::BasicBlock*>& Blocks);
Region* getHeader() { return header; }
void setHeader(Region* region) { header = region; }
std::unordered_set<Region*>& getBasickBlocks() { return basickBlocks; }
void addBasickBlocks(Region* region) { basickBlocks.insert(region); }
const std::unordered_set<Region*>& getPrevRegions() { return prevRegions; }
std::unordered_set<Region*> getNextRegions() { return nextRegions; }
void addPrevRegion(Region* region) { prevRegions.insert(region); }
void addNextRegion(Region* region) { nextRegions.insert(region); }
void replaceInPrevRegions(Region* source, Region* destination)
{
prevRegions.erase(destination);
prevRegions.insert(source);
}
void replaceInNextRegions(Region* source, Region* destination)
{
nextRegions.erase(destination);
nextRegions.insert(source);
}
std::unordered_set<Region*> getSubRegions() { return subRegions; }
void addSubRegions(Region* region) { subRegions.insert(region); }
ArrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv;
private:
std::unordered_set<Region*> subRegions, basickBlocks;
/*next Region which is BB for current BB Region*/
std::unordered_set<Region*> nextRegions;
/*prev Regions which is BBs for current BB Region*/
std::unordered_set<Region*> prevRegions;
Region* header;
};

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -6,9 +6,9 @@
#include <string>
#include <vector>
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "../Utils/utils.h"
#include "errors.h"
#include "SgUtils.h"
#include "utils.h"
#include "../VerificationCode/verifications.h"

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -7,8 +7,8 @@
#include <vector>
#include "FileInfo.h"
#include "../Utils/utils.h"
#include "../Utils/errors.h"
#include "utils.h"
#include "errors.h"
using namespace std;

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -22,8 +22,8 @@
#include <thread>
#include <stack>
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "errors.h"
#include "SgUtils.h"
#include "../VisualizerCalls/get_information.h"
#include "../VisualizerCalls/SendMessage.h"
@@ -34,6 +34,7 @@
using namespace std;
extern "C" int parse_file(int argc, char* argv[], char* proj_name);
extern const char* VISUALIZER_DATA_PATH;
static void findModuleDeclInProject(const string& name, const vector<string>& files, map<string, string>& modDecls)
{
@@ -293,11 +294,8 @@ static vector<string> parseList(vector<FileInfo>& listOfProject,
}
}
#ifdef _WIN32
sendMessage_2lvl(L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> '" + to_wstring(file) + L"'");
#else
sendMessage_2lvl(L" processing file '" + to_wstring(file) + L"'");
#endif
sendMessage_2lvl(3, file);
StdCapture::Init();
string errorMessage = "";
try
@@ -443,20 +441,12 @@ static int dumpErrors(const vector<FileInfo>& listOfProject, const vector<string
if (errors[z] == "")
{
FILE* ferr = fopen(file.errPath.c_str(), "w");
if (!ferr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
fclose(ferr);
if (ferr)
fclose(ferr);
++z;
continue;
}
FILE* ferr = fopen(file.errPath.c_str(), "w");
FILE* fout = fopen(file.outPath.c_str(), "w");
if (!ferr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (!fout)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
string errS = "", outS = "";
vector<string> splited;
splitString(errors[z], '\n', splited);
@@ -475,13 +465,22 @@ static int dumpErrors(const vector<FileInfo>& listOfProject, const vector<string
}
}
fprintf(fout, "%s", outS.c_str());
fprintf(ferr, "%s", errS.c_str());
FILE* ferr = fopen(file.errPath.c_str(), "w");
FILE* fout = fopen(file.outPath.c_str(), "w");
if (ferr)
{
fprintf(ferr, "%s", errS.c_str());
fclose(ferr);
}
if (fout)
{
fprintf(fout, "%s", outS.c_str());
fclose(fout);
}
fflush(NULL);
fclose(fout);
fclose(ferr);
++z;
}
@@ -576,11 +575,8 @@ static void parseFiles(int& iters, vector<string>& errors, vector<FileInfo>& lis
do
{
#ifdef _WIN32
sendMessage_1lvl(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring((iters + 1)) + L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
#else
sendMessage_1lvl(L"running " + std::to_wstring((iters + 1)) + L" iteration of syntax analisys");
#endif
sendMessage_1lvl(0, iters + 1);
errors = parseList(listOfProject, iters != 0, parseForInlining, mapModuleDeps, moduleDelc, modDirectOrder, isFromConsole);
changed = createMapOfUse(errors, listOfProject, mapModuleDeps);
if (iters != 0)
@@ -713,7 +709,7 @@ int parseFiles(const char* proj, vector<string>& filesCompilationOrder, int pars
if (pathSplit.size() < 2)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (pathSplit[pathSplit.size() - 2] != "visualiser_data")
if (pathSplit[pathSplit.size() - 2] != VISUALIZER_DATA_PATH)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
string fullPath = "";
for (int z = 0; z < pathSplit.size() - 2; ++z)
@@ -745,9 +741,9 @@ int parseFiles(const char* proj, vector<string>& filesCompilationOrder, int pars
else
fileNameFixed = (toAdd.substr(0, 2) == "./") ? toAdd.substr(2) : toAdd;
const string optPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".opt";
const string errPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".err";
const string outPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".out";
const string optPath = fullPath + VISUALIZER_DATA_PATH + "/options/" + fileNameFixed + ".opt";
const string errPath = fullPath + VISUALIZER_DATA_PATH + "/options/" + fileNameFixed + ".err";
const string outPath = fullPath + VISUALIZER_DATA_PATH + "/options/" + fileNameFixed + ".out";
const string fileText = readFileToStr(toAdd);
@@ -809,6 +805,8 @@ void parseFiles(int argc, char** argv)
printf(" run parsing for inlining\n");
int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, isInline, true);
int errCount = dumpErrors(listOfProject, errors, messages);
if (rethrow == 0)
{
for (auto& err : errors)
@@ -838,5 +836,7 @@ void parseFiles(int argc, char** argv)
}
else
printf("Parsing was completed with errors, throw code %d, errors count %d\n", rethrow, code);
dumpMessages(false, messages, VISUALIZER_DATA_PATH);
exit(0);
}

View File

@@ -1,4 +1,4 @@
#include "../Utils/leak_detector.h"
#include "leak_detector.h"
#include <cstdio>
#include <cstdlib>
@@ -6,8 +6,8 @@
#include <string>
#include <vector>
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "errors.h"
#include "SgUtils.h"
#include "StdCapture.h"

View File

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

Some files were not shown because too many files have changed in this diff Show More