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
2fd08e79f1 Merge branch 'master' into analyze_loops_with_IR 2025-06-22 20:09:16 +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
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
f7c66f537d merged master 2025-05-30 12:54:18 +03:00
267f85ae27 Merge branch 'master' into analyze_loops_with_IR 2025-05-28 16:23:11 +03:00
b137ea5ef3 WIP: testing on big data 2025-05-27 23:34:45 +03:00
6a84171382 finish inductive variables 2025-04-22 16:14:29 +03:00
cd209a587a WIP: merge master 2025-03-25 21:53:01 +03:00
ALEXks
0b0d7d373b fixed removeDvmSpfDirectives 2025-03-25 21:09:34 +03:00
ALEXks
781a892497 fixed removeDvmSpfDirectives 2025-03-25 21:09:34 +03:00
ALEXks
a55440c071 fixed module analysis 2025-03-25 21:09:34 +03:00
ALEXks
996f7ead1b fixed 2025-03-25 21:09:34 +03:00
ALEXks
5231eeacd8 fixed module symbols analysis 2025-03-25 21:09:34 +03:00
ALEXks
7460cf6e59 added REMOVE_SPF pass 2025-03-25 21:09:34 +03:00
ALEXks
5596b57021 version updated 2025-03-25 21:09:34 +03:00
3ad972c188 Обновить README.md 2025-03-25 21:09:34 +03:00
dde0bcdee5 Обновить README.md 2025-03-25 21:09:34 +03:00
65cdbef201 added forgotten files 2025-03-25 21:09:34 +03:00
2ad239d1e3 moved dvm to submodule 2025-03-25 21:09:34 +03:00
12f311077b added dvm as submodule 2025-03-25 21:09:34 +03:00
ALEXks
a2e0a99891 added Server project 2025-03-25 21:09:34 +03:00
27a350dac0 fixed cmakes 2025-03-25 21:09:33 +03:00
3c1032bfd0 moved to dvm_svn 2025-03-25 21:09:33 +03:00
189374274e finalyze moving 2025-03-25 21:09:12 +03:00
de4690513b fixed paths 2025-03-25 20:43:08 +03:00
86ab34e7f3 fixed paths 2025-03-25 20:43:01 +03:00
06cfe83666 removed unnecessary 2025-03-25 20:39:36 +03:00
a3c1e1e5d1 fixed paths 2025-03-25 20:39:36 +03:00
75e89ab868 fixed paths 2025-03-25 20:39:35 +03:00
d4fb323f86 moved 2025-03-25 20:39:29 +03:00
ALEXks
0c9f0664fd added module symbols initiazliation 2025-03-25 20:35:21 +03:00
ALEXks
90a608230c version updated 2025-03-25 20:35:21 +03:00
ALEXks
d6df2f6b5f fdvm updated 2025-03-25 20:35:21 +03:00
ALEXks
90894a4723 fixed module analysis 2025-03-25 20:35:21 +03:00
ALEXks
26fe1d3f61 first step of shadow fixing 2025-03-25 20:35:21 +03:00
ALEXks
68d2f3253c improved module analysis 2025-03-25 20:35:21 +03:00
ALEXks
09401376c7 improved module analysis 2025-03-25 20:35:21 +03:00
ALEXks
a0c8f78868 fixed implicit 2025-03-25 20:35:21 +03:00
ALEXks
2aa9e569f4 refactoring module analysis 2025-03-25 20:35:20 +03:00
ALEXks
9e5ee78b80 fixed module symbol analysis 2025-03-25 20:35:20 +03:00
ALEXks
d5d5514e17 fixed function analysis 2025-03-25 20:35:20 +03:00
ALEXks
68c779790d fixed dead flag for functions 2025-03-25 20:35:20 +03:00
ALEXks
c6b09ad285 fixed distribution, fixed routine, fixed null program unparsing 2025-03-25 20:35:20 +03:00
ALEXks
fd402b6ab0 added optimized version of CG on GPU 2025-03-25 20:35:20 +03:00
ALEXks
b76753c285 removed logging from SAPFOR and SERVER, updated NPB and fdvm 2025-03-25 20:35:20 +03:00
ALEXks
44600a50c1 updated dvm 2025-03-25 20:35:20 +03:00
ALEXks
d2f5e5fcc1 fixed DECLARE 2025-03-25 20:35:20 +03:00
ALEXks
18ac0ae47c fixed DECLARE 2025-03-25 20:35:20 +03:00
ALEXks
00b6026761 fixed 2025-03-25 20:35:20 +03:00
ALEXks
2036fab86f added dvm declare 2025-03-25 20:35:20 +03:00
ALEXks
da4e992926 fixed routine convertation 2025-03-25 20:35:20 +03:00
ALEXks
8e4a4c78ad improved ROUTINE insertion 2025-03-25 20:35:20 +03:00
b4038b532f WIP try to fix renaming 2025-03-25 20:35:20 +03:00
dec1a853db Merge branch 'master' into analyze_loops_with_IR 2024-12-31 16:41:12 +03:00
7df02737c7 WIP: finishing SSA renaming 2024-12-26 01:58:15 +03:00
d267dc047a WIP: add fi functions and rename vars 2024-12-19 15:37:34 +03:00
12a810ad35 WIP fix russian coments 2024-11-22 00:28:12 +03:00
1522dc7f27 Merge branch 'master' into analyze_loops_with_IR 2024-11-21 21:27:58 +03:00
bd52d5c6ec Remove debug files 2024-11-17 22:34:53 +03:00
4ba2bb4c94 Merge branch 'master' into analyze_loops_with_IR 2024-11-17 22:27:14 +03:00
60544ea4d6 WIP: add dominators logic 2024-11-14 15:28:51 +03:00
ALEXks
b40e969d02 Merge branch 'analyze_loops_with_IR' of http://alex-freenas.ddns.net:3000/Alexander_KS/SAPFOR into analyze_loops_with_IR 2024-05-26 20:49:46 +03:00
d062e52dd6 WIP add afterLoopLine 2024-05-26 20:49:14 +03:00
392ad97738 WIP add analizing IR loop 2024-05-26 20:49:14 +03:00
c2c111586c WIP add afterLoopLine 2024-05-26 13:53:47 +03:00
172eedfef1 WIP add analizing IR loop 2024-05-26 12:32:53 +03:00
44 changed files with 1582 additions and 1491 deletions

1
.gitignore vendored
View File

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

View File

@@ -12,7 +12,6 @@ add_definitions("-D SYS5")
add_definitions("-D YYDEBUG") add_definitions("-D YYDEBUG")
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 17)
set(fdvm_include projects/dvm/fdvmh/include/fdvmh/) set(fdvm_include projects/dvm/fdvmh/include/fdvmh/)
set(fdvm_sources projects/dvm/fdvmh/tools/fdvmh/) set(fdvm_sources projects/dvm/fdvmh/tools/fdvmh/)
@@ -34,7 +33,6 @@ include_directories(src/Distribution)
include_directories(src/GraphCall) include_directories(src/GraphCall)
include_directories(src/GraphLoop) include_directories(src/GraphLoop)
include_directories(src/Transformations/ExpressionSubstitution) include_directories(src/Transformations/ExpressionSubstitution)
include_directories(src/Transformations)
#Sage lib includes #Sage lib includes
include_directories(${fdvm_include}) include_directories(${fdvm_include})
@@ -204,8 +202,6 @@ set(TR_INLINER src/Transformations/FunctionInlining/inliner.cpp
src/Transformations/FunctionInlining/inliner.h) src/Transformations/FunctionInlining/inliner.h)
set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp
src/Transformations/RenameSymbols/rename_symbols.h) src/Transformations/RenameSymbols/rename_symbols.h)
SET(TR_SWAP_OPERATORS src/Transformations/SwapOperators/swap_operators.cpp
src/Transformations/SwapOperators/swap_operators.h)
set(TRANSFORMS set(TRANSFORMS
${TR_DEAD_CODE} ${TR_DEAD_CODE}
@@ -228,9 +224,8 @@ set(TRANSFORMS
${TR_REPLACE_ARRAYS_IN_IO} ${TR_REPLACE_ARRAYS_IN_IO}
${TR_EXPR_TRANSFORM} ${TR_EXPR_TRANSFORM}
${TR_INLINER} ${TR_INLINER}
${TR_RENAME_SYMBOLS} ${TR_RENAME_SYMBOLS})
${TR_SWAP_OPERATORS})
set(CFG src/CFGraph/IR.cpp set(CFG src/CFGraph/IR.cpp
src/CFGraph/IR.h src/CFGraph/IR.h
src/CFGraph/IR_domTree.cpp src/CFGraph/IR_domTree.cpp
@@ -243,14 +238,14 @@ set(CFG src/CFGraph/IR.cpp
src/CFGraph/live_variable_analysis.h src/CFGraph/live_variable_analysis.h
src/CFGraph/private_variables_analysis.cpp src/CFGraph/private_variables_analysis.cpp
src/CFGraph/private_variables_analysis.h src/CFGraph/private_variables_analysis.h
) src/CFGraph/IR_SSAForm.cpp
src/CFGraph/IR_SSAForm.h)
set(DATA_FLOW set(DATA_FLOW
src/CFGraph/DataFlow/data_flow.h src/CFGraph/DataFlow/data_flow.h
src/CFGraph/DataFlow/data_flow_impl.h src/CFGraph/DataFlow/data_flow_impl.h
src/CFGraph/DataFlow/backward_data_flow.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 set(CREATE_INTER_T src/CreateInterTree/CreateInterTree.cpp
src/CreateInterTree/CreateInterTree.h) src/CreateInterTree/CreateInterTree.h)
@@ -326,7 +321,9 @@ set(GR_LOOP src/GraphLoop/graph_loops_base.cpp
set(LOOP_ANALYZER src/LoopAnalyzer/allocations_prepoc.cpp set(LOOP_ANALYZER src/LoopAnalyzer/allocations_prepoc.cpp
src/LoopAnalyzer/dep_analyzer.cpp src/LoopAnalyzer/dep_analyzer.cpp
src/LoopAnalyzer/loop_analyzer.cpp src/LoopAnalyzer/loop_analyzer.cpp
src/LoopAnalyzer/loop_analyzer.h) src/LoopAnalyzer/loop_analyzer.h
src/LoopAnalyzer/implicit_loops_analyzer.cpp
src/LoopAnalyzer/implicit_loops_analyzer.h)
set(MAIN src/Sapfor.cpp set(MAIN src/Sapfor.cpp
src/Sapfor.h src/Sapfor.h
@@ -462,7 +459,6 @@ source_group (Transformations\\GlobalVariables FILES ${TR_GV})
source_group (Transformations\\ConvertToC FILES ${TR_CONV}) source_group (Transformations\\ConvertToC FILES ${TR_CONV})
source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE}) source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE})
source_group (Transformations\\ReplaceArraysInIO FILES ${TR_REPLACE_ARRAYS_IN_IO}) source_group (Transformations\\ReplaceArraysInIO FILES ${TR_REPLACE_ARRAYS_IN_IO})
source_group (Transformations\\SwapOperators FILES ${TR_SWAP_OPERATORS})
source_group (CreateIntervals FILES ${CREATE_INTER_T}) source_group (CreateIntervals FILES ${CREATE_INTER_T})
@@ -491,7 +487,7 @@ source_group (Predictor\\Library FILES ${LIBPREDICTOR})
source_group (Parser FILES ${PARSER}) source_group (Parser FILES ${PARSER})
source_group (PPPA\\PPPA FILES ${PPPA}) source_group (PPPA\\PPPA FILES ${PPPA})
source_group (PPPA\\ZLib FILES ${ZLIB}) source_group (PPPA\\ZLib FILES ${ZLIB})
if (MSVC_IDE) if (MSVC_IDE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Zc:__cplusplus") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Zc:__cplusplus")
else() else()
@@ -500,9 +496,7 @@ else()
else() else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif() endif()
if(NOT CMAKE_BUILD_TYPE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif()
endif() endif()
add_subdirectory(projects/Fdvm) add_subdirectory(projects/Fdvm)

View File

@@ -50,12 +50,30 @@ BBlock::BasicBlock(const BBlock& copyFrom)
prev = copyFrom.prev; 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); item->setBasicBlock(this);
} }
void BBlock::addInstructionBefore(IR_Block* item, Instruction* before)
{
checkNull(before, convertFileName(__FILE__).c_str(), __LINE__);
checkNull(item, convertFileName(__FILE__).c_str(), __LINE__);
for (auto it = instructions.begin(); it != instructions.end(); ++it) {
if ((*it)->getInstruction() == before) {
instructions.insert(it, item);
item->setBasicBlock(this);
return;
}
}
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
int BBlock::removePrev(BBlock* removed) int BBlock::removePrev(BBlock* removed)
{ {
auto it = std::remove(prev.begin(), prev.end(), removed); auto it = std::remove(prev.begin(), prev.end(), removed);
@@ -512,7 +530,7 @@ static int buildReachingDefs(const vector<BBlock*>& CFG, const FuncInfo* currF,
return iter; return iter;
} }
//Kosaraju<EFBFBD>Sharir algorithm //Kosaraju-Sharir algorithm
static vector<int> getStronglyConnectedComps(vector<vector<int>>& g) { static vector<int> getStronglyConnectedComps(vector<vector<int>>& g) {
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty. // 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
auto size = g.size(); auto size = g.size();

View File

@@ -6,6 +6,10 @@
#include <vector> #include <vector>
#include "IR.h" #include "IR.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "IR_domTree.h" #include "IR_domTree.h"
namespace SAPFOR namespace SAPFOR
@@ -41,7 +45,8 @@ namespace SAPFOR
BasicBlock(IR_Block* item); BasicBlock(IR_Block* item);
BasicBlock(const BasicBlock& copyFrom); BasicBlock(const BasicBlock& copyFrom);
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 addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
void addNext(BasicBlock* next_) { next.push_back(next_); } void addNext(BasicBlock* next_) { next.push_back(next_); }
void setDom(BasicBlock* dom) { directDominator = dom; } void setDom(BasicBlock* dom) { directDominator = dom; }

View File

@@ -42,6 +42,7 @@ namespace SAPFOR
Argument() : number(lastNumArg++), type(CFG_ARG_TYPE::NONE), value(""), mType(CFG_MEM_TYPE::NONE_) { } Argument() : number(lastNumArg++), type(CFG_ARG_TYPE::NONE), value(""), mType(CFG_MEM_TYPE::NONE_) { }
Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType) : number(lastNumArg++), type(type), mType(mType), value("") { } Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType) : number(lastNumArg++), type(type), mType(mType), value("") { }
Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType, const std::string& value) : number(lastNumArg++), type(type), mType(mType), value(value) { } Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType, const std::string& value) : number(lastNumArg++), type(type), mType(mType), value(value) { }
Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType, const std::string& value, int num) : number(num), type(type), mType(mType), value(value) { }
Argument(CFG_ARG_TYPE type, const std::string& value) : number(lastNumArg++), type(type), mType(CFG_MEM_TYPE::NONE_), value(value) Argument(CFG_ARG_TYPE type, const std::string& value) : number(lastNumArg++), type(type), mType(CFG_MEM_TYPE::NONE_), value(value)
{ {
if (type != CFG_ARG_TYPE::INSTR && type == CFG_ARG_TYPE::LAB && if (type != CFG_ARG_TYPE::INSTR && type == CFG_ARG_TYPE::LAB &&
@@ -50,6 +51,9 @@ namespace SAPFOR
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
} }
} }
Argument(const Argument& other)
: number(other.number), type(other.type), mType(other.mType), value(other.value)
{ }
void setType(CFG_ARG_TYPE newType) { type = newType; } void setType(CFG_ARG_TYPE newType) { type = newType; }
CFG_ARG_TYPE getType() const { return type; } CFG_ARG_TYPE getType() const { return type; }

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);

View File

@@ -7,7 +7,7 @@
#include "CFGraph.h" #include "CFGraph.h"
// Lengauer, Thomas. A fast algorithm for finding dominators in a flowgraph / Thomas Lengauer, Robert Endre Tarjan // 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. // ACM Transactions on Programming Languages and Systems (TOPLAS). <20> 1979. <20> Vol. 1, no. 1. <20> Pp. 121<32>141.
namespace SAPFOR { namespace SAPFOR {

View File

@@ -22,7 +22,7 @@
#include "SgUtils.h" #include "SgUtils.h"
#include "../Sapfor.h" #include "../Sapfor.h"
#include "graph_loops_func.h" #include "graph_loops_func.h"
#include "LoopNesting/loop_transform.h" #include "../Transformations/LoopNesting/loop_transform.h"
#include "expr_transform.h" #include "expr_transform.h"
#include "graph_calls_func.h" #include "graph_calls_func.h"

View File

@@ -10,7 +10,7 @@
#include "../ParallelizationRegions/ParRegions.h" #include "../ParallelizationRegions/ParRegions.h"
#include "../Distribution/Arrays.h" #include "../Distribution/Arrays.h"
#include "LoopNesting/loop_transform.h" #include "../Transformations/LoopNesting/loop_transform.h"
#include "errors.h" #include "errors.h"
#include "directive_parser.h" #include "directive_parser.h"

View File

@@ -15,7 +15,7 @@
#include "SgUtils.h" #include "SgUtils.h"
#include "expr_transform.h" #include "expr_transform.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
#include "shadow.h" #include "shadow.h"
#include "dvm.h" #include "dvm.h"

View File

@@ -241,15 +241,13 @@ static void findArrayRefs (SgExpression* ex, SgStatement* st, string fName, int
itNew->second.first->SetRegionPlace(reg); itNew->second.first->SetRegionPlace(reg);
const auto oldVal = itNew->second.first->GetDistributeFlagVal(); const auto oldVal = itNew->second.first->GetDistributeFlagVal();
bool isArrayInModule = (itNew->second.first->GetLocation().first == DIST::l_MODULE); bool isarrayInModule = (itNew->second.first->GetLocation().first == DIST::l_MODULE);
if (oldVal == DIST::DISTR || oldVal == DIST::NO_DISTR) if (oldVal == DIST::DISTR || oldVal == DIST::NO_DISTR)
{ {
if (itNew->second.first->IsOmpThreadPrivate()) if (itNew->second.first->IsOmpThreadPrivate())
itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV);
else if (deprecatedByIO.find(symb->identifier()) != deprecatedByIO.end()) else if (privates.find(symb->identifier()) != privates.end() || isarrayInModule)
itNew->second.first->SetDistributeFlag(DIST::IO_PRIV);
else if (isArrayInModule || privates.find(symb->identifier()) != privates.end())
{ {
//check in module //check in module
if (itNew->second.first->GetLocation().first == DIST::l_MODULE) if (itNew->second.first->GetLocation().first == DIST::l_MODULE)
@@ -276,6 +274,8 @@ static void findArrayRefs (SgExpression* ex, SgStatement* st, string fName, int
else else
itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV);
} }
else if (deprecatedByIO.find(symb->identifier()) != deprecatedByIO.end())
itNew->second.first->SetDistributeFlag(DIST::IO_PRIV);
else if (isSgConstantSymb(symb) || inDataStat) else if (isSgConstantSymb(symb) || inDataStat)
itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV); itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV);
else else

View File

@@ -11,9 +11,9 @@
#include "DvmhRegionInserter.h" #include "DvmhRegionInserter.h"
#include "DvmhRegions/RegionsMerger.h" #include "DvmhRegions/RegionsMerger.h"
#include "../VerificationCode/verifications.h" #include "../VerificationCode/verifications.h"
#include "../Transformations/FunctionPurifying/function_purifying.h"
#include "../LoopAnalyzer/loop_analyzer.h" #include "../LoopAnalyzer/loop_analyzer.h"
#include "../DirectiveProcessing/directive_parser.h" #include "../DirectiveProcessing/directive_parser.h"
#include "FunctionPurifying/function_purifying.h"
using namespace std; using namespace std;
@@ -794,6 +794,154 @@ ArraySet DvmhRegionInserter::get_used_arrs_for_block(SgStatement* st, int usage_
return usages; return usages;
} }
static bool filterFromList(SgStatement* st, const set<string>& idents, bool exclude = false)
{
bool empty = false;
SgExpression* list = st->expr(0);
vector<SgExpression*> newList;
int total = 0;
while (list)
{
if (exclude)
{
if (idents.find(list->lhs()->symbol()->identifier()) == idents.end())
newList.push_back(list->lhs());
}
else
{
if (idents.find(list->lhs()->symbol()->identifier()) != idents.end())
newList.push_back(list->lhs());
}
total++;
list = list->rhs();
}
if (newList.size() == 0)
empty = true;
else if (total != newList.size())
st->setExpression(0, makeExprList(newList));
return empty;
}
static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
{
string oldFile = current_file->filename();
if (!func->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto copy = duplicateProcedure(func, NULL, false, false, false, true);
const set<string> idents(pars.identificators.begin(), pars.identificators.end());
bool need = (func->symbol()->identifier() == string("bl182"));
//remove all exec
SgStatement* st = copy->lexNext();
SgStatement* last = copy->lastNodeOfStmt();
vector<SgStatement*> toExtract;
while (st != last)
{
if (isDVM_stat(st) || isSPF_stat(st))
{
if (st->variant() != ACC_ROUTINE_DIR)
{
toExtract.push_back(st);
st = st->lexNext();
}
else
st = st->lexNext();
}
else if (isSgExecutableStatement(st))
{
SgStatement* next = st->lastNodeOfStmt();
if (next != last)
next = next->lexNext();
toExtract.push_back(st);
st = next;
}
else
st = st->lexNext();
}
//remove unused declarations
st = copy->lexNext();
while (st != last)
{
const int var = st->variant();
if (var == VAR_DECL
|| var == VAR_DECL_90
|| var == DIM_STAT
|| var == INTENT_STMT
|| var == EXTERN_STAT)
{
bool empty = filterFromList(st, idents);
if (empty)
{
toExtract.push_back(st);
st = st->lexNext();
continue;
}
}
else if (!isDVM_stat(st) && !isSPF_stat(st))
toExtract.push_back(st);
if (st->variant() == CONTAINS_STMT)
break;
st = st->lexNext();
}
for (auto& elem : toExtract)
elem->extractStmt();
string retVal = copy->unparse();
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return retVal;
}
static void insertInterface(SgStatement* func, const string& iface, const string& fName)
{
string oldFile = current_file->filename();
if (!func->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* st = func->lexNext();
SgStatement* last = func->lastNodeOfStmt();
while (st != last)
{
if (st->variant() == VAR_DECL || st->variant() == VAR_DECL_90)
{
bool empty = filterFromList(st, { fName }, true);
if (empty)
{
SgStatement* next = st->lexNext();
st->extractStmt();
st = next;
continue;
}
}
if (isSgExecutableStatement(st))
break;
st = st->lexNext();
}
SgStatement* ifaceBlock = new SgStatement(INTERFACE_STMT);
addControlEndToStmt(ifaceBlock->thebif);
ifaceBlock->setlineNumber(getNextNegativeLineNumber()); // st->lineNumber()
ifaceBlock->setFileName(st->fileName());
st->insertStmtBefore(*ifaceBlock, *st->controlParent());
ifaceBlock->lastNodeOfStmt()->addComment(iface.c_str());
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
static LoopGraph* getParallelLoop(LoopGraph* loop) static LoopGraph* getParallelLoop(LoopGraph* loop)
{ {
auto prev_st = loop->loop->lexPrev(); auto prev_st = loop->loop->lexPrev();
@@ -1024,7 +1172,7 @@ static bool isPure(SgStatement* func)
void DvmhRegionInserter::createInterfaceBlockForOutCall(FuncInfo* func, FuncInfo* callFrom) void DvmhRegionInserter::createInterfaceBlockForOutCall(FuncInfo* func, FuncInfo* callFrom)
{ {
insertInterface(func->funcPointer, callFrom); insertInterface(func->funcPointer, getInterfaceBlock(callFrom->funcPointer->GetOriginal(), callFrom->funcParams), callFrom->funcName);
} }
void DvmhRegionInserter::createInterfaceBlockForParallelFunctions(bool onlyRoutine) void DvmhRegionInserter::createInterfaceBlockForParallelFunctions(bool onlyRoutine)
@@ -1297,10 +1445,7 @@ static set<DIST::Array*>
{ {
declStat = SgStatement::getStatementByFileAndLine(decl.first, decl.second); declStat = SgStatement::getStatementByFileAndLine(decl.first, decl.second);
if (declStat == NULL) // check in inlcudes if (declStat == NULL) // check in inlcudes
{ {
if (!main->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto st = main; st != main->lastNodeOfStmt() && !declStat; st = st->lexNext()) for (auto st = main; st != main->lastNodeOfStmt() && !declStat; st = st->lexNext())
{ {
if (st->fileName() == decl.first && st->lineNumber() == decl.second) if (st->fileName() == decl.first && st->lineNumber() == decl.second)
@@ -1312,7 +1457,7 @@ static set<DIST::Array*>
} }
else else
{ {
declStat = getFuncStat(declStat, { BLOCK_DATA }); declStat = getFuncStat(declStat);
if (declStat != main) if (declStat != main)
{ {
declStat = NULL; declStat = NULL;

View File

@@ -14,7 +14,7 @@
#include "dvm.h" #include "dvm.h"
#include "graph_calls_func.h" #include "graph_calls_func.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
#include "graph_loops_func.h" #include "graph_loops_func.h"
#include "../DirectiveProcessing/directive_parser.h" #include "../DirectiveProcessing/directive_parser.h"
#include "SgUtils.h" #include "SgUtils.h"
@@ -779,20 +779,6 @@ static void checkSpecList(SgExpression *spec, FuncInfo* currF, const map<string,
} }
} }
static void checkInTypeDescription(SgExpression *ex, FuncInfo* currF, const map<string, int>& parNames)
{
if (ex)
{
if (ex->variant() == ARRAY_REF)
fillIn(currF, ex->lhs(), parNames, false);
else
{
checkInTypeDescription(ex->lhs(), currF, parNames);
checkInTypeDescription(ex->rhs(), currF, parNames);
}
}
}
static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, const set<SgStatement*>& activeOps) static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, const set<SgStatement*>& activeOps)
{ {
if (currF->funcParams.countOfPars == 0) if (currF->funcParams.countOfPars == 0)
@@ -812,13 +798,8 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co
if (st->variant() == ENTRY_STAT) if (st->variant() == ENTRY_STAT)
continue; continue;
if (isSgExecutableStatement(st) == NULL) {
checkInTypeDescription(st->expr(0), currF, parNames);
continue;
}
if (st->lineNumber() <= 0) if (isSgExecutableStatement(st) == NULL || st->lineNumber() <= 0)
continue; continue;
if (activeOps.size() && activeOps.find(st) == activeOps.end()) if (activeOps.size() && activeOps.find(st) == activeOps.end())

View File

@@ -31,7 +31,7 @@
#include "../DirectiveProcessing/directive_parser.h" #include "../DirectiveProcessing/directive_parser.h"
#include "../DynamicAnalysis/gCov_parser_func.h" #include "../DynamicAnalysis/gCov_parser_func.h"
#include "VectorAssignToLoop/array_assign_to_loop.h" #include "../Transformations/VectorAssignToLoop/array_assign_to_loop.h"
using std::vector; using std::vector;
using std::map; using std::map;

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

@@ -48,7 +48,7 @@ extern int passDone;
#include "../VisualizerCalls/get_information.h" #include "../VisualizerCalls/get_information.h"
#include "../VisualizerCalls/SendMessage.h" #include "../VisualizerCalls/SendMessage.h"
#include "LoopEndDoConverter/enddo_loop_converter.h" #include "../Transformations/LoopEndDoConverter/enddo_loop_converter.h"
#include "../DirectiveProcessing/remote_access.h" #include "../DirectiveProcessing/remote_access.h"
#include "../DirectiveProcessing/directive_omp_parser.h" #include "../DirectiveProcessing/directive_omp_parser.h"

View File

@@ -18,7 +18,7 @@
#include "../DirectiveProcessing/insert_directive.h" #include "../DirectiveProcessing/insert_directive.h"
#include "SgUtils.h" #include "SgUtils.h"
#include "expr_transform.h" #include "expr_transform.h"
#include "FunctionPurifying/function_purifying.h" #include "../Transformations/FunctionPurifying/function_purifying.h"
using std::map; using std::map;
using std::pair; using std::pair;

View File

@@ -22,7 +22,7 @@
#include "graph_loops_func.h" #include "graph_loops_func.h"
#include "expr_transform.h" #include "expr_transform.h"
#include "../LoopAnalyzer/loop_analyzer.h" #include "../LoopAnalyzer/loop_analyzer.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
#include "json.hpp" #include "json.hpp"

View File

@@ -12,7 +12,7 @@
#include "graph_calls.h" #include "graph_calls.h"
#include "private_analyzer.h" #include "private_analyzer.h"
#include "dvm.h" #include "dvm.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
using std::vector; using std::vector;

View File

@@ -11,11 +11,11 @@
#include "region.h" #include "region.h"
#include "SgUtils.h" #include "SgUtils.h"
#include "graph_loops.h" #include "graph_loops.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
using namespace std; using namespace std;
static void Collapse(Region* region) void Collapse(Region* region)
{ {
if (region->getBasickBlocks().empty()) if (region->getBasickBlocks().empty())
return; return;
@@ -121,7 +121,7 @@ static void SolveDataFlow(Region* DFG)
Collapse(DFG); Collapse(DFG);
} }
map<LoopGraph*, ArrayAccessingIndexes> FindPrivateArrays(map<string, vector<LoopGraph*>> &loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) map<LoopGraph*, ArrayAccessingIndexes> findPrivateArrays(map<string, vector<LoopGraph*>> &loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
{ {
map<LoopGraph*, ArrayAccessingIndexes> result; map<LoopGraph*, ArrayAccessingIndexes> result;
for (const auto& [loopName, loops] : loopGraph) for (const auto& [loopName, loops] : loopGraph)

View File

@@ -5,8 +5,10 @@
#include <unordered_set> #include <unordered_set>
#include "range_structures.h" #include "range_structures.h"
#include "region.h"
#include "graph_loops.h" #include "graph_loops.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
std::map<LoopGraph*, ArrayAccessingIndexes> FindPrivateArrays(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR); 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); std::pair<SAPFOR::BasicBlock*, std::unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const std::vector<SAPFOR::BasicBlock*> blocks);

View File

@@ -6,7 +6,7 @@
#include <string> #include <string>
#include "graph_loops.h" #include "graph_loops.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
class Region : public SAPFOR::BasicBlock { class Region : public SAPFOR::BasicBlock {
public: public:

View File

@@ -403,7 +403,7 @@ static int convertFile(int argc, char* argv[], const set<string>& filesInProj, c
fprintf(stderr, "<<<<< Unparsing %s >>>>>\n", fout_name); fprintf(stderr, "<<<<< Unparsing %s >>>>>\n", fout_name);
if (mod_gpu) /*ACC*/ if (mod_gpu) /*ACC*/
UnparseTo_CufAndCu_Files(file, fout_cuf, fout_C_cu, fout_info, fout_name); UnparseTo_CufAndCu_Files(file, fout_cuf, fout_C_cu, fout_info);
const string fileN = file->filename(); const string fileN = file->filename();
set<SgStatement*> toRemove; set<SgStatement*> toRemove;

View File

@@ -40,6 +40,7 @@
#include "ProjectManipulation/ConvertFiles.h" #include "ProjectManipulation/ConvertFiles.h"
#include "LoopAnalyzer/loop_analyzer.h" #include "LoopAnalyzer/loop_analyzer.h"
#include "LoopAnalyzer/implicit_loops_analyzer.h"
#include "GraphCall/graph_calls_func.h" #include "GraphCall/graph_calls_func.h"
#include "GraphLoop/graph_loops_func.h" #include "GraphLoop/graph_loops_func.h"
@@ -89,13 +90,13 @@
#include "Transformations/DeadCodeRemoving/dead_code.h" #include "Transformations/DeadCodeRemoving/dead_code.h"
#include "Transformations/RenameSymbols/rename_symbols.h" #include "Transformations/RenameSymbols/rename_symbols.h"
#include "Transformations/FunctionInlining/inliner.h" #include "Transformations/FunctionInlining/inliner.h"
#include "Transformations/SwapOperators/swap_operators.h"
#include "ProjectParameters/projectParameters.h" #include "ProjectParameters/projectParameters.h"
#include "CFGraph/IR.h" #include "CFGraph/IR.h"
#include "CFGraph/RD_subst.h" #include "CFGraph/RD_subst.h"
#include "CFGraph/CFGraph.h" #include "CFGraph/CFGraph.h"
#include "CFGraph/IR_SSAForm.h"
#include "CFGraph/live_variable_analysis.h" #include "CFGraph/live_variable_analysis.h"
#include "CFGraph/private_variables_analysis.h" #include "CFGraph/private_variables_analysis.h"
@@ -940,8 +941,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
internalExit = err; internalExit = err;
} }
} }
else if (curr_regime == SWAP_OPERATORS)
runSwapOperators(file, loopGraph, fullIR, countOfTransform);
else if (curr_regime == PRIVATE_REMOVING_ANALYSIS) else if (curr_regime == PRIVATE_REMOVING_ANALYSIS)
{ {
auto itFound = loopGraph.find(file->filename()); auto itFound = loopGraph.find(file->filename());
@@ -1022,8 +1021,19 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
if(func->funcPointer->variant() != ENTRY_STAT) if(func->funcPointer->variant() != ENTRY_STAT)
countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks); countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
} }
else if (curr_regime == BUILD_IR_SSA_FORM)
{
auto irFound = getIRByFilename(fullIR, file_name);
buildFuncIRSSAForm(irFound, fullIR[irFound], fullIR_SSA);
}
else if (curr_regime == FIND_IMPLICIT_LOOPS)
{
auto itFound = loopGraph.find(file_name);
auto irFound = getIRByFilename(fullIR_SSA, file_name);
findImplicitLoops(fullIR_SSA[irFound], itFound->second);
}
else if (curr_regime == FIND_PRIVATE_ARRAYS) else if (curr_regime == FIND_PRIVATE_ARRAYS)
FindPrivateArrays(loopGraph, fullIR); findPrivateArrays(loopGraph, fullIR);
else if (curr_regime == TEST_PASS) else if (curr_regime == TEST_PASS)
{ {
//test pass //test pass
@@ -1040,8 +1050,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
PRIVATE_REMOVING, PRIVATE_REMOVING,
PRIVATE_ARRAYS_EXPANSION, PRIVATE_ARRAYS_EXPANSION,
PRIVATE_ARRAYS_SHRINKING, PRIVATE_ARRAYS_SHRINKING,
REMOVE_DEAD_CODE, REMOVE_DEAD_CODE };
SWAP_OPERATORS };
if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end()) if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end())
{ {
@@ -1285,6 +1294,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
detectCopies(allFuncInfo); detectCopies(allFuncInfo);
fillInterfaceBlock(allFuncInfo); fillInterfaceBlock(allFuncInfo);
intentInsertToInterfaces(allFuncInfo); intentInsertToInterfaces(allFuncInfo);
createInterfacesForAssumedSize(allFuncInfo);
//this call is only for testing //this call is only for testing
//setPureStatus(allFuncInfo); //setPureStatus(allFuncInfo);
@@ -1918,8 +1928,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
calculateStatsForPredictor(allFuncInfo, gCovInfo); calculateStatsForPredictor(allFuncInfo, gCovInfo);
parseDvmDirForPredictor(declaredArrays, commonBlocks, allFuncInfo, gCovInfo); parseDvmDirForPredictor(declaredArrays, commonBlocks, allFuncInfo, gCovInfo);
} }
else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS)
transformAssumedSizeParameters(allFuncInfo);
const float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - timeForPass).count() / 1000.; const float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - timeForPass).count() / 1000.;
const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.; const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.;
@@ -2155,8 +2163,6 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
runAnalysis(*project, REMOVE_COPIES, false); runAnalysis(*project, REMOVE_COPIES, false);
runAnalysis(*project, SWAP_LOOPS, false); runAnalysis(*project, SWAP_LOOPS, false);
runPass(TRANSFORM_ASSUMED_SIZE_PARAMETERS, proj_name, folderName);
if (folderName || consoleMode) if (folderName || consoleMode)
runAnalysis(*project, UNPARSE_FILE, true, additionalName.c_str(), folderName); runAnalysis(*project, UNPARSE_FILE, true, additionalName.c_str(), folderName);
} }
@@ -2338,7 +2344,6 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case INSERT_NO_DISTR_FLAGS_FROM_GUI: case INSERT_NO_DISTR_FLAGS_FROM_GUI:
case PRIVATE_REMOVING: case PRIVATE_REMOVING:
case RENAME_INLCUDES: case RENAME_INLCUDES:
case SWAP_OPERATORS:
runAnalysis(*project, curr_regime, true, "", folderName); runAnalysis(*project, curr_regime, true, "", folderName);
break; break;
case INLINE_PROCEDURES: case INLINE_PROCEDURES:
@@ -2640,10 +2645,7 @@ int main(int argc, char **argv)
} }
if (curr_regime == INSERT_PARALLEL_DIRS_NODIST) if (curr_regime == INSERT_PARALLEL_DIRS_NODIST)
{
ignoreArrayDistributeState = true; ignoreArrayDistributeState = true;
sharedMemoryParallelization = 1;
}
if (runAsClient) if (runAsClient)
{ {

View File

@@ -122,8 +122,6 @@ enum passes {
CREATE_INTER_TREE, CREATE_INTER_TREE,
INSERT_INTER_TREE, INSERT_INTER_TREE,
SWAP_OPERATORS,
SHADOW_GROUPING, SHADOW_GROUPING,
INLINE_PROCEDURES, INLINE_PROCEDURES,
FILL_PARALLEL_REG_IR, FILL_PARALLEL_REG_IR,
@@ -184,11 +182,11 @@ enum passes {
SET_IMPLICIT_NONE, SET_IMPLICIT_NONE,
RENAME_INLCUDES, RENAME_INLCUDES,
FIND_IMPLICIT_LOOPS,
BUILD_IR_SSA_FORM,
FIND_PRIVATE_ARRAYS, FIND_PRIVATE_ARRAYS,
TRANSFORM_ASSUMED_SIZE_PARAMETERS,
TEST_PASS, TEST_PASS,
EMPTY_PASS EMPTY_PASS
}; };
@@ -321,7 +319,6 @@ static void setPassValues()
passNames[CHECK_PAR_REG_DIR] = "CHECK_PAR_REG_DIR"; passNames[CHECK_PAR_REG_DIR] = "CHECK_PAR_REG_DIR";
passNames[CREATE_INTER_TREE] = "CREATE_INTER_TREE"; passNames[CREATE_INTER_TREE] = "CREATE_INTER_TREE";
passNames[INSERT_INTER_TREE] = "INSERT_INTER_TREE"; passNames[INSERT_INTER_TREE] = "INSERT_INTER_TREE";
passNames[SWAP_OPERATORS] = "SWAP_OPERATORS";
passNames[CREATE_PARALLEL_REGIONS] = "CREATE_PARALLEL_REGIONS"; passNames[CREATE_PARALLEL_REGIONS] = "CREATE_PARALLEL_REGIONS";
passNames[PRIVATE_REMOVING_ANALYSIS] = "PRIVATE_REMOVING_ANALYSIS"; passNames[PRIVATE_REMOVING_ANALYSIS] = "PRIVATE_REMOVING_ANALYSIS";
passNames[PRIVATE_REMOVING] = "PRIVATE_REMOVING"; passNames[PRIVATE_REMOVING] = "PRIVATE_REMOVING";
@@ -374,10 +371,10 @@ static void setPassValues()
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE"; passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
passNames[RENAME_INLCUDES] = "RENAME_INLCUDES"; passNames[RENAME_INLCUDES] = "RENAME_INLCUDES";
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI"; passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
passNames[FIND_IMPLICIT_LOOPS] = "FIND_IMPLICIT_LOOPS";
passNames[BUILD_IR_SSA_FORM] = "BUILD_IR_SSA_FORM";
passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS"; passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS";
passNames[TRANSFORM_ASSUMED_SIZE_PARAMETERS] = "TRANSFORM_ASSUMED_SIZE_PARAMETERS";
passNames[TEST_PASS] = "TEST_PASS"; passNames[TEST_PASS] = "TEST_PASS";
} }

View File

@@ -181,3 +181,7 @@ bool passNamesWasInit = false;
std::map<PTR_BFND, std::pair<std::string, int>> sgStats; std::map<PTR_BFND, std::pair<std::string, int>> sgStats;
std::map<PTR_LLND, std::pair<std::string, int>> sgExprs; std::map<PTR_LLND, std::pair<std::string, int>> sgExprs;
//for FIND_IMPLICIT_LOOPS and BUILD_IR_SSA_FORM
map<FuncInfo*, vector<SAPFOR::BasicBlock*>> fullIR_SSA;
//

View File

@@ -6,7 +6,7 @@
#include <set> #include <set>
#include <algorithm> #include <algorithm>
#include "../CFGraph/CFGraph.h" #include "../../CFGraph/CFGraph.h"
using std::map; using std::map;
using std::string; using std::string;

View File

@@ -4,10 +4,10 @@
#include<vector> #include<vector>
#include "SgUtils.h" #include "SgUtils.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
#include "CFGraph/live_variable_analysis.h" #include "../CFGraph/live_variable_analysis.h"
#include "CFGraph/DataFlow/data_flow.h" #include "../CFGraph/DataFlow/data_flow.h"
#include "CFGraph/DataFlow/backward_data_flow.h" #include "../CFGraph/DataFlow/backward_data_flow.h"
int removeDeadCode(SgStatement* func, int removeDeadCode(SgStatement* func,
const std::map<std::string, std::vector<FuncInfo*>>&allFuncs, const std::map<std::string, std::vector<FuncInfo*>>&allFuncs,

View File

@@ -440,18 +440,15 @@ bool replaceConstantRec(SgExpression *&exp)
if (exp->variant() == CONST_REF) if (exp->variant() == CONST_REF)
{ {
SgExpression *ret = ReplaceParameter_(exp); SgExpression *ret = ReplaceParameter_(exp);
int sign = 1; int sign = 1;
SgExpression* toCalc = ret; SgExpression* toCalc = ret;
if (toCalc->variant() == UNARY_ADD_OP) if (ret->variant() == UNARY_ADD_OP)
toCalc = toCalc->lhs(); toCalc = ret->lhs();
if (ret->variant() == MINUS_OP)
if (toCalc->variant() == MINUS_OP)
{ {
toCalc = toCalc->lhs(); toCalc = ret->lhs();
sign = -1; sign = -1;
} }
if (toCalc->isInteger()) if (toCalc->isInteger())
{ {
exp = new SgValueExp(sign * toCalc->valueInteger()); exp = new SgValueExp(sign * toCalc->valueInteger());

View File

@@ -66,7 +66,7 @@ void insertIntrinsicStat(const vector<FuncInfo*>& allFuncInfo)
void* ptr = call.pointerDetailCallsFrom.first; void* ptr = call.pointerDetailCallsFrom.first;
int var = call.pointerDetailCallsFrom.second; int var = call.pointerDetailCallsFrom.second;
SgSymbol* s = NULL; SgSymbol* s = NULL;
if (var == PROC_STAT) if (var == PROC_STAT)
s = ((SgStatement*)ptr)->symbol(); s = ((SgStatement*)ptr)->symbol();
@@ -103,7 +103,7 @@ void insertIntrinsicStat(const vector<FuncInfo*>& allFuncInfo)
if (line <= 0) if (line <= 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
intr->setlineNumber(getNextNegativeLineNumber()); intr->setlineNumber(line);
st->insertStmtBefore(*intr, *func->funcPointer); st->insertStmtBefore(*intr, *func->funcPointer);
} }
else else
@@ -126,7 +126,7 @@ bool checkOutCalls(const set<string>& outCalls)
return false; return false;
} }
void createInterfacesForOutCalls(FuncInfo* func) void createInterfacesForOutCalls(FuncInfo* func)
{ {
if (func->isPure && !func->isMain) if (func->isPure && !func->isMain)
{ {
@@ -136,41 +136,33 @@ void createInterfacesForOutCalls(FuncInfo* func)
} }
} }
static bool changeIfHasStarRange(SgExpression* arrayDecl, SgStatement* scope, vector<SgSymbol*>& parNames) static bool changeIfHasStarRange(SgExpression* arrayDecl, bool doReplace = false)
{ {
SgExpression* list = arrayDecl->lhs(); SgExpression* list = arrayDecl->lhs();
string varN = arrayDecl->symbol()->identifier() + string("_sz"); bool has = doReplace;
bool has = false;
SgExpression* allDimsBefore = NULL;
while (list) while (list)
{ {
const int var = list->lhs()->variant(); const int var = list->lhs()->variant();
if (var == STAR_RANGE) if (var == STAR_RANGE)
{
has = true; has = true;
parNames.push_back(new SgSymbol(VARIABLE_NAME, varN.c_str(), SgTypeInt(), scope));
SgExpression* par = allDimsBefore ? &(*new SgVarRefExp(parNames.back()) / *allDimsBefore) : (new SgVarRefExp(parNames.back()));
list->setLhs(par);
break;
}
else
{
if (allDimsBefore == NULL)
allDimsBefore = list->lhs();
else
allDimsBefore = &(*allDimsBefore * *list->lhs()->copyPtr());
}
list = list->rhs(); list = list->rhs();
} }
if (has)
{
list = arrayDecl->lhs();
while (list)
{
list->setLhs(new SgExpression(DDOT));
list = list->rhs();
}
}
return has; return has;
} }
/*static void removeExternalStat(SgStatement* func, const set<string>& addedInterfaceFor) static void removeExternalStat(SgStatement* func, const set<string>& addedInterfaceFor)
{ {
vector<SgStatement*> toRem; vector<SgStatement*> toRem;
for (auto st = func; st != func->lastNodeOfStmt(); st = st->lexNext()) for (auto st = func; st != func->lastNodeOfStmt(); st = st->lexNext())
@@ -205,7 +197,7 @@ static bool changeIfHasStarRange(SgExpression* arrayDecl, SgStatement* scope, ve
for (auto& rem : toRem) for (auto& rem : toRem)
rem->deleteStmt(); rem->deleteStmt();
}*/ }
template<typename T> template<typename T>
static vector<FuncInfo*> sortByName(const T &funcs) static vector<FuncInfo*> sortByName(const T &funcs)
@@ -218,25 +210,9 @@ static vector<FuncInfo*> sortByName(const T &funcs)
return funcList; return funcList;
} }
static bool hasDvmParallel(SgStatement *func) void createInterfacesForAssumedSize(const map<string, vector<FuncInfo*>>& allFuncInfo)
{ {
for (auto st = func; st != func->lastNodeOfStmt(); st = st->lexNext()) set<FuncInfo*> hasAssumedSizeArrays;
{
const int var = st->variant();
if (var == DVM_PARALLEL_ON_DIR || var == ACC_REGION_DIR ||
var == ACC_ACTUAL_DIR || var == ACC_GET_ACTUAL_DIR)
return true;
if (st->variant() == CONTAINS_STMT)
break;
}
return false;
}
void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFuncInfo)
{
map<string, vector<int>> assumedSizeArraysByFunc;
for (auto& funcByFile : allFuncInfo) for (auto& funcByFile : allFuncInfo)
{ {
@@ -244,17 +220,11 @@ void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFun
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& func : funcByFile.second) for (auto& func : funcByFile.second)
{ {
SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal()); SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal());
if (prog == NULL) if (prog == NULL)
continue; continue;
if (!hasDvmParallel(prog))
continue;
vector<SgSymbol*> parNames;
SgStatement* scope = prog->getScopeForDeclare();
vector<SgExpression*> arrayRefs; vector<SgExpression*> arrayRefs;
bool hasRefs = false; bool hasRefs = false;
for (int z = 0; z < func->funcParams.countOfPars; ++z) for (int z = 0; z < func->funcParams.countOfPars; ++z)
@@ -274,8 +244,13 @@ void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFun
{ {
if (list->lhs() && list->lhs()->symbol()->identifier() == name) if (list->lhs() && list->lhs()->symbol()->identifier() == name)
{ {
if (changeIfHasStarRange(list->lhs(), scope, parNames)) if (changeIfHasStarRange(list->lhs()))
assumedSizeArraysByFunc[func->funcName].push_back(z); {
hasRefs = true;
hasAssumedSizeArrays.insert(func);
}
else
arrayRefs.push_back(list->lhs());
break; break;
} }
list = list->rhs(); list = list->rhs();
@@ -284,20 +259,13 @@ void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFun
} }
} }
if (parNames.size()) if (hasRefs)
{ for (auto& ref : arrayRefs)
SgProcHedrStmt* proc = isSgProcHedrStmt(func->funcPointer->GetOriginal()); changeIfHasStarRange(ref, true);
checkNull(proc, convertFileName(__FILE__).c_str(), __LINE__);
//makeDeclaration(parNames, scope);
for (auto& newPar : parNames)
proc->AddArg(*new SgVarRefExp(newPar));
}
} }
} }
if (assumedSizeArraysByFunc.size() == 0) if (hasAssumedSizeArrays.size() == 0)
return; return;
for (auto& funcByFile : allFuncInfo) for (auto& funcByFile : allFuncInfo)
@@ -305,61 +273,27 @@ void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFun
if (SgFile::switchToFile(funcByFile.first) == -1) if (SgFile::switchToFile(funcByFile.first) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgSymbol* funcSize = new SgSymbol(FUNCTION_NAME, "size");
for (auto& func : sortByName(funcByFile.second)) for (auto& func : sortByName(funcByFile.second))
{ {
SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal()); SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal());
if (prog == NULL) if (prog == NULL)
continue; continue;
for (auto& detailedCall : func->callsFromDetailed) set<string> addedInterfaceFor;
for (auto& elem : sortByName(func->callsFromV))
{ {
auto it = assumedSizeArraysByFunc.find(detailedCall.detailCallsFrom.first); auto it = hasAssumedSizeArrays.find(elem);
if (it != assumedSizeArraysByFunc.end()) if (it != hasAssumedSizeArrays.end())
{ {
auto pointer = detailedCall.pointerDetailCallsFrom; auto callFrom = *it;
DvmhRegionInserter::createInterfaceBlockForOutCall(func, callFrom);
SgExpression* list = NULL; addedInterfaceFor.insert(callFrom->funcName);
if (pointer.second == FUNC_CALL)
{
SgExpression* p = (SgExpression*)pointer.first;
list = p->lhs();
}
else
{
SgStatement* p = (SgStatement*)pointer.first;
list = p->expr(0);
}
SgExpression* last = list;
vector<SgExpression*> pars;
while (list)
{
last = list;
pars.push_back(list->lhs());
list = list->rhs();
}
for (int z = 0; z < it->second.size(); ++z)
{
int parNum = it->second[z];
if (parNum >= pars.size())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
//TODO: need to do it better
SgExpression* parArray = pars[parNum]->copyPtr();
parArray->setLhs(NULL);
parArray->setRhs(NULL);
SgFunctionCallExp* call = new SgFunctionCallExp(*funcSize, *parArray);
last->setRhs(new SgExpression(EXPR_LIST, call));
last = last->rhs();
}
} }
} }
}
if (addedInterfaceFor.size())
removeExternalStat(prog, addedInterfaceFor);
}
} }
} }
@@ -379,7 +313,7 @@ static void setPureStatus(FuncInfo* func)
bool hasIO = func->linesOfIO.size() || func->linesOfStop.size(); bool hasIO = func->linesOfIO.size() || func->linesOfStop.size();
if (!hasPure && !hasIO && ((isFunc == false) || (isFunc && hasOut == false))) if (!hasPure && !hasIO && ((isFunc == false) || (isFunc && hasOut == false)))
{ {
header->setExpression(2, new SgExpression(PURE_OP)); header->setExpression(2, new SgExpression(PURE_OP));
header->symbol()->setAttribute(header->symbol()->attributes() | PURE_BIT); header->symbol()->setAttribute(header->symbol()->attributes() | PURE_BIT);
} }
@@ -525,7 +459,7 @@ static void insertIntents(set<string>& identificators, SgStatement* header, cons
if (args.size()) if (args.size())
{ {
SgIntentStmt* intent = new SgIntentStmt(*makeExprList(args), *attr); SgIntentStmt* intent = new SgIntentStmt(*makeExprList(args), *attr);
intent->setlineNumber(getNextNegativeLineNumber()); intent->setlineNumber(lastDecl->lineNumber());
lastDecl->insertStmtAfter(*intent, (header == lastDecl) ? *header : *lastDecl->controlParent()); lastDecl->insertStmtAfter(*intent, (header == lastDecl) ? *header : *lastDecl->controlParent());
} }
@@ -593,7 +527,7 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
OutIdentificators.insert(ident); OutIdentificators.insert(ident);
} }
//remove conflicted intents //remove conflicted intents
for (auto& entry : func->entry) for (auto& entry : func->entry)
{ {
for (int i = 0; i < entry->funcParams.countOfPars; i++) for (int i = 0; i < entry->funcParams.countOfPars; i++)
@@ -624,11 +558,11 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
} }
insertIntents(InOutIdentificators, headerSt, parSym, INOUT_OP, INOUT_BIT); insertIntents(InOutIdentificators, headerSt, parSym, INOUT_OP, INOUT_BIT);
insertIntents(InIdentificators, headerSt, parSym, IN_OP, IN_BIT); insertIntents(InIdentificators, headerSt, parSym, IN_OP, IN_BIT);
insertIntents(OutIdentificators, headerSt, parSym, OUT_OP, OUT_BIT); insertIntents(OutIdentificators, headerSt, parSym, OUT_OP, OUT_BIT);
} }
void intentInsert(const vector<FuncInfo*>& allFuncInfo) void intentInsert(const vector<FuncInfo*>& allFuncInfo)
{ {
for (auto& func : allFuncInfo) for (auto& func : allFuncInfo)
{ {
@@ -697,7 +631,7 @@ static void collectForChange(set<FuncInfo*>& allForChange, FuncInfo* start)
for (auto& call : elem->callsFromV) for (auto& call : elem->callsFromV)
if (allForChange.find(call) == allForChange.end()) if (allForChange.find(call) == allForChange.end())
newAdd.insert(call); newAdd.insert(call);
chagned = newAdd.size() != 0; chagned = newAdd.size() != 0;
allForChange.insert(newAdd.begin(), newAdd.end()); allForChange.insert(newAdd.begin(), newAdd.end());
@@ -705,7 +639,7 @@ static void collectForChange(set<FuncInfo*>& allForChange, FuncInfo* start)
} }
template<typename CallExp> template<typename CallExp>
static void transferVarToArg(const map<string, vector<int>>& commonVarsUsed, const map<string, CommonBlock*>& commonBlocks, static void transferVarToArg(const map<string, vector<int>>& commonVarsUsed, const map<string, CommonBlock*>& commonBlocks,
const FuncInfo* curFunc, CallExp* callExp) const FuncInfo* curFunc, CallExp* callExp)
{ {
for (auto& common : commonVarsUsed) for (auto& common : commonVarsUsed)
@@ -789,7 +723,7 @@ static void transferCommons(set<FuncInfo*>& allForChange, map <FuncInfo*, map<st
{ {
SgFunctionCallExp* callExp = (SgFunctionCallExp*)call.first; SgFunctionCallExp* callExp = (SgFunctionCallExp*)call.first;
if (callExp->funName()->identifier() == precFunc->funcName) if (callExp->funName()->identifier() == precFunc->funcName)
transferVarToArg(commonVarsUsed, commonBlocks, curFunc, callExp); transferVarToArg(commonVarsUsed, commonBlocks, curFunc, callExp);
} }
else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT) else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT)
{ {
@@ -814,7 +748,7 @@ static void transferCommons(set<FuncInfo*>& allForChange, map <FuncInfo*, map<st
if (v == var) if (v == var)
done = true; done = true;
if (!done) if (!done)
{ {
funcCommons[curFunc][common.first].push_back(var); funcCommons[curFunc][common.first].push_back(var);
if (nextCommonVarsUsed.count(common.first) == 0) if (nextCommonVarsUsed.count(common.first) == 0)
@@ -832,7 +766,7 @@ static void transferCommons(set<FuncInfo*>& allForChange, map <FuncInfo*, map<st
{ {
bool uses = false; bool uses = false;
auto groupedVars = commonBlocks.find(common.first)->second->getGroupedVars(); auto groupedVars = commonBlocks.find(common.first)->second->getGroupedVars();
if (curFunc->commonBlocks.count(common.first) > 0) //rename common vars in funcs if (curFunc->commonBlocks.count(common.first) > 0) //rename common vars in funcs
{ {
uses = true; uses = true;
@@ -864,7 +798,7 @@ static void transferCommons(set<FuncInfo*>& allForChange, map <FuncInfo*, map<st
} }
} }
} }
} }
else if (!allForChange.count(curFunc)) //add of commons to main else if (!allForChange.count(curFunc)) //add of commons to main
{ {
SgExprListExp* res = NULL; SgExprListExp* res = NULL;
@@ -1027,13 +961,13 @@ void commonTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo, const map
if (func->commonBlocks.size() > 0 && st->variant() != PROG_HEDR) if (func->commonBlocks.size() > 0 && st->variant() != PROG_HEDR)
{ {
for (SgStatement* start = st, *end = st->lastNodeOfStmt(); start != end;) for (SgStatement* start = st, *end = st->lastNodeOfStmt(); start != end;)
{ {
if (start->variant() == CONTAINS_STMT) if (start->variant() == CONTAINS_STMT)
break; break;
SgStatement* next = start->lexNext(); SgStatement* next = start->lexNext();
if (start->variant() == COMM_STAT && string(start->fileName()) == func->fileName) if (start->variant() == COMM_STAT && string(start->fileName()) == func->fileName)
{ {
if (funcCommonDeclared.count(func) == 0) if (funcCommonDeclared.count(func) == 0)
funcCommonDeclared[func] = set<string>(); funcCommonDeclared[func] = set<string>();
@@ -1064,11 +998,11 @@ void commonTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo, const map
if (st->variant() < 0 || st->variant() == PROG_HEDR || func->isInterface) if (st->variant() < 0 || st->variant() == PROG_HEDR || func->isInterface)
continue; continue;
if (func->commonBlocks.size() > 0) if (func->commonBlocks.size() > 0)
{ {
map<string, vector<int>> commonVarsUsed; map<string, vector<int>> commonVarsUsed;
set<string> usedVars; set<string> usedVars;
for (SgStatement* start = st->lastDeclaration()->lexNext(), *end = st->lastNodeOfStmt(); start != end; start = start->lexNext()) for (SgStatement* start = st->lastDeclaration()->lexNext(), *end = st->lastNodeOfStmt(); start != end; start = start->lexNext())
{ {
if (start->variant() == CONTAINS_STMT) if (start->variant() == CONTAINS_STMT)
break; break;
@@ -1138,7 +1072,7 @@ static string changeData(const string& data, const map<string, string>& constSym
return res; return res;
} }
static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vector <SgSymbol*>& varsToTransfer, vector <string>& dataToTransfer, static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vector <SgSymbol*>& varsToTransfer, vector <string>& dataToTransfer,
FuncInfo* curFunc, FuncInfo* precFunc, FuncInfo* startFunc) FuncInfo* curFunc, FuncInfo* precFunc, FuncInfo* startFunc)
{ {
if (curFunc != precFunc) if (curFunc != precFunc)
@@ -1159,7 +1093,7 @@ static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vec
else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT) else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT)
{ {
SgCallStmt* callSt = (SgCallStmt*)call.first; SgCallStmt* callSt = (SgCallStmt*)call.first;
if (callSt->name()->identifier() == precFunc->funcName) if (callSt->name()->identifier() == precFunc->funcName)
for (auto& var : varsToTransfer) for (auto& var : varsToTransfer)
callSt->addArg(*new SgVarRefExp(*var)); callSt->addArg(*new SgVarRefExp(*var));
} }
@@ -1185,7 +1119,7 @@ static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vec
{ {
((SgProcHedrStmt*)(hedr))->AddArg(*new SgVarRefExp(var->copy())); ((SgProcHedrStmt*)(hedr))->AddArg(*new SgVarRefExp(var->copy()));
hedr->lexNext()->deleteStmt(); hedr->lexNext()->deleteStmt();
if (curFunc != startFunc || i!=0) if (curFunc != startFunc || i!=0)
{ {
vector<SgSymbol*> varVec = vector<SgSymbol*>(); vector<SgSymbol*> varVec = vector<SgSymbol*>();
varVec.push_back(var); varVec.push_back(var);
@@ -1225,7 +1159,7 @@ static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vec
for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext()) for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext())
{ {
if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && !strcmp(hedr->fileName(), start->fileName())) if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && !strcmp(hedr->fileName(), start->fileName()))
{ {
firstExDec = start; firstExDec = start;
break; break;
@@ -1264,7 +1198,7 @@ void saveTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
for (auto& byfile : allFuncInfo) for (auto& byfile : allFuncInfo)
for (auto& func : byfile.second) for (auto& func : byfile.second)
if (func->isMain) if (func->isMain)
start = func; start = func;
collectForChange(allForChange, start); collectForChange(allForChange, start);
allForChange.erase(start); allForChange.erase(start);
@@ -1306,8 +1240,8 @@ void saveTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
if (s->scope() == st) if (s->scope() == st)
{ {
if ( (s->attributes() & SAVE_BIT) || if ( (s->attributes() & SAVE_BIT) ||
(s->attributes() & DATA_BIT) || (s->attributes() & DATA_BIT) ||
allSave && s->variant() == VARIABLE_NAME && !params.count(s->identifier())) allSave && s->variant() == VARIABLE_NAME && !params.count(s->identifier()))
{ {
if ((s->type() ? s->type()->variant() : (T_COMPLEX + 1)) > T_COMPLEX) if ((s->type() ? s->type()->variant() : (T_COMPLEX + 1)) > T_COMPLEX)
@@ -1358,21 +1292,21 @@ void saveTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
SgExprListExp* attrsNoSave = new SgExprListExp(); SgExprListExp* attrsNoSave = new SgExprListExp();
bool needChange = false; bool needChange = false;
for (int i = 0; i < vst->numberOfAttributes(); i++) for (int i = 0; i < vst->numberOfAttributes(); i++)
{ {
if (vst->attribute(i)->variant() != SAVE_OP) if (vst->attribute(i)->variant() != SAVE_OP)
{ {
attrsNoSave->append(vst->attribute(i)->copy()); attrsNoSave->append(vst->attribute(i)->copy());
} }
else else
needChange = true; needChange = true;
} }
if (needChange) if (needChange)
{ {
SgVarDeclStmt* newVst; SgVarDeclStmt* newVst;
if (!attrsNoSave->length()) if (!attrsNoSave->length())
newVst = new SgVarDeclStmt(vst->varList()->copy(), *attrsNoSave, vst->type()->copy()); newVst = new SgVarDeclStmt(vst->varList()->copy(), *attrsNoSave, vst->type()->copy());
else else
newVst = new SgVarDeclStmt(vst->varList()->copy(), vst->type()->copy()); newVst = new SgVarDeclStmt(vst->varList()->copy(), vst->type()->copy());
@@ -1400,8 +1334,8 @@ void saveTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
} }
}*/ }*/
static string makeName(SgSymbol* var, map<SgSymbol*, set< SgSymbol*>>& modVarsToAdd, const set<string>& useMod, static string makeName(SgSymbol* var, map<SgSymbol*, set< SgSymbol*>>& modVarsToAdd, const set<string>& useMod,
const map<string, vector<pair<SgSymbol*, SgSymbol*>>>& modByUse, const map<string, vector<pair<SgSymbol*, SgSymbol*>>>& modByUse,
const map<string, vector<pair<SgSymbol*, SgSymbol*>>>& modByUseOnly) const map<string, vector<pair<SgSymbol*, SgSymbol*>>>& modByUseOnly)
{ {
string name = "", modName = OriginalSymbol(var)->scope()->symbol()->identifier(); string name = "", modName = OriginalSymbol(var)->scope()->symbol()->identifier();
@@ -1423,7 +1357,7 @@ static string makeName(SgSymbol* var, map<SgSymbol*, set< SgSymbol*>>& modVarsTo
} }
if (!name.length()) if (!name.length())
name = varOrName; name = varOrName;
} }
else if (mbuo) else if (mbuo)
{ {
@@ -1454,37 +1388,6 @@ static string makeName(SgSymbol* var, map<SgSymbol*, set< SgSymbol*>>& modVarsTo
return name; return name;
} }
static bool filterFromList(SgStatement* st, const set<string>& idents, bool exclude = false)
{
bool empty = false;
SgExpression* list = st->expr(0);
vector<SgExpression*> newList;
int total = 0;
while (list)
{
if (exclude)
{
if (idents.find(list->lhs()->symbol()->identifier()) == idents.end())
newList.push_back(list->lhs());
}
else
{
if (idents.find(list->lhs()->symbol()->identifier()) != idents.end())
newList.push_back(list->lhs());
}
total++;
list = list->rhs();
}
if (newList.size() == 0)
empty = true;
else if (total != newList.size())
st->setExpression(0, makeExprList(newList));
return empty;
}
static string getInterfaceBlock(SgStatement* func, const FuncParam& pars) static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
{ {
string oldFile = current_file->filename(); string oldFile = current_file->filename();
@@ -1492,21 +1395,22 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto copy = duplicateProcedure(func, NULL, false, false, false, true); auto copy = duplicateProcedure(func, NULL, false, false, false, true);
const set<string> idents(pars.identificators.begin(), pars.identificators.end());
const set<string> ident(pars.identificators.begin(), pars.identificators.end());
//remove all exec //remove all exec
SgStatement* st = copy->lexNext(); SgStatement* st = copy->lexNext();
SgStatement* last = copy->lastNodeOfStmt(); SgStatement* last = copy->lastNodeOfStmt();
vector<SgStatement*> toExtract; vector<SgStatement*> toExtract;
while (st != last) while (st != last)
{ {
if (isDVM_stat(st) || isSPF_stat(st)) if (isDVM_stat(st) || isSPF_stat(st))
{ {
if (st->variant() != ACC_ROUTINE_DIR) if (st->variant() != ACC_ROUTINE_DIR)
{ {
toExtract.push_back(st); SgStatement* next = st->lexNext();
st = st->lexNext(); st->extractStmt();
st = next;
} }
else else
st = st->lexNext(); st = st->lexNext();
@@ -1527,20 +1431,31 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
st = copy->lexNext(); st = copy->lexNext();
while (st != last) while (st != last)
{ {
const int var = st->variant(); if (st->variant() == VAR_DECL
|| st->variant() == VAR_DECL_90
if (var == VAR_DECL || var == VAR_DECL_90 || var == DIM_STAT || || st->variant() == DIM_STAT
var == INTENT_STMT || var == EXTERN_STAT) || st->variant() == INTENT_STMT)
{ {
bool empty = filterFromList(st, idents); SgExpression* list = st->expr(0);
if (empty) vector<SgExpression*> newList;
while (list)
{ {
if (ident.find(list->lhs()->symbol()->identifier()) != ident.end())
newList.push_back(list->lhs());
list = list->rhs();
}
if (newList.size() == 0)
{
SgStatement* next = st->lexNext();
toExtract.push_back(st); toExtract.push_back(st);
st = st->lexNext(); st = next;
continue; continue;
} }
else
st->setExpression(0, makeExprList(newList));
} }
else if (!isDVM_stat(st) && !isSPF_stat(st)) else
toExtract.push_back(st); toExtract.push_back(st);
if (st->variant() == CONTAINS_STMT) if (st->variant() == CONTAINS_STMT)
@@ -1551,56 +1466,16 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
for (auto& elem : toExtract) for (auto& elem : toExtract)
elem->extractStmt(); elem->extractStmt();
string codeString = copy->unparse(); string retVal = copy->unparse();
if (SgFile::switchToFile(oldFile) == -1) if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
//insert tabs
const string tab = " ";
const int countEnds = std::count(codeString.begin(), codeString.end(), '\n');
string retVal = " ";
retVal.reserve(retVal.size() + codeString.size() + countEnds * tab.size());
for (int z = 0, ends = 0; z < codeString.size(); ++z)
{
retVal += codeString[z];
if (codeString[z] == '\n')
{
ends++;
if (ends == countEnds)
continue;
int p = z + 1;
while (codeString[p] == ' ' && p < codeString.size())
++p;
auto start = p;
auto end = string::npos;
auto sub = codeString.find("subroutine", p);
auto func = codeString.find("function", p);
auto end_sub = codeString.find("end subroutine", p);
auto end_func = codeString.find("end function", p);
if (sub != end && sub == start || end_sub != end && end_sub == start ||
func != end && func == start || end_func != end && end_func == start)
{
retVal += " ";
}
else
retVal += tab;
}
}
return retVal; return retVal;
} }
void insertInterface(SgStatement* func, const FuncInfo *callFrom) static void insertInterface(SgStatement* func, const string& iface)
{ {
const string& iface = getInterfaceBlock(callFrom->funcPointer->GetOriginal(), callFrom->funcParams);
const string& fName = callFrom->funcName;
string oldFile = current_file->filename(); string oldFile = current_file->filename();
if (!func->switchToFile()) if (!func->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1609,18 +1484,6 @@ void insertInterface(SgStatement* func, const FuncInfo *callFrom)
SgStatement* last = func->lastNodeOfStmt(); SgStatement* last = func->lastNodeOfStmt();
while (st != last) while (st != last)
{ {
if (st->variant() == VAR_DECL || st->variant() == VAR_DECL_90)
{
bool empty = filterFromList(st, { fName }, true);
if (empty)
{
SgStatement* next = st->lexNext();
st->extractStmt();
st = next;
continue;
}
}
if (isSgExecutableStatement(st)) if (isSgExecutableStatement(st))
break; break;
st = st->lexNext(); st = st->lexNext();
@@ -1628,7 +1491,7 @@ void insertInterface(SgStatement* func, const FuncInfo *callFrom)
SgStatement* ifaceBlock = new SgStatement(INTERFACE_STMT); SgStatement* ifaceBlock = new SgStatement(INTERFACE_STMT);
addControlEndToStmt(ifaceBlock->thebif); addControlEndToStmt(ifaceBlock->thebif);
ifaceBlock->setlineNumber(getNextNegativeLineNumber()); ifaceBlock->setlineNumber(st->lineNumber());
ifaceBlock->setFileName(st->fileName()); ifaceBlock->setFileName(st->fileName());
st->insertStmtBefore(*ifaceBlock, *st->controlParent()); st->insertStmtBefore(*ifaceBlock, *st->controlParent());
ifaceBlock->lastNodeOfStmt()->addComment(iface.c_str()); ifaceBlock->lastNodeOfStmt()->addComment(iface.c_str());
@@ -1644,12 +1507,12 @@ static void createInterfaceBlockForToCalls(FuncInfo* func)
if (callTo->interfaceBlocks.find(func->funcName) == callTo->interfaceBlocks.end()) if (callTo->interfaceBlocks.find(func->funcName) == callTo->interfaceBlocks.end())
{ {
callTo->interfaceBlocks[func->funcName] = func; callTo->interfaceBlocks[func->funcName] = func;
insertInterface(callTo->funcPointer, func); insertInterface(callTo->funcPointer, getInterfaceBlock(func->funcPointer->GetOriginal(), func->funcParams));
} }
} }
} }
static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, set<FuncInfo*>& allForChange, static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, set<FuncInfo*>& allForChange,
vector<SgSymbol*>& varsToTransfer, FuncInfo* curFunc, FuncInfo* precFunc, set<FuncInfo*>& funcForInterfaceAdd) vector<SgSymbol*>& varsToTransfer, FuncInfo* curFunc, FuncInfo* precFunc, set<FuncInfo*>& funcForInterfaceAdd)
{ {
SgStatement* st = curFunc->funcPointer->GetOriginal(); SgStatement* st = curFunc->funcPointer->GetOriginal();
@@ -1701,7 +1564,7 @@ static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, se
else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT) else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT)
{ {
SgCallStmt* callSt = (SgCallStmt*)call.first; SgCallStmt* callSt = (SgCallStmt*)call.first;
if (callSt->name()->identifier() == precFunc->funcName) if (callSt->name()->identifier() == precFunc->funcName)
{ {
for (auto& var : varsToTransfer) for (auto& var : varsToTransfer)
{ {
@@ -1753,7 +1616,7 @@ static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, se
{ {
if (i == 0) if (i == 0)
curFunc->funcParams.identificators.push_back(var->identifier()); curFunc->funcParams.identificators.push_back(var->identifier());
((SgProcHedrStmt*)(hedr))->AddArg(*new SgVarRefExp(var->copy())); ((SgProcHedrStmt*)(hedr))->AddArg(*new SgVarRefExp(var->copy()));
hedr->lexNext()->deleteStmt(); hedr->lexNext()->deleteStmt();
vector<SgSymbol*> varVec = vector<SgSymbol*>(); vector<SgSymbol*> varVec = vector<SgSymbol*>();
@@ -1777,7 +1640,7 @@ static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, se
} }
} }
if (!isAuto) if (!isAuto)
{ {
funcForInterfaceAdd.insert(curFunc); funcForInterfaceAdd.insert(curFunc);
SgAttributeExp* a = new SgAttributeExp(ALLOCATABLE_OP); SgAttributeExp* a = new SgAttributeExp(ALLOCATABLE_OP);
@@ -1797,8 +1660,8 @@ static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, se
SgStatement* firstExDec = NULL; SgStatement* firstExDec = NULL;
for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext()) for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext())
{ {
if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) &&
!strcmp(hedr->fileName(), start->fileName())) !strcmp(hedr->fileName(), start->fileName()))
{ {
firstExDec = start; firstExDec = start;
break; break;
@@ -1889,7 +1752,7 @@ void moduleTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
break; break;
SgStatement* next = start->lexNext(); SgStatement* next = start->lexNext();
if (start->variant() == USE_STMT) if (start->variant() == USE_STMT)
{ {
SgExpression* onlyE = start->expr(0); SgExpression* onlyE = start->expr(0);
if (onlyE) if (onlyE)
@@ -1915,7 +1778,7 @@ void moduleTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
} }
if (renameL) if (renameL)
onlyE->setLhs(renameL); onlyE->setLhs(renameL);
else else
start->deleteStmt(); start->deleteStmt();
} }
@@ -1923,7 +1786,7 @@ void moduleTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
if (isSgExecutableStatement(start)|| isSgDeclarationStatement(start)) if (isSgExecutableStatement(start)|| isSgDeclarationStatement(start))
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
fillUsedVars(usedVars, start->expr(i)); fillUsedVars(usedVars, start->expr(i));
// if (start->variant() == IMPL_DECL) // if (start->variant() == IMPL_DECL)
// start->deleteStmt(); // start->deleteStmt();
start = next; start = next;

View File

@@ -6,14 +6,11 @@ bool checkOutCalls(const std::set<std::string>& outCalls);
std::map<SgStatement*, std::set<std::string>> fillFromIntent(SgStatement* header); std::map<SgStatement*, std::set<std::string>> fillFromIntent(SgStatement* header);
void intentInsert(const std::vector<FuncInfo*>& allFuncInfo); void intentInsert(const std::vector<FuncInfo*>& allFuncInfo);
void intentInsertToInterfaces(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo); void intentInsertToInterfaces(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
void createInterfacesForAssumedSize(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
void createInterfacesForOutCalls(FuncInfo* func); void createInterfacesForOutCalls(FuncInfo* func);
void setPureStatus(const std::set<FuncInfo*>& funcInfo); void setPureStatus(const std::set<FuncInfo*>& funcInfo);
void setPureStatus(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo); void setPureStatus(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
void commonTransfer(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, const std::map<std::string, CommonBlock*>& commonBlocks); void commonTransfer(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, const std::map<std::string, CommonBlock*>& commonBlocks);
void saveTransfer(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo); void saveTransfer(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
void moduleTransfer(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo); void moduleTransfer(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
void insertInterface(SgStatement* func, const FuncInfo* callFrom);
void transformAssumedSizeParameters(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);

View File

@@ -6,7 +6,7 @@
#include "../LoopAnalyzer/loop_analyzer.h" #include "../LoopAnalyzer/loop_analyzer.h"
#include "expr_transform.h" #include "expr_transform.h"
#include "errors.h" #include "errors.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
#include "../SageAnalysisTool/OmegaForSage/include/lang-interf.h" #include "../SageAnalysisTool/OmegaForSage/include/lang-interf.h"
#include "../DirectiveProcessing/directive_parser.h" #include "../DirectiveProcessing/directive_parser.h"
#include "../DirectiveProcessing/directive_omp_parser.h" #include "../DirectiveProcessing/directive_omp_parser.h"

View File

@@ -2,8 +2,8 @@
#include "dvm.h" #include "dvm.h"
#include "../DirectiveProcessing/directive_parser.h" #include "../DirectiveProcessing/directive_parser.h"
#include "CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
#include "CFGraph/RD_subst.h" #include "../CFGraph/RD_subst.h"
// Regime defines the regime of private removing // Regime defines the regime of private removing
enum class Regime { DEFLT = 1, REGULAR_INDEXES }; enum class Regime { DEFLT = 1, REGULAR_INDEXES };

View File

@@ -17,157 +17,6 @@ using std::pair;
#define DEBUG_TRACE 0 #define DEBUG_TRACE 0
static bool hasArrayRef(SgExpression* ex)
{
if (ex)
return isArrayRef(ex) || hasArrayRef(ex->lhs()) || hasArrayRef(ex->rhs());
return false;
}
static inline bool isArrayDeclaration(SgStatement* st)
{
return isSgDeclarationStatement(st) || isSgVarListDeclStmt(st) || isSgNestedVarListDeclStmt(st);
}
static SgExpression* findExprWithVariant(SgExpression* exp, int variant)
{
if (exp)
{
if (exp->variant() == variant)
return exp;
auto *l = findExprWithVariant(exp->lhs(), variant);
if (l)
return l;
auto *r = findExprWithVariant(exp->rhs(), variant);
if (r)
return r;
}
return NULL;
}
static bool switchToDeclarationFile(DIST::Array* array_p,
pair<string, int>& decl_place,
const string &current_file_name,
FuncInfo *current_func)
{
if (!array_p)
return false;
// try to find declaration from current function
for (const auto &p : array_p->GetDeclInfo())
{
if (p.first == current_file_name &&
current_func->linesNum.first <= p.second &&
p.second <= current_func->linesNum.second)
{
decl_place = p;
return true;
}
}
for (const auto &p : array_p->GetDeclInfo())
{
if (SgFile::switchToFile(p.first) != -1)
{
decl_place = p;
return true;
}
}
return false;
}
static bool checkAssumedShape(SgStatement* decl, const string& array_name)
{
SgExpression* list = decl->expr(0);
SgExpression* dim_list = NULL;
while (list)
{
auto *arr_ref = list->lhs();
if (arr_ref &&
arr_ref->symbol() &&
arr_ref->symbol()->identifier() &&
arr_ref->symbol()->identifier() == array_name)
{
dim_list = arr_ref->lhs();
break;
}
list = list->rhs();
}
if (!dim_list)
{
auto *dim_expr = findExprWithVariant(decl->expr(2), DIMENSION_OP);
if (dim_expr)
dim_list = dim_expr->lhs();
}
while (dim_list)
{
auto *lhs = dim_list->lhs();
if (lhs && lhs->variant() == DDOT && (!lhs->lhs() || !lhs->rhs()))
return true;
dim_list = dim_list->rhs();
}
return false;
}
static bool checkAssumedSize(const string &array_name, DIST::Array* array_p, const string &current_file_name, FuncInfo *current_func)
{
if (!array_p)
return true; // raise true to prevent array from copying
bool found = false;
pair<string, int> decl_place;
if (!switchToDeclarationFile(array_p, decl_place, current_file_name, current_func))
return true;
auto *st = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second);
checkNull(st, convertFileName(__FILE__).c_str(), __LINE__);
SgExpression* list = st->expr(0);
while (list)
{
if (list->lhs() &&
list->lhs()->symbol() &&
list->lhs()->symbol()->identifier() &&
list->lhs()->symbol()->identifier() == array_name
)
{
if(findExprWithVariant(list->lhs(), STAR_RANGE))
found = true;
break;
}
list = list->rhs();
}
if (!found)
{
auto *dim_expr = findExprWithVariant(st->expr(2), DIMENSION_OP);
if (dim_expr && findExprWithVariant(dim_expr, STAR_RANGE))
found = true;
}
if (SgFile::switchToFile(current_file_name) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); // can't switch back to file with array usage
return found;
}
static void findArrays(SgExpression* exp, set<SgSymbol*>& arrays) static void findArrays(SgExpression* exp, set<SgSymbol*>& arrays)
{ {
if (exp) if (exp)
@@ -180,15 +29,12 @@ static void findArrays(SgExpression* exp, set<SgSymbol*>& arrays)
} }
} }
static bool populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& arrays, static void populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& arrays, SgStatement* stat)
SgStatement* stat,
const string& current_file_name,
FuncInfo *current_func)
{ {
auto var = stat->variant(); auto var = stat->variant();
if (var != READ_STAT && var != PRINT_STAT && var != WRITE_STAT) if (var != READ_STAT && var != PRINT_STAT && var != WRITE_STAT)
return false; return;
// check if such IO allowed in dvm: // check if such IO allowed in dvm:
// list should consist only of single array and format string should be * // list should consist only of single array and format string should be *
@@ -198,26 +44,22 @@ static bool populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
SgExpression* ioList = stat->expr(0); SgExpression* ioList = stat->expr(0);
if (!ioList) if (!ioList)
return false; return;
if (ioList->variant() != EXPR_LIST) if (ioList->variant() != EXPR_LIST)
return false; return;
if (ioList->rhs() == NULL) if (ioList->rhs() == NULL)
{ {
SgExpression* arg = ioList->lhs(); SgExpression* arg = ioList->lhs();
if (!arg) if (!arg)
return false; return;
if (hasArrayRef(arg)) if (!isArrayRef(arg))
{ return;
if (isArrayRef(arg) && arg->lhs())
need_replace = true; if (arg->lhs())
} need_replace = true;
else
{
return false;
}
} }
else else
{ {
@@ -232,11 +74,15 @@ static bool populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
{ {
SgExpression* fmt = stat->expr(1); SgExpression* fmt = stat->expr(1);
if (!fmt || fmt->variant() != SPEC_PAIR || fmt->lhs()->variant() != KEYWORD_VAL) if (!fmt || fmt->variant() != SPEC_PAIR || fmt->lhs()->variant() != KEYWORD_VAL)
{
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return;
}
if (fmt->rhs()->variant() != KEYWORD_VAL || fmt->rhs()->sunparse() != "*") if (fmt->rhs()->variant() != KEYWORD_VAL || fmt->rhs()->sunparse() != "*")
need_replace = true; need_replace = true;
break; break;
} }
case READ_STAT: case READ_STAT:
@@ -258,7 +104,10 @@ static bool populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
{ {
auto *kv = spec->lhs(); auto *kv = spec->lhs();
if (!kv || kv->variant() != SPEC_PAIR || !kv->rhs()) if (!kv || kv->variant() != SPEC_PAIR || !kv->rhs())
{
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return;
}
if (kv->rhs()->variant() != KEYWORD_VAL || kv->rhs()->sunparse() != "*") if (kv->rhs()->variant() != KEYWORD_VAL || kv->rhs()->sunparse() != "*")
{ {
@@ -269,7 +118,6 @@ static bool populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
spec = spec->rhs(); spec = spec->rhs();
} }
} }
break;
} }
default: default:
break; break;
@@ -277,9 +125,7 @@ static bool populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
} }
if (!need_replace) if (!need_replace)
return false; return;
bool ret = false;
set<SgSymbol*> found_arrays; set<SgSymbol*> found_arrays;
@@ -290,21 +136,11 @@ static bool populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
{ {
string array_name = string(by_symb->identifier()); string array_name = string(by_symb->identifier());
DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(by_symb), array_name); DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(by_symb), array_name);
if (array_p && if (array_p && array_p->GetDistributeFlagVal() == Distribution::distFlag::IO_PRIV && arrays[by_symb].insert(stat).second)
array_p->GetDistributeFlagVal() == Distribution::distFlag::IO_PRIV && __spf_print(DEBUG_TRACE, "[%d]: add array %s\n", stat->lineNumber(), array_p->GetName().c_str());
!checkAssumedSize(array_name, array_p, current_file_name, current_func))
{
auto inserted = arrays[by_symb].insert(stat).second;
if (inserted)
__spf_print(DEBUG_TRACE, "[%d]: add array %s %p\n", stat->lineNumber(), array_p->GetName().c_str(), by_symb);
ret = true;
}
} }
__spf_print(DEBUG_TRACE, "[replace]\n"); __spf_print(DEBUG_TRACE, "[replace]\n");
return ret;
} }
static void replaceArrayRec(SgSymbol* arr, SgSymbol* replace_by, SgExpression* exp, bool& has_read, bool& has_write, bool from_read, bool from_write) static void replaceArrayRec(SgSymbol* arr, SgSymbol* replace_by, SgExpression* exp, bool& has_read, bool& has_write, bool from_read, bool from_write)
@@ -374,12 +210,7 @@ static void replaceArrayRec(SgSymbol* arr, SgSymbol* replace_by, SgStatement* st
} }
} }
static void copyArrayBetweenStatements(SgSymbol* replace_symb, static void copyArrayBetweenStatements(SgSymbol* replace_symb, SgSymbol* replace_by, SgStatement* start, SgStatement* last, bool start_is_scope)
SgSymbol* replace_by,
SgStatement* start,
SgStatement* last,
bool start_is_scope,
FuncInfo *func_info)
{ {
while (start->lexNext() && !isSgExecutableStatement(start->lexNext())) while (start->lexNext() && !isSgExecutableStatement(start->lexNext()))
start = start->lexNext(); start = start->lexNext();
@@ -398,23 +229,10 @@ static void copyArrayBetweenStatements(SgSymbol* replace_symb,
auto* parent = start_is_scope ? start : start->controlParent(); auto* parent = start_is_scope ? start : start->controlParent();
if (parent && parent->lastNodeOfStmt() == start) if (parent && parent->lastNodeOfStmt() == start)
parent = parent->controlParent(); parent = parent->controlParent();
checkNull(parent, convertFileName(__FILE__).c_str(), __LINE__);
start->insertStmtAfter(*assign, *parent); start->insertStmtAfter(*assign, *parent);
} }
if (has_write)
{
for (int i = 0; i < func_info->funcParams.identificators.size(); i++)
{
if (func_info->funcParams.identificators[i] == replace_symb->identifier())
{
has_write &= func_info->funcParams.isArgOut(i);
break;
}
}
}
if (has_write) if (has_write)
{ {
// A = A_reg // A = A_reg
@@ -425,14 +243,9 @@ static void copyArrayBetweenStatements(SgSymbol* replace_symb,
} }
} }
static void replaceArrayInFragment(SgSymbol* replace_symb, static void replaceArrayInFragment(SgSymbol* replace_symb, const set<SgStatement*> usages, SgSymbol* replace_by, SgStatement* start, SgStatement* last, const string& filename)
const set<SgStatement*> usages,
SgSymbol* replace_by,
SgStatement* start,
SgStatement* last,
FuncInfo *func_info)
{ {
while (start->lexNext() && (!isSgExecutableStatement(start->lexNext()) || start->lexNext()->variant() == ALLOCATE_STMT)) while (start->lexNext() && !isSgExecutableStatement(start->lexNext()))
start = start->lexNext(); start = start->lexNext();
set<SgStatement*> not_opened, not_closed, copied; set<SgStatement*> not_opened, not_closed, copied;
@@ -499,7 +312,7 @@ static void replaceArrayInFragment(SgSymbol* replace_symb,
} }
__spf_print(DEBUG_TRACE, "[copy %s] [%d, %d]\n", replace_symb->identifier(), scope_start->lineNumber(), scope_end->lineNumber()); __spf_print(DEBUG_TRACE, "[copy %s] [%d, %d]\n", replace_symb->identifier(), scope_start->lineNumber(), scope_end->lineNumber());
copyArrayBetweenStatements(replace_symb, replace_by, scope_start, scope_end, copy_scope == scope_start, func_info); copyArrayBetweenStatements(replace_symb, replace_by, scope_start, scope_end, copy_scope == scope_start);
copied.insert(copy_scope); copied.insert(copy_scope);
} }
} }
@@ -522,16 +335,12 @@ static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound)
STOP_STAT, STOP_STAT,
STOP_NODE, STOP_NODE,
EXIT_STMT, EXIT_STMT,
EXIT_NODE, EXIT_NODE
GOTO_NODE
}; };
if (border_stats.find(var) != border_stats.end()) if (border_stats.find(var) != border_stats.end())
return true; return true;
if (stat->hasLabel())
return true;
if (last_io_bound && last_io_bound->lastNodeOfStmt() && last_io_bound->lastNodeOfStmt() == stat) if (last_io_bound && last_io_bound->lastNodeOfStmt() && last_io_bound->lastNodeOfStmt() == stat)
return true; return true;
@@ -544,9 +353,9 @@ static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound)
} }
void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions, void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
const map<string, vector<FuncInfo*>>& allFuncInfo, const map<string, vector<FuncInfo*>>& allFuncInfo,
map<string, vector<Messages>>& SPF_messages, map<string, vector<Messages>>& SPF_messages,
map<string, map<int, set<string>>>& newDeclsToInclude) map<string, map<int, set<string>>>& newDeclsToInclude)
{ {
map<SgSymbol*, SgSymbol*> created_copies; map<SgSymbol*, SgSymbol*> created_copies;
map<string, map<int, set<string>>> copied_syms; map<string, map<int, set<string>>> copied_syms;
@@ -555,29 +364,26 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
{ {
__spf_print(DEBUG_TRACE, "[%s]: enter region\n", region->GetName().c_str()); __spf_print(DEBUG_TRACE, "[%s]: enter region\n", region->GetName().c_str());
for (auto& lines_by_file : region->GetAllLinesToModify()) for (auto& linesByFile : region->GetAllLinesToModify())
{ {
const auto& current_file_name = lines_by_file.first; const auto& filename = linesByFile.first;
if (SgFile::switchToFile(current_file_name) == -1) if (SgFile::switchToFile(filename) < 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto func_info_it = allFuncInfo.find(current_file_name);
if (func_info_it == allFuncInfo.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto *lbound_symb = new SgSymbol(FUNCTION_NAME, "lbound");
auto *ubound_symb = new SgSymbol(FUNCTION_NAME, "ubound");
for (auto& lines : lines_by_file.second)
{ {
__spf_print(DEBUG_TRACE, "[fragment] %s: %d:%d %d\n", current_file_name.c_str(), lines.lines.first, printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return;
}
for (auto& lines : linesByFile.second)
{
__spf_print(DEBUG_TRACE, "[fragment] %s: %d:%d %d\n", filename.c_str(), lines.lines.first,
lines.lines.second, lines.isImplicit()); lines.lines.second, lines.isImplicit());
SgStatement* curr_stmt, * end; SgStatement* curr_stmt, * end;
if (lines.isImplicit()) if (lines.isImplicit())
{ {
curr_stmt = current_file->SgStatementAtLine(lines.lines.first); curr_stmt = current_file->SgStatementAtLine(lines.lines.first);
end = current_file->SgStatementAtLine(lines.lines.second); end = current_file->SgStatementAtLine(lines.lines.second);
@@ -593,7 +399,6 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
map<SgSymbol*, set<SgStatement*>> need_replace; map<SgSymbol*, set<SgStatement*>> need_replace;
SgStatement* last_io_bound = NULL; SgStatement* last_io_bound = NULL;
FuncInfo *current_func_info = NULL;
while (curr_stmt != end) while (curr_stmt != end)
{ {
@@ -602,21 +407,9 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
auto var = curr_stmt->variant(); auto var = curr_stmt->variant();
if (var == PROC_HEDR || var == PROG_HEDR || var == FUNC_HEDR) if (var == PROC_HEDR || var == PROG_HEDR || var == FUNC_HEDR)
{ {
current_func_info = NULL;
for (auto *func_info : func_info_it->second)
{
if (func_info->funcName == curr_stmt->symbol()->identifier())
{
current_func_info = func_info;
break;
}
}
if (!current_func_info)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
curr_stmt = curr_stmt->lexNext(); curr_stmt = curr_stmt->lexNext();
while (curr_stmt && !isSgExecutableStatement(curr_stmt)) while (curr_stmt && !isSgExecutableStatement(curr_stmt))
{ {
@@ -640,192 +433,77 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
string array_name = string(array_to_copy->identifier()); string array_name = string(array_to_copy->identifier());
DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(array_to_copy), array_name); DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(array_to_copy), array_name);
// at this point all considered arrays must have DIST::Array* references bool fromModule = (array_p->GetLocation().first == DIST::l_MODULE);
if (!array_p) const string locationName = array_p->GetLocation().second;
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
// ... and be declared in switchable files (not in headers)
pair<string, int> decl_place;
if (!switchToDeclarationFile(array_p, decl_place, current_file_name, current_func_info))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto place = *array_p->GetDeclInfo().begin();
string fileName = place.first;
string suffix = "_io_l"; string suffix = "_io_l";
switch (array_p->GetLocation().first) if (fromModule)
suffix = "_io_m";
pair<SgSymbol*, SgSymbol*> copied;
copied.first = array_to_copy;
if (SgFile::switchToFile(fileName) == -1)
{ {
case DIST::l_MODULE:
suffix = "_io_m";
break;
case DIST::l_COMMON:
suffix = "_io_c";
break;
}
auto copied_symbol = copyArray(decl_place,
array_p,
lines_by_file.second,
suffix + to_string(region->GetId()),
decl_place.first,
newDeclsToInclude,
copied_syms);
// original declaration statement
auto *decl_stmt = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second);
if (!decl_stmt || !isArrayDeclaration(decl_stmt))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto dynamic_array = checkAssumedShape(decl_stmt, array_name);
while (decl_stmt && !isSgExecutableStatement(decl_stmt))
{
if (isArrayDeclaration(decl_stmt) &&
decl_stmt->expr(0) &&
decl_stmt->expr(0)->lhs() &&
decl_stmt->expr(0)->lhs()->symbol() == copied_symbol.second)
{
break;
}
decl_stmt = decl_stmt->lexNext();
}
// created declaration statement
if (!decl_stmt || !isArrayDeclaration(decl_stmt))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
// insert !$SPF ANALYSIS(PROCESS_PRIVATE(array)) directive before declaration statement
string dir_str;
if (decl_stmt->comments())
{
auto str_comment = string(decl_stmt->comments());
if (str_comment.size() && str_comment.back() != '\n')
dir_str += "\n";
}
dir_str += "!$SPF ANALYSIS(PROCESS_PRIVATE(" + string(copied_symbol.second->identifier()) + "))\n";
decl_stmt->addComment(dir_str.c_str());
created_copies.insert({ array_to_copy, copied_symbol.second });
// make array copy allocatable in case of assumed-shape array
if(dynamic_array)
{
// insert allocatable keyword in declaration
auto *kword_list = decl_stmt->expr(2);
if (!findExprWithVariant(kword_list, ALLOCATABLE_OP))
{
if (!kword_list)
{
kword_list = new SgExprListExp();
decl_stmt->setExpression(2, *kword_list);
}
while (kword_list->rhs())
kword_list = kword_list->rhs();
if (kword_list->lhs())
{
kword_list->setRhs(new SgExprListExp());
kword_list = kword_list->rhs();
}
kword_list->setLhs(new SgExpression(ALLOCATABLE_OP));
}
// can't switch back to file with array usage
if (SgFile::switchToFile(current_file_name) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
// insert allocate(a_l(lbound(a, 1):ubound(a,1),...)) statement
SgStatement* allocate_stmt_place = NULL;
auto* func_stmt = curr_stmt->getScopeForDeclare(); auto* func_stmt = curr_stmt->getScopeForDeclare();
SgStatement* insertPlace = NULL;
for (auto iterator = func_stmt->lexNext(); for (auto iterator = func_stmt->lexNext();
iterator && !isSgExecutableStatement(iterator); !isSgExecutableStatement(iterator) || isSPF_stat(iterator) &&
!(iterator->variant() == SPF_PARALLEL_REG_DIR || iterator->variant() == SPF_END_PARALLEL_REG_DIR);
iterator = iterator->lexNext()) iterator = iterator->lexNext())
{ {
allocate_stmt_place = iterator; insertPlace = iterator;
} }
//NULL - no decl stats in function! //NULL - no decl stats in function!
if (!allocate_stmt_place) if (!insertPlace)
allocate_stmt_place = func_stmt; insertPlace = func_stmt;
auto *allocate_stmt_parent = allocate_stmt_place->controlParent(); auto st = insertPlace->controlParent();
if (allocate_stmt_parent->variant() == GLOBAL) if (st->variant() == GLOBAL)
allocate_stmt_parent = allocate_stmt_place; st = insertPlace;
auto *created_array_ref = new SgArrayRefExp(*copied_symbol.second);
auto* dim_list = new SgExprListExp(); auto& copied_symb = array_to_copy->copy();
created_array_ref->setLhs(dim_list); copied.second = &copied_symb;
int dim_len = array_p->GetSizes().size();
for (int i = 1; i <= dim_len; i++)
{
auto *lcall = new SgFunctionCallExp(*lbound_symb);
auto *rcall = new SgFunctionCallExp(*ubound_symb);
for (auto *call : {lcall, rcall})
{
call->setLhs(new SgExprListExp());
call->lhs()->setLhs(new SgArrayRefExp(*array_to_copy)); auto new_name = string(array_to_copy->identifier()) + "_io_c";
call->lhs()->setRhs(new SgValueExp(i)); copied_symb.changeName(new_name.c_str());
}
auto *dot_expr = new SgExpression(DDOT);
dot_expr->setLhs(lcall);
dot_expr->setRhs(rcall);
dim_list->setLhs(dot_expr); auto stat = array_to_copy->makeVarDeclStmt();
auto res = CalculateInteger(stat->expr(0)->copyPtr());
res->lhs()->setSymbol(copied_symb);
stat->setExpression(0, res);
if (i < dim_len) insertPlace->insertStmtAfter(*stat, *st);
{ }
auto *next = new SgExprListExp(); else
dim_list->setRhs(next); {
dim_list = next; copied = copyArray(place, array_p, linesByFile.second, suffix + to_string(region->GetId()), fileName, newDeclsToInclude, copied_syms);
}
}
auto *allocate_stmt = new SgStatement(ALLOCATE_STMT);
allocate_stmt->setExpression(0, created_array_ref);
allocate_stmt_place->insertStmtAfter(*allocate_stmt, *allocate_stmt_parent);
// insert deallocate statemens before all returns
auto *find_return_stmt = func_stmt;
while (find_return_stmt != func_stmt->lastNodeOfStmt())
{
auto *next = find_return_stmt->lexNext();
if (next && (isSgReturnStmt(next) || next == func_stmt->lastNodeOfStmt()))
{
if (next->hasLabel())
{
moveLabelBefore(next);
find_return_stmt = next->lexPrev();
}
auto *dealloc_stmt = new SgStatement(DEALLOCATE_STMT);
dealloc_stmt->setExpression(0, new SgExprListExp());
dealloc_stmt->expr(0)->setLhs(new SgArrayRefExp(*copied_symbol.second));
find_return_stmt->insertStmtAfter(*dealloc_stmt, *next->controlParent());
if (next == curr_stmt)
curr_stmt = dealloc_stmt;
}
find_return_stmt = next;
}
} }
// can't switch back to file with array usage SgStatement* decl = SgStatement::getStatementByFileAndLine(place.first, place.second);
if (SgFile::switchToFile(current_file_name) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); if (decl)
decl = decl->lexNext();
if (decl)
{
string dir_str;
if (decl->comments())
{
string str_comment = string(decl->comments());
if (str_comment.size() && str_comment.back() != '\n')
dir_str += "\n";
}
dir_str += "!$SPF ANALYSIS(PROCESS_PRIVATE(" + string(copied.second->identifier()) + "))\n";
decl->addComment(dir_str.c_str());
}
created_copies.insert({ array_to_copy, copied.second });
} }
} }
@@ -837,9 +515,12 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
{ {
auto it = created_copies.find(p.first); auto it = created_copies.find(p.first);
if (it != created_copies.end()) if (it != created_copies.end())
replaceArrayInFragment(p.first, p.second, it->second, last_io_bound, curr_stmt, current_func_info); replaceArrayInFragment(p.first, p.second, it->second, last_io_bound, curr_stmt, filename);
else else
{
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return;
}
} }
} }
@@ -857,17 +538,7 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
} }
} }
auto need_fix_io = populateDistributedIoArrays(need_replace, curr_stmt, current_file_name, current_func_info); populateDistributedIoArrays(need_replace, curr_stmt);
// incorrect IO statement with label
// move label to dummy statement and insert copy statements between dummy statement and IO
if (need_fix_io && curr_stmt->hasLabel())
{
moveLabelBefore(curr_stmt);
if (last_io_bound == curr_stmt) // always true
last_io_bound = curr_stmt->lexPrev();
}
curr_stmt = curr_stmt->lexNext(); curr_stmt = curr_stmt->lexNext();
} }
} }

View File

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

View File

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

View File

@@ -212,8 +212,6 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE); Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE);
list({BUILD_IR, CALL_GRAPH2}) <= Pass(SWAP_OPERATORS);
list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS); list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS);
list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING); list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING);
@@ -318,7 +316,9 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE); list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE);
list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS); list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2, BUILD_IR }) <= Pass(BUILD_IR_SSA_FORM) <= Pass(FIND_IMPLICIT_LOOPS);
list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2, BUILD_IR, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS);
passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS, passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS,
EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW, EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,

View File

@@ -390,15 +390,32 @@ void clearGlobalBuffer() { globalOutputBuffer = ""; }
const string& getGlobalBuffer() { return globalOutputBuffer; } const string& getGlobalBuffer() { return globalOutputBuffer; }
set<short*> allocated; set<short*> allocated;
set<int*> allocatedInt;
static void convertGlobalBuffer(short *&result, int *&resultSize)
{
const unsigned len = (unsigned)globalOutputBuffer.size();
result = new short[len + 1];
allocated.insert(result);
result[len] = '\0';
for (unsigned i = 0; i < len; ++i)
result[i] = globalOutputBuffer[i];
resultSize = new int[1];
resultSize[0] = (int)len;
}
extern map<string, vector<Messages>> SPF_messages; //file ->messages extern map<string, vector<Messages>> SPF_messages; //file ->messages
void clearGlobalMessagesBuffer() void clearGlobalMessagesBuffer()
{ {
//clear allocated memory //clear allocated memory
for (auto& elem : allocated) for (auto& elem : allocated)
delete []elem; delete[]elem;
for (auto& elem : allocatedInt)
delete[]elem;
allocated.clear(); allocated.clear();
allocatedInt.clear();
SPF_messages.clear(); SPF_messages.clear();
} }
@@ -434,7 +451,7 @@ static map<string, vector<Messages>> removeCopies(map<string, vector<Messages>>
return out; return out;
} }
static string convertGlobalMessagesBuffer() static void convertGlobalMessagesBuffer(short *&result, int *&resultSize)
{ {
auto copySPF_messages = removeCopies(SPF_messages); auto copySPF_messages = removeCopies(SPF_messages);
for (auto &byFile : copySPF_messages) for (auto &byFile : copySPF_messages)
@@ -472,13 +489,21 @@ static string convertGlobalMessagesBuffer()
json all; json all;
all["allMessages"] = allMessages; all["allMessages"] = allMessages;
return all.dump(); const string str = all.dump();
const unsigned len = (unsigned)str.size();
copyStringToShort(result, str);
allocated.insert(result);
resultSize = new int[1];
resultSize[0] = (int)len;
} }
void convertBuffers(string &resultM, string &result)
void convertBuffers(short*& resultM, int*& resultSizeM, short*& result, int*& resultSize)
{ {
resultM = convertGlobalMessagesBuffer(); convertGlobalMessagesBuffer(resultM, resultSizeM);
result = getGlobalBuffer(); convertGlobalBuffer(result, resultSize);
} }
bool isSPF_comment(const string &bufStr) bool isSPF_comment(const string &bufStr)

View File

@@ -33,7 +33,7 @@ void addToGlobalBufferAndPrint(const std::string &toPrint);
void clearGlobalBuffer(); void clearGlobalBuffer();
const std::string& getGlobalBuffer(); const std::string& getGlobalBuffer();
std::wstring to_wstring(const std::string); std::wstring to_wstring(const std::string);
void convertBuffers(std::string& resultM, std::string& result); void convertBuffers(short*& resultM, int*& resultSizeM, short*& result, int*& resultSize);
void clearGlobalMessagesBuffer(); void clearGlobalMessagesBuffer();
std::string renameInclude(const std::string& inc); std::string renameInclude(const std::string& inc);
void copyIncludes(const std::set<std::string> &allIncludeFiles, const std::map<std::string, std::map<int, std::set<std::string>>> &commentsToInclude, const std::map<std::string, std::map<int, std::set<std::string>>>& newCopyDeclToIncl, const char *folderName, bool keepSpfDirs, bool isFreeStyle, bool isRename, int removeDirs = 0); void copyIncludes(const std::set<std::string> &allIncludeFiles, const std::map<std::string, std::map<int, std::set<std::string>>> &commentsToInclude, const std::map<std::string, std::map<int, std::set<std::string>>>& newCopyDeclToIncl, const char *folderName, bool keepSpfDirs, bool isFreeStyle, bool isRename, int removeDirs = 0);

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_SPF "2446" #define VERSION_SPF "2432"

File diff suppressed because it is too large Load Diff