94 Commits

Author SHA1 Message Date
fc98972bc2 fix algorythm 2026-02-21 02:34:57 +03:00
ca77cc05d5 Merge pull request 'fix some compiler warnings' (#74) from minor_fixes into master 2026-02-19 05:49:32 +00:00
ALEXks
a04ee16023 improved fix_common_blocks 2026-02-19 08:48:44 +03:00
ALEXks
0c4f9465df fixed getModuleSymbols 2026-02-19 08:34:58 +03:00
9dbbe9fcdc fix some compiler warnings 2026-02-19 08:32:42 +03:00
f5d2ecf549 Merge pull request 'PRIVATE_ANALYSIS_IR: handle unreachable loops' (#75) from fix_private_scalars_analysis into master 2026-02-19 05:32:13 +00:00
eee6f30f94 PRIVATE_ANALYSIS_IR: handle unreachable loops 2026-02-19 00:03:13 +03:00
ALEXks
11b3ecba2e dvm updated 2026-02-18 20:43:04 +03:00
ALEXks
d4e7b39acd dvm updated 2026-02-18 19:58:50 +03:00
ALEXks
d8e5c1bdf6 fixed shadow grouping 2026-02-14 10:15:28 +03:00
ALEXks
9afdf2a98b added CFG_withUnreachable option 2026-02-14 10:05:25 +03:00
ALEXks
6091fa474d improved CFG settings 2026-02-14 09:59:20 +03:00
ALEXks
bc9c7cba5c turn on staticShadowAnalysis option 2026-02-14 08:39:57 +03:00
ALEXks
c1d94be0be fixed private filling 2026-02-10 09:18:44 +03:00
ALEXks
d78753888f fixed deps 2026-02-06 08:28:18 +03:00
ALEXks
025bbbe259 fixed getNameInLocation for module functions 2026-02-05 15:01:05 +03:00
ALEXks
076a0c9699 fixed unparsing COMMON list 2026-02-05 13:52:24 +03:00
ALEXks
90b311d049 fixed GetDeclSymbol 2026-02-04 16:34:19 +03:00
ALEXks
5a1377e7ea fixed ChangeName function for common 2026-02-03 09:26:06 +03:00
ALEXks
b90d200fad fixed different names of same arrays in common 2026-02-01 12:25:54 +03:00
ALEXks
331d4f9d99 fixed private analysis 2026-01-19 21:01:49 +03:00
ALEXks
904292f109 updated submodule libpredictor 2026-01-18 16:50:57 +03:00
ALEXks
c36326660c fixed submodule libpredictor 2026-01-06 18:50:54 +03:00
ALEXks
ec08e3af0e version updated 2026-01-06 18:36:07 +03:00
ALEXks
b1ef5d0b67 dvm submodule updated 2026-01-06 18:35:34 +03:00
d6c046ea57 Merge pull request 'egormayorov' (#72) from egormayorov into master 2025-12-29 18:26:19 +00:00
ALEXks
af85311480 refactored, added pass to Visualizer calls 2025-12-29 21:22:53 +03:00
ALEXks
d9f54739d2 refactored 2025-12-29 21:10:55 +03:00
Egor Mayorov
6907f44ac5 fixes & improvements 2025-12-25 15:01:01 +03:00
Egor Mayorov
582d2d5e70 Adding handing of nested loops and conditional statements 2025-12-24 21:08:42 +03:00
Egor Mayorov
1c37336459 Make pass correct 2025-12-24 21:08:42 +03:00
Egor Mayorov
f527deb02c attempt to build new ast 2025-12-24 21:08:42 +03:00
d09e92a947 moved to transformations 2025-12-24 21:08:42 +03:00
Egor Mayorov
029da32719 swap operators in AST 2025-12-24 21:08:42 +03:00
Egor Mayorov
085e6312a3 Use more complex algorythm for building new order of statements 2025-12-24 21:08:42 +03:00
Egor Mayorov
c5927fe80f update in new order 2025-12-24 21:08:42 +03:00
Egor Mayorov
8728f84546 biulding new order 2025-12-24 21:08:42 +03:00
Egor Mayorov
9e4db270fc some loop analysis done 2025-12-24 21:08:42 +03:00
Egor Mayorov
0c20b37923 Add _bin to gitignore 2025-12-24 21:08:42 +03:00
Egor Mayorov
61c6ad1363 Some actions simplify analyzing IR 2025-12-24 21:08:42 +03:00
Egor Mayorov
e5fa2e41b3 Pass with output file added 2025-12-24 21:08:42 +03:00
Egor Mayorov
3b9e4653b6 change pass deps 2025-12-24 21:08:42 +03:00
Egor Mayorov
2d84aaff1f New pass 2025-12-24 21:08:42 +03:00
032cdb9b03 Merge pull request 'private_arrays' (#71) from private_arrays into master 2025-12-24 05:59:30 +00:00
ALEXks
a8f8f44ac1 corrected style, updated version 2025-12-24 08:58:28 +03:00
1c39001e28 small fix 2025-12-23 16:29:10 +03:00
7802f538e8 add whole array assign 2025-12-23 02:03:57 +03:00
93fa183b63 fix 2025-12-21 03:58:45 +03:00
a07a701826 Merge pull request 'fix private arrays search' (#70) from private_arrays into master 2025-12-19 18:07:14 +00:00
ALEXks
e99855cdff updated version, fixed code style 2025-12-19 21:06:55 +03:00
f07bea4980 fix FIND_PRIVATE_ARRAYS 2025-12-19 04:52:31 +03:00
ALEXks
3de06d9261 finalyze first version of private arrays search 2025-12-11 12:26:39 +03:00
678c2cf351 Merge pull request 'add directives' (#69) from private_arrays into master 2025-12-11 08:30:47 +00:00
40cfd83de5 add directives 2025-12-10 01:46:26 +03:00
ALEXks
a0cea2df91 added new function for visualizer 2025-11-08 20:17:32 +03:00
ALEXks
4b7df86b8a version updated 2025-11-08 20:08:22 +03:00
836894fef1 Merge pull request 'private_arrays' (#68) from private_arrays into master 2025-11-08 17:07:07 +00:00
9ac15eec79 fix codestyle 2025-11-08 20:06:07 +03:00
03f565f50b add multifile support 2025-11-08 20:06:07 +03:00
47e2b961e2 Merge pull request 'replace_io_arrays' (#67) from replace_io_arrays into master 2025-10-01 18:13:01 +00:00
ALEXks
b95b336372 version updated 2025-10-01 21:12:49 +03:00
f35d7cb4bd REMOVE_DIST_ARRAYS_FROM_IO: consider write/read statements with nested loops 2025-10-01 19:48:34 +03:00
54615e34d4 REMOVE_DIST_ARRAYS_FROM_IO: use more general isSgVarListDeclStmt and isSgNestedVarListDeclStmt functions 2025-10-01 18:54:55 +03:00
8752f4a139 REMOVE_DIST_ARRAYS_FROM_IO: consider labels and goto statements while inserting copy statements 2025-10-01 18:54:55 +03:00
453105d273 REMOVE_DIST_ARRAYS_FROM_IO: consider array declarations from common blocks and dimension statements 2025-10-01 18:54:55 +03:00
cad0a0b217 Merge pull request 'cmake: set -O2 optimization level only if CMAKE_BUILD_TYPE is not specified' (#66) from cmake_linux_opt_level into master 2025-09-25 18:13:00 +00:00
9c0fd40e7b cmake: change default optimization level to O3 2025-09-25 20:49:11 +03:00
c7a31c8bbb cmake: set -O2 optimization level only if CMAKE_BUILD_TYPE is not specified 2025-09-25 13:44:10 +03:00
ALEXks
9900929349 refactored 2025-09-23 08:21:05 +03:00
ALEXks
e1ba299159 cleanup 2025-09-21 08:47:42 +03:00
ALEXks
8de18d1788 added json to global results 2025-09-18 21:09:43 +03:00
06aabdbee6 Merge pull request 'REMOVE_DIST_ARRAYS_FROM_IO Handle assumed-size and assumed-shape arrays' (#64) from replace_io_arrays into master 2025-09-16 05:23:30 +00:00
ALEXks
c6f290bb56 trivial, version updated 2025-09-16 08:22:53 +03:00
49d3b9b96e REMOVE_DIST_ARRAYS_FROM_IO: revert hotfix for issue with generated intent statements 2025-09-15 21:25:57 +03:00
280beb13cc REMOVE_DIST_ARRAYS_FROM_IO: regard generated intent statements, carefully detect assumed-shape arrays 2025-09-13 20:48:24 +03:00
3bc9351641 REMOVE_DIST_ARRAYS_FROM_IO: do not process arrays from headers, copy from correct declarations, improve style 2025-09-13 20:48:24 +03:00
16b2c6b42b REMOVE_DIST_ARRAYS_FROM_IO: remove debug prints 2025-09-13 20:48:24 +03:00
fe31df0ef2 REMOVE_DIST_ARRAYS_FROM_IO: handle assumed-size and assumed-shape arrays 2025-09-13 20:48:24 +03:00
ALEXks
4c8681bfe2 dvm updated 2025-09-13 20:25:59 +03:00
ALEXks
d330a6ee23 changed line numbers to negative for INTENT and INTRINSIC 2025-09-13 20:21:56 +03:00
ALEXks
b439759e9b updated dvm for SAPFOR 2025-09-11 17:20:44 +03:00
b11973cb64 Merge pull request 'ArrayAnalysis: consider case of IO_PRIV array from module' (#65) from io_priv_module_arrays into master 2025-09-11 05:07:39 +00:00
ALEXks
df9a9a30bb fixed DIST::IO_PRIV detection 2025-09-11 08:07:14 +03:00
ALEXks
2cd02c295f fixed expression calculation, fixed addArg 2025-08-20 14:34:17 +03:00
ALEXks
278fc1ff9c fixed replace_dist_array pass: added more file switching 2025-07-27 08:52:28 +03:00
ALEXks
80eac5b957 fixed region inserter 2025-07-27 08:20:36 +03:00
ALEXks
0c9eed4bb7 fixed transformation 2025-07-27 07:59:25 +03:00
ALEXks
d3d6d0bec7 added TRANSFORM_ASSUMED_SIZE_PARAMETERS pass, fixed shared memory parallelization 2025-07-26 20:22:15 +03:00
ALEXks
3095510826 improved cmake 2025-07-22 08:54:21 +03:00
ALEXks
85e2a60183 removed createInterfacesForAssumedSize call 2025-07-09 14:46:29 +03:00
ALEXks
68bd21b7b0 fixed inout analysis for function's parameters 2025-07-09 12:00:27 +03:00
ALEXks
177433a95b turn off createInterfacesForAssumedSize call 2025-07-05 20:58:12 +03:00
ALEXks
29ece9072e fixed shared memory parallelization 2025-07-05 20:49:23 +03:00
ALEXks
feafa43f32 fixed declare insertion 2025-07-02 12:02:30 +03:00
63 changed files with 3214 additions and 1941 deletions

1
.gitignore vendored
View File

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

View File

@@ -12,6 +12,7 @@ add_definitions("-D SYS5")
add_definitions("-D YYDEBUG")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 17)
set(fdvm_include projects/dvm/fdvmh/include/fdvmh/)
set(fdvm_sources projects/dvm/fdvmh/tools/fdvmh/)
@@ -33,6 +34,7 @@ include_directories(src/Distribution)
include_directories(src/GraphCall)
include_directories(src/GraphLoop)
include_directories(src/Transformations/ExpressionSubstitution)
include_directories(src/Transformations)
#Sage lib includes
include_directories(${fdvm_include})
@@ -161,6 +163,10 @@ set(PARALLEL_REG src/ParallelizationRegions/ParRegions.cpp
src/ParallelizationRegions/resolve_par_reg_conflicts.cpp
src/ParallelizationRegions/resolve_par_reg_conflicts.h)
set(ARRAY_PROP src/ArrayConstantPropagation/propagation.cpp
src/ArrayConstantPropagation/propagation.h
)
set(TR_DEAD_CODE src/Transformations/DeadCodeRemoving/dead_code.cpp
src/Transformations/DeadCodeRemoving/dead_code.h)
set(TR_CP src/Transformations/CheckPoints/checkpoints.cpp
@@ -201,7 +207,9 @@ set(TR_EXPR_TRANSFORM src/Transformations/ExpressionSubstitution/control_flow_gr
set(TR_INLINER src/Transformations/FunctionInlining/inliner.cpp
src/Transformations/FunctionInlining/inliner.h)
set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp
src/Transformations/RenameSymbols/rename_symbols.h)
src/Transformations/RenameSymbols/rename_symbols.h)
SET(TR_MOVE_OPERATORS src/Transformations/MoveOperators/move_operators.cpp
src/Transformations/MoveOperators/move_operators.h)
set(TRANSFORMS
${TR_DEAD_CODE}
@@ -224,8 +232,9 @@ set(TRANSFORMS
${TR_REPLACE_ARRAYS_IN_IO}
${TR_EXPR_TRANSFORM}
${TR_INLINER}
${TR_RENAME_SYMBOLS})
${TR_RENAME_SYMBOLS}
${TR_MOVE_OPERATORS})
set(CFG src/CFGraph/IR.cpp
src/CFGraph/IR.h
src/CFGraph/IR_domTree.cpp
@@ -238,14 +247,14 @@ set(CFG src/CFGraph/IR.cpp
src/CFGraph/live_variable_analysis.h
src/CFGraph/private_variables_analysis.cpp
src/CFGraph/private_variables_analysis.h
src/CFGraph/IR_SSAForm.cpp
src/CFGraph/IR_SSAForm.h)
)
set(DATA_FLOW
src/CFGraph/DataFlow/data_flow.h
src/CFGraph/DataFlow/data_flow_impl.h
src/CFGraph/DataFlow/backward_data_flow.h
src/CFGraph/DataFlow/backward_data_flow_impl.h)
src/CFGraph/DataFlow/backward_data_flow_impl.h
)
set(CREATE_INTER_T src/CreateInterTree/CreateInterTree.cpp
src/CreateInterTree/CreateInterTree.h)
@@ -321,9 +330,7 @@ set(GR_LOOP src/GraphLoop/graph_loops_base.cpp
set(LOOP_ANALYZER src/LoopAnalyzer/allocations_prepoc.cpp
src/LoopAnalyzer/dep_analyzer.cpp
src/LoopAnalyzer/loop_analyzer.cpp
src/LoopAnalyzer/loop_analyzer.h
src/LoopAnalyzer/implicit_loops_analyzer.cpp
src/LoopAnalyzer/implicit_loops_analyzer.h)
src/LoopAnalyzer/loop_analyzer.h)
set(MAIN src/Sapfor.cpp
src/Sapfor.h
@@ -420,6 +427,7 @@ set(SOURCE_EXE
${TRANSFORMS}
${PARALLEL_REG}
${PRIV}
${ARRAY_PROP}
${FDVM}
${OMEGA}
${UTILS}
@@ -459,6 +467,7 @@ source_group (Transformations\\GlobalVariables FILES ${TR_GV})
source_group (Transformations\\ConvertToC FILES ${TR_CONV})
source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE})
source_group (Transformations\\ReplaceArraysInIO FILES ${TR_REPLACE_ARRAYS_IN_IO})
source_group (Transformations\\MoveOperators FILES ${TR_MOVE_OPERATORS})
source_group (CreateIntervals FILES ${CREATE_INTER_T})
@@ -471,6 +480,7 @@ source_group (GraphLoop FILES ${GR_LOOP})
source_group (LoopAnalyzer FILES ${LOOP_ANALYZER})
source_group (ParallelizationRegions FILES ${PARALLEL_REG})
source_group (PrivateAnalyzer FILES ${PRIV})
source_group (ArrayConstantPropagation FILES ${ARRAY_PROP})
source_group (FDVM_Compiler FILES ${FDVM})
source_group (SageExtension FILES ${OMEGA})
source_group (Utils FILES ${UTILS})
@@ -487,7 +497,7 @@ source_group (Predictor\\Library FILES ${LIBPREDICTOR})
source_group (Parser FILES ${PARSER})
source_group (PPPA\\PPPA FILES ${PPPA})
source_group (PPPA\\ZLib FILES ${ZLIB})
if (MSVC_IDE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Zc:__cplusplus")
else()
@@ -496,7 +506,9 @@ else()
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif()
endif()
add_subdirectory(projects/Fdvm)

View File

@@ -0,0 +1,301 @@
#include "propagation.h"
#include "../Utils/SgUtils.h"
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
static SgStatement* declPlace = NULL;
static bool CheckConstIndexes(SgExpression* exp)
{
if (!exp)
{
return true;
}
SgExpression* lhs = exp->lhs();
SgExpression* rhs = exp->rhs();
do
{
if (lhs->variant() != INT_VAL)
{
return false;
}
if (rhs)
{
lhs = rhs->lhs();
rhs = rhs->rhs();
}
} while (rhs);
return true;
}
static SgExpression* CreateVar(int& variableNumber, SgType* type)
{
string varName = "__tmp_prop_var";
string name = varName + std::to_string(variableNumber) + "__";
variableNumber++;
SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *declPlace->controlParent());
const string commonBlockName = "__propagation_common__";
SgStatement* funcStart = declPlace->controlParent();
SgStatement* commonStat = NULL;
SgExpression* commonList = NULL;
SgStatement* funcEnd = funcStart->lastNodeOfStmt();
SgStatement* current = funcStart->lexNext();
while (current != funcEnd && current)
{
if (current->variant() == COMM_STAT)
{
for (SgExpression* exp = current->expr(0); exp; exp = exp->rhs())
{
if (exp->variant() == COMM_LIST)
{
string existingName = exp->symbol() ?
string(exp->symbol()->identifier()) :
string("spf_unnamed");
if (existingName == commonBlockName)
{
commonStat = current;
commonList = exp;
break;
}
}
}
if (commonStat)
break;
}
current = current->lexNext();
}
vector<SgExpression*> varRefs;
if (commonList)
{
SgExpression* varList = commonList->lhs();
if (varList)
{
auto extractSymbol = [](SgExpression* exp) -> SgSymbol* {
if (!exp)
return NULL;
if (exp->symbol())
return exp->symbol();
if (exp->lhs() && exp->lhs()->symbol())
return exp->lhs()->symbol();
return NULL;
};
if (varList->variant() == EXPR_LIST)
{
for (SgExpression* exp = varList; exp; exp = exp->rhs())
{
SgExpression* varExp = exp->lhs();
SgSymbol* sym = extractSymbol(varExp);
if (sym)
{
varRefs.push_back(new SgVarRefExp(sym));
}
}
}
else
{
for (SgExpression* varExp = varList; varExp; varExp = varExp->rhs())
{
SgSymbol* sym = extractSymbol(varExp);
if (sym)
{
varRefs.push_back(new SgVarRefExp(sym));
}
}
}
}
}
if (!commonList)
{
current = funcStart->lexNext();
while (current != funcEnd && current)
{
if (current->variant() == COMM_STAT)
{
commonStat = current;
break;
}
current = current->lexNext();
}
SgSymbol* commonSymbol = new SgSymbol(COMMON_NAME, commonBlockName.c_str());
commonList = new SgExpression(COMM_LIST, NULL, NULL, commonSymbol);
if (commonStat)
{
SgExpression* lastCommList = commonStat->expr(0);
if (lastCommList)
{
while (lastCommList->rhs())
lastCommList = lastCommList->rhs();
lastCommList->setRhs(commonList);
}
else
{
commonStat->setExpression(0, commonList);
}
}
else
{
commonStat = new SgStatement(COMM_STAT);
commonStat->setFileName(declPlace->fileName());
commonStat->setFileId(declPlace->getFileId());
commonStat->setProject(declPlace->getProject());
commonStat->setlineNumber(getNextNegativeLineNumber());
commonStat->setExpression(0, commonList);
declPlace->insertStmtBefore(*commonStat, *declPlace->controlParent());
}
}
varRefs.push_back(new SgVarRefExp(varSymbol));
if (varRefs.size() > 0)
{
std::reverse(varRefs.begin(), varRefs.end());
SgExpression* varList = makeExprList(varRefs, false);
commonList->setLhs(varList);
}
return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr());
}
static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map<string, SgExpression*>& arrayToVariable, int& variableNumber)
{
if (!exp)
{
return;
}
vector<SgExpression*> subnodes = { exp->lhs(), exp->rhs() };
string expUnparsed;
SgExpression* toAdd = NULL;
if (exp->variant() == ARRAY_REF && CheckConstIndexes(exp->lhs()))
{
cout << st->unparse() << endl;
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType())
{
arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType());
}
st->setExpression(1, arrayToVariable[expUnparsed]->copyPtr());
return;
}
for (int i = 0; i < 2; i++)
{
if (subnodes[i] && subnodes[i]->variant() == ARRAY_REF && subnodes[i]->symbol()->type()->baseType() && CheckConstIndexes(subnodes[i]->lhs()))
{
expUnparsed = subnodes[i]->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end())
{
arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType());;
}
toAdd = arrayToVariable[expUnparsed]->copyPtr();
if (toAdd)
{
if (i == 0)
{
exp->setLhs(toAdd);
}
else
{
exp->setRhs(toAdd);
}
}
}
else
{
TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber);
}
}
}
static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map<string, SgExpression*>& arrayToVariable, int& variableNumber)
{
if (exp->symbol()->type()->variant() == T_STRING)
return;
string expUnparsed = exp->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType())
{
arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType());
}
SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, arrayToVariable[expUnparsed]->copyPtr(), st->expr(1)->copyPtr(), NULL);
newStatement->setFileId(st->getFileId());
newStatement->setProject(st->getProject());
newStatement->setlineNumber(getNextNegativeLineNumber());
newStatement->setLocalLineNumber(st->lineNumber());
st->insertStmtBefore(*newStatement, *st->controlParent());
}
void ArrayConstantPropagation(SgProject& project)
{
unordered_map<string, SgExpression*> arrayToVariable;
int variableNumber = 0;
for (int i = 0; i < project.numberOfFiles(); i++)
{
SgFile* file = &(project.file(i));
if (!file)
continue;
const int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i)
{
SgStatement* st = file->functions(i);
declPlace = st->lexNext();
SgStatement* lastNode = st->lastNodeOfStmt();
for (; st != lastNode; st = st->lexNext())
{
if (st->variant() == ASSIGN_STAT)
{
if (st->expr(1))
{
TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber);
}
if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()))
{
TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber);
}
}
else if (st->variant() == FOR_NODE)
{
SgExpression* lowerBound = st->expr(0)->lhs();
SgExpression* upperBound = st->expr(0)->rhs();
string lowerBoundUnparsed = lowerBound->unparse(), upperBoundUnparsed = upperBound->unparse();
if (upperBound->variant() == ARRAY_REF && upperBound->symbol()->type()->baseType() && CheckConstIndexes(upperBound->lhs()))
{
if (arrayToVariable.find(upperBoundUnparsed) == arrayToVariable.end())
{
arrayToVariable[upperBoundUnparsed] = CreateVar(variableNumber, upperBound->symbol()->type()->baseType());
}
st->expr(0)->setRhs(arrayToVariable[upperBoundUnparsed]->copyPtr());
}
if (lowerBound->variant() == ARRAY_REF && lowerBound->symbol()->type()->baseType() && CheckConstIndexes(lowerBound->lhs()))
{
if (arrayToVariable.find(lowerBoundUnparsed) == arrayToVariable.end())
{
arrayToVariable[lowerBoundUnparsed] = CreateVar(variableNumber, lowerBound->symbol()->type()->baseType());
}
st->expr(0)->setLhs(arrayToVariable[lowerBoundUnparsed]->copyPtr());
}
}
}
}
}
}

View File

@@ -0,0 +1,4 @@
#pragma once
#include "../Utils/SgUtils.h"
void ArrayConstantPropagation(SgProject& project);

View File

@@ -50,30 +50,12 @@ BBlock::BasicBlock(const BBlock& copyFrom)
prev = copyFrom.prev;
}
void BBlock::addInstruction(IR_Block* item, bool pushFront)
void BBlock::addInstruction(IR_Block* item)
{
if (pushFront)
instructions.insert(instructions.begin(), item);
else
instructions.push_back(item);
instructions.push_back(item);
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)
{
auto it = std::remove(prev.begin(), prev.end(), removed);
@@ -530,7 +512,7 @@ static int buildReachingDefs(const vector<BBlock*>& CFG, const FuncInfo* currF,
return iter;
}
//Kosaraju-Sharir algorithm
//KosarajuSharir algorithm
static vector<int> getStronglyConnectedComps(vector<vector<int>>& g) {
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
auto size = g.size();
@@ -1180,8 +1162,9 @@ map<FuncInfo*, vector<BBlock*>> buildCFG(const map<string, CommonBlock*>& common
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& [func, blocks] : result)
removedUnreachableBlocks(blocks);
if (!settings.withUnreachable)
for (auto& [func, blocks] : result)
removedUnreachableBlocks(blocks);
return result;
}

View File

@@ -6,10 +6,6 @@
#include <vector>
#include "IR.h"
#include "../Utils/errors.h"
#include "../Utils/utils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "IR_domTree.h"
namespace SAPFOR
@@ -45,8 +41,7 @@ namespace SAPFOR
BasicBlock(IR_Block* item);
BasicBlock(const BasicBlock& copyFrom);
void addInstructionBefore(IR_Block* item, Instruction* istruction);
void addInstruction(IR_Block* item, bool pushFront = false);
void addInstruction(IR_Block* item);
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
void addNext(BasicBlock* next_) { next.push_back(next_); }
void setDom(BasicBlock* dom) { directDominator = dom; }
@@ -110,23 +105,52 @@ namespace SAPFOR
struct CFG_Settings
{
enum setting { CFG_atLeastOneIterInLoop = 1,
CFG_withRD = 2,
CFG_withRegisters = 3,
CFG_withSPF = 4,
CFG_withDVM = 5,
CFG_withCallsInBlocks = 6,
CFG_withCallFrom = 7,
CFG_withDominators = 8,
CFG_withUnreachable = 9 };
bool atLeastOneIterInLoop = false;
bool withRD = true;
bool withRegisters = false;
bool withSPF = false;
bool withDVM = false;
bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock
bool withCallFrom = true;
bool withDominators = true;
bool withRD = false;
bool withRegisters = false;
bool withSPF = false;
bool withDVM = false;
bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock
bool withCallFrom = false;
bool withDominators = false;
bool withUnreachable = false;
explicit CFG_Settings(int) { }
explicit CFG_Settings(bool atLeastOneIterInLoop = false, bool withRD = true, bool withRegisters = false,
bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false,
bool withCallFrom = true, bool withDominators = true) :
atLeastOneIterInLoop(atLeastOneIterInLoop), withRD(withRD), withRegisters(withRegisters), withDVM(withDVM), withSPF(withSPF),
withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom), withDominators(withDominators)
{ }
explicit CFG_Settings(const std::set<setting> &settings = { CFG_withRD, CFG_withCallFrom, CFG_withDominators })
{
for (auto& set : settings)
{
if (set == CFG_atLeastOneIterInLoop)
atLeastOneIterInLoop = true;
else if (set == CFG_withRD)
withRD = true;
else if (set == CFG_withRegisters)
withRegisters = true;
else if (set == CFG_withSPF)
withSPF = true;
else if (set == CFG_withDVM)
withDVM = true;
else if (set == CFG_withCallsInBlocks)
withCallsInBlocks = true;
else if (set == CFG_withCallFrom)
withCallFrom = true;
else if (set == CFG_withDominators)
withDominators = true;
else if (set == CFG_withUnreachable)
withUnreachable = true;
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
};
}

View File

@@ -42,7 +42,6 @@ namespace SAPFOR
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, 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)
{
if (type != CFG_ARG_TYPE::INSTR && type == CFG_ARG_TYPE::LAB &&
@@ -51,9 +50,6 @@ namespace SAPFOR
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; }
CFG_ARG_TYPE getType() const { return type; }

View File

@@ -1,386 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <set>
#include "../Utils/SgUtils.h"
#include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
#include "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;
}

View File

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

View File

@@ -200,20 +200,46 @@ static void fillOutForFunc(const FuncInfo* func, const vector<SAPFOR::BasicBlock
outForFunc[func->funcName] = { defined, common_defined };
}
static void getDefsFromBlock(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& res,
static bool isInstructionSpfParameter(SAPFOR::Instruction* instr)
{
SgStatement* st = instr->getOperator();
// check if this operator is SPF(ANALYSIS(PARAMETER( )))
if (st && st->variant() == ASSIGN_STAT)
{
if (st->lineNumber() < 0 && st->numberOfAttributes())
{
for (int i = 0; i < st->numberOfAttributes(); ++i)
{
SgAttribute* attr = st->getAttribute(i);
SgStatement* attributeStatement = (SgStatement*)(attr->getAttributeData());
int type = st->attributeType(i);
if (type == SPF_PARAMETER_OP)
return true;
}
}
}
return false;
}
static void getDefsFromBlock(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& res,
const vector<pair<const Variable*, CommonBlock*>>& commonVars,
const FuncInfo* func)
{
vector<SAPFOR::Argument*> lastParamRef;
for (auto ir_block : block->getInstructions())
for (const auto &ir_block : block->getInstructions())
{
SAPFOR::Instruction* instr = ir_block->getInstruction();
if (isInstructionSpfParameter(instr))
continue;
SAPFOR::CFG_OP instr_operation = instr->getOperation();
if (instr_operation == SAPFOR::CFG_OP::PARAM)
{
SAPFOR::Argument* arg = instr->getArg1();
if(arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
addPlaceWithDef(commonVars, func, arg, instr);
lastParamRef.push_back(arg);
@@ -236,12 +262,20 @@ static void getDefsFromBlock(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>&
int last_instr_num = block->getInstructions().back()->getNumber();
for (const auto& def : block->getRD_Out())
{
for (int place : def.second)
{
if (place >= first_instr_num && place <= last_instr_num && def.first->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
{
SAPFOR::Instruction* instr = block->getInstructions()[place - first_instr_num]->getInstruction();
if (isInstructionSpfParameter(instr))
continue;
res.insert(def.first);
addPlaceWithDef(commonVars, func, def.first, block->getInstructions()[place - first_instr_num]->getInstruction());
addPlaceWithDef(commonVars, func, def.first, instr);
}
}
}
}
// recursively analyze FOR loops
@@ -266,7 +300,7 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
SAPFOR::BasicBlock* head_block = NULL;
int loop_start = loop->lineNum, loop_end = loop->lineNumAfterLoop;
for (auto bb : blocks)
for (const auto &bb : blocks)
{
if (!bb || (bb->getInstructions().size() == 0))
continue;
@@ -287,6 +321,12 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
}
}
if (currentLoop.empty()) // can't find loop IR - loop unreachable!
{
__spf_print(1, "Unreachable loop on %s:%d\n", current_file->filename(), loop_operator->lineNumber());
return currentLoop;
}
if (!head_block)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -348,7 +388,7 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
getDefsFromBlock(*loop_it, changeValueOnExit, commonVars, func);
for (auto bb : currentLoop)
for (const auto &bb : currentLoop)
{
//fill LiveWhenLoopEnds
bool has_next_outside_body = false;

View File

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

View File

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

View File

@@ -853,12 +853,21 @@ static pair<string, string> getModuleRename(const set<SgStatement*>& allocatable
return make_pair("", "");
}
static void doRename(string& str, const pair<string, string>& renamePair)
{
auto it = str.find(renamePair.first);
if (it != string::npos)
if (str[it + renamePair.first.size()] == '(' && str[it - 1] == ' ')
str = str.replace(it, renamePair.first.size(), renamePair.second);
}
static pair<DIST::Array*, string>
getNewDirective(const string &fullArrayName,
const vector<string> &distrRules,
const vector<string> &alignRules,
const DataDirective &dataDir,
const set<SgStatement*>& allocatableStmts)
const set<SgStatement*>& allocatableStmts,
const pair<string, int>& position_decl)
{
string out = "";
DIST::Array* outA = NULL;
@@ -877,7 +886,8 @@ getNewDirective(const string &fullArrayName,
for (int i = 0; i < dataDir.alignRules.size(); ++i)
{
if (dataDir.alignRules[i].alignArray->GetName() == fullArrayName)
auto alignArray = dataDir.alignRules[i].alignArray;
if (alignArray->GetName() == fullArrayName)
{
string rule = alignRules[i];
if (allocatableStmts.size())
@@ -889,21 +899,21 @@ getNewDirective(const string &fullArrayName,
it = rule.find("ALIGN", it + 7);
}
auto renamePair = getModuleRename(allocatableStmts, dataDir.alignRules[i].alignArray);
if (renamePair.first != "")
{
it = rule.find(renamePair.first);
if (it != string::npos)
if (rule[it + renamePair.first.size()] == '(' && rule[it - 1] == ' ')
rule = rule.replace(it, renamePair.first.size(), renamePair.second);
}
auto renamePair = getModuleRename(allocatableStmts, alignArray);
doRename(rule, renamePair);
}
else if (alignArray->GetLocation().first == DIST::l_COMMON)
{
auto symb = alignArray->GetDeclSymbol(position_decl);
if (symb->identifier() != alignArray->GetShortName())
doRename(rule, make_pair(alignArray->GetShortName(), symb->identifier()));
}
out += "!DVM$ " + rule + "\n";
if (!out_free_form)
out = splitDirective(out);
return make_pair(dataDir.alignRules[i].alignArray, out);
return make_pair(alignArray, out);
}
}
@@ -1743,7 +1753,7 @@ void insertDistributionToFile(SgFile *file, const char *fin_name, const DataDire
if (allocatableStmtsCopy.size())
allocatableStmts = filterAllocateStats(file, allocatableStmtsCopy, currSymb->identifier());
pair<DIST::Array*, string> dirWithArray = getNewDirective(fullArrayName, distrRules, alignRules, dataDir, allocatableStmts);
pair<DIST::Array*, string> dirWithArray = getNewDirective(fullArrayName, distrRules, alignRules, dataDir, allocatableStmts, make_pair(st->fileName(), st->lineNumber()));
string toInsert = dirWithArray.second;
if (toInsert != "")
@@ -1975,20 +1985,27 @@ void insertDistributionToFile(SgFile *file, const char *fin_name, const DataDire
set<string> toInsertArrays;
for (auto &array : dynamicArraysLocal)
{
string name = array->GetShortName();
if (array->GetLocation().first == DIST::l_COMMON)
{
auto symb = array->GetDeclSymbol(make_pair(st->fileName(), st->lineNumber()));
name = symb->identifier();
}
if (extractDir)
{
if (dynamicArraysAdded.find(array->GetShortName()) != dynamicArraysAdded.end())
if (dynamicArraysAdded.find(name) != dynamicArraysAdded.end())
{
dynamicArraysAdded.erase(array->GetShortName());
toInsertArrays.insert(array->GetShortName());
dynamicArraysAdded.erase(name);
toInsertArrays.insert(name);
}
}
else
{
if (dynamicArraysAdded.find(array->GetShortName()) == dynamicArraysAdded.end())
if (dynamicArraysAdded.find(name) == dynamicArraysAdded.end())
{
dynamicArraysAdded.insert(array->GetShortName());
toInsertArrays.insert(array->GetShortName());
dynamicArraysAdded.insert(name);
toInsertArrays.insert(name);
}
}
}
@@ -2145,7 +2162,14 @@ void insertShadowSpecToFile(SgFile *file, const char *fin_name, const set<string
if (needToGen)
{
string shadowSpecInsert = "!DVM$ SHADOW " + array->GetShortName() + "(";
string name = array->GetShortName();
if (array->GetLocation().first == DIST::l_COMMON)
{
auto symb = array->GetDeclSymbol(make_pair(st->fileName(), st->lineNumber()));
name = symb->identifier();
}
string shadowSpecInsert = "!DVM$ SHADOW " + name + "(";
for (int k = 0; k < currSpec.size(); ++k)
{
char buf[256];
@@ -2157,7 +2181,7 @@ void insertShadowSpecToFile(SgFile *file, const char *fin_name, const set<string
shadowSpecInsert += ")\n";
shadowsSpecsString.push_back(shadowSpecInsert);
pair<SgExpression*, SgExpression*> newSpec = genShadowSpec(file, make_pair(array->GetShortName(), currSpec));
pair<SgExpression*, SgExpression*> newSpec = genShadowSpec(file, make_pair(name, currSpec));
if (newSpec.first == NULL || newSpec.second == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
shadowsSpecs.push_back(newSpec);

View File

@@ -15,7 +15,7 @@
#include "SgUtils.h"
#include "expr_transform.h"
#include "../CFGraph/CFGraph.h"
#include "CFGraph/CFGraph.h"
#include "shadow.h"
#include "dvm.h"
@@ -26,6 +26,7 @@ using std::string;
using std::vector;
using std::pair;
using std::make_pair;
using SAPFOR::CFG_Settings;
extern int debSh;
@@ -1672,9 +1673,12 @@ void GroupShadow(const map<string, vector<FuncInfo*>>& allFuncs,
SgStatement* func = currF->funcPointer->GetOriginal();
auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, true, false, true, false), commonBlocks, allFuncs);
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop, CFG_Settings::CFG_withDVM,
CFG_Settings::CFG_withCallsInBlocks, CFG_Settings::CFG_withUnreachable });
auto cfg = buildCFGforCurrentFunc(func, settings, commonBlocks, allFuncs);
if (cfg.size() != 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto& blocks = cfg.begin()->second;
//create reaching blocks

View File

@@ -336,9 +336,24 @@ namespace Distribution
if (pos != STRING::npos)
{
name.erase(pos, shortName.size());
shortName = newName;
name += newName;
}
else if (locationPos.first == l_COMMON) // name of array in common may be different
{
pos = name.rfind("_");
if (pos != STRING::npos)
{
name.erase(pos + 1, shortName.size());
name += newName;
}
else
{
#if __SPF
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
#endif
}
}
shortName = newName;
GenUniqKey();
}
@@ -542,6 +557,44 @@ namespace Distribution
return NULL;
}
Symbol* GetDeclSymbol(const PAIR<STRING, int>& position_decl) const
{
if (!IsArray() || locationPos.first != l_COMMON)
return declSymbol;
auto it = declPlacesSymbol.find(position_decl);
if (it != declPlacesSymbol.end())
return it->second;
else // find nearest
{
MAP<PAIR<STRING, int>, Symbol*> currFile;
for (auto& [position, symb] : declPlacesSymbol)
{
if (position.first == position_decl.first)
currFile[position] = symb;
}
PAIR<int, Symbol*> nearest = { (int)0, NULL };
const int needed_pos = position_decl.second;
for (auto& [position, symb] : currFile)
{
if (nearest.second == NULL)
nearest = { abs(position.second - needed_pos), symb };
if (abs(position.second - needed_pos) < nearest.first)
nearest = { abs(position.second - needed_pos), symb };
}
if (nearest.second)
return nearest.second;
#if __SPF
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
#endif
}
return NULL;
}
Symbol* GetDeclSymbol() const { return declSymbol; }
void SetDeclSymbol(Symbol *s) { declSymbol = s; }

View File

@@ -241,13 +241,15 @@ static void findArrayRefs (SgExpression* ex, SgStatement* st, string fName, int
itNew->second.first->SetRegionPlace(reg);
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 (itNew->second.first->IsOmpThreadPrivate())
itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV);
else if (privates.find(symb->identifier()) != privates.end() || isarrayInModule)
else if (deprecatedByIO.find(symb->identifier()) != deprecatedByIO.end())
itNew->second.first->SetDistributeFlag(DIST::IO_PRIV);
else if (isArrayInModule || privates.find(symb->identifier()) != privates.end())
{
//check in module
if (itNew->second.first->GetLocation().first == DIST::l_MODULE)
@@ -274,8 +276,6 @@ static void findArrayRefs (SgExpression* ex, SgStatement* st, string fName, int
else
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)
itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV);
else

View File

@@ -274,7 +274,7 @@ static void convertTrees(const map<DIST::Array*, int> &treesIn, map<int, vector<
static DIST::Array* findBestInEqual(vector<DIST::Array*> &arrays, DIST::GraphCSR<int, double, attrType> &reducedG, DIST::Arrays<int> &allArrays)
{
DIST::Array *retVal = NULL;
vector<vector<attrType>> coefsByDims;
vector<vector<attrType>> coeffsByDims;
for (auto &array : arrays)
{
vector<int> verts;
@@ -285,7 +285,7 @@ static DIST::Array* findBestInEqual(vector<DIST::Array*> &arrays, DIST::GraphCSR
{
retVal = array;
for (auto &V : verts)
coefsByDims.push_back(reducedG.GetAllAttributes(V));
coeffsByDims.push_back(reducedG.GetAllAttributes(V));
}
else
{
@@ -294,11 +294,11 @@ static DIST::Array* findBestInEqual(vector<DIST::Array*> &arrays, DIST::GraphCSR
toCmp.push_back(reducedG.GetAllAttributes(V));
for (int z = 0; z < toCmp.size(); ++z)
{
if (toCmp[z].size() && coefsByDims[z].size())
if (toCmp[z].size() && coeffsByDims[z].size())
{
if (toCmp[z].back().first.first > coefsByDims[z].back().first.first)
if (toCmp[z].back().first.first > coeffsByDims[z].back().first.first)
{
coefsByDims = toCmp;
coeffsByDims = toCmp;
retVal = array;
break;
}

View File

@@ -45,10 +45,10 @@ static bool findArrayRefAndCheck(SgExpression *ex, const DIST::Array* currArray,
int countOfShadows = 0;
for (int i = 0; i < ref->numberOfSubscripts(); ++i)
{
const vector<int*> &coefs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
if (coefs.size() == 1)
const vector<int*> &coeffs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
if (coeffs.size() == 1)
{
const pair<int, int> coef(coefs[0][0], coefs[0][1]);
const pair<int, int> coef(coeffs[0][0], coeffs[0][1]);
auto it = shiftsByAccess[i].find(coef);
if (it != shiftsByAccess[i].end())
if (it->second != 0)

View File

@@ -364,11 +364,11 @@ static inline string calculateShifts(DIST::GraphCSR<int, double, attrType> &redu
{
if (sharedMemoryParallelization)
{
for (auto& coefs : currReadOp->first[k].coefficients)
for (auto& coeffs : currReadOp->first[k].coefficients)
{
auto currAccess = coefs.first;
auto currAccess = coeffs.first;
const int currShift = coefs.first.second;
const int currShift = coeffs.first.second;
auto itFound = shiftsByAccess[k].find(currAccess);
if (itFound == shiftsByAccess[k].end())
@@ -393,9 +393,9 @@ static inline string calculateShifts(DIST::GraphCSR<int, double, attrType> &redu
int minShift = 9999999;
int maxShift = -9999999;
for (auto &coefs : currReadOp->first[k].coefficients)
for (auto &coeffs : currReadOp->first[k].coefficients)
{
auto currAccess = coefs.first;
auto currAccess = coeffs.first;
auto result = DIST::Fx(currAccess, currRuleShadow);
if (result.first == loopRule.first)
@@ -417,7 +417,7 @@ static inline string calculateShifts(DIST::GraphCSR<int, double, attrType> &redu
auto it = remoteRegularReads.find(calcForArray);
if (it == remoteRegularReads.end())
it = remoteRegularReads.insert(it, make_pair(calcForArray, vector<ArrayOp>(calcForArray->GetDimSize())));
it->second[k].coefficients.insert(coefs);
it->second[k].coefficients.insert(coeffs);
}
}

View File

@@ -11,9 +11,9 @@
#include "DvmhRegionInserter.h"
#include "DvmhRegions/RegionsMerger.h"
#include "../VerificationCode/verifications.h"
#include "../Transformations/FunctionPurifying/function_purifying.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "FunctionPurifying/function_purifying.h"
using namespace std;
@@ -794,154 +794,6 @@ ArraySet DvmhRegionInserter::get_used_arrs_for_block(SgStatement* st, int usage_
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)
{
auto prev_st = loop->loop->lexPrev();
@@ -1172,7 +1024,7 @@ static bool isPure(SgStatement* func)
void DvmhRegionInserter::createInterfaceBlockForOutCall(FuncInfo* func, FuncInfo* callFrom)
{
insertInterface(func->funcPointer, getInterfaceBlock(callFrom->funcPointer->GetOriginal(), callFrom->funcParams), callFrom->funcName);
insertInterface(func->funcPointer, callFrom);
}
void DvmhRegionInserter::createInterfaceBlockForParallelFunctions(bool onlyRoutine)
@@ -1445,7 +1297,10 @@ static set<DIST::Array*>
{
declStat = SgStatement::getStatementByFileAndLine(decl.first, decl.second);
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())
{
if (st->fileName() == decl.first && st->lineNumber() == decl.second)
@@ -1457,7 +1312,7 @@ static set<DIST::Array*>
}
else
{
declStat = getFuncStat(declStat);
declStat = getFuncStat(declStat, { BLOCK_DATA });
if (declStat != main)
{
declStat = NULL;

View File

@@ -14,7 +14,7 @@
#include "dvm.h"
#include "graph_calls_func.h"
#include "../CFGraph/CFGraph.h"
#include "CFGraph/CFGraph.h"
#include "graph_loops_func.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "SgUtils.h"
@@ -779,6 +779,20 @@ 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)
{
if (currF->funcParams.countOfPars == 0)
@@ -798,8 +812,13 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co
if (st->variant() == ENTRY_STAT)
continue;
if (isSgExecutableStatement(st) == NULL) {
checkInTypeDescription(st->expr(0), currF, parNames);
continue;
}
if (isSgExecutableStatement(st) == NULL || st->lineNumber() <= 0)
if (st->lineNumber() <= 0)
continue;
if (activeOps.size() && activeOps.find(st) == activeOps.end())

View File

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

View File

@@ -1137,9 +1137,9 @@ static bool isMapped(const vector<ArrayOp> &allOps)
bool mapped = false;
for (auto &ops : allOps)
{
for (auto &coefs : ops.coefficients)
for (auto &coeffs : ops.coefficients)
{
if (coefs.first.first != 0)
if (coeffs.first.first != 0)
{
mapped = true;
break;

View File

@@ -1,281 +0,0 @@
#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

@@ -1,7 +0,0 @@
#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/SendMessage.h"
#include "../Transformations/LoopEndDoConverter/enddo_loop_converter.h"
#include "LoopEndDoConverter/enddo_loop_converter.h"
#include "../DirectiveProcessing/remote_access.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
@@ -247,7 +247,7 @@ static vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentL
}
}
pair<int, int> coefs = pair<int, int>(0, 0);
pair<int, int> coeffs = pair<int, int>(0, 0);
// more than one loop symbol in subscription
if (countOfSymbols > 1)
{
@@ -326,16 +326,16 @@ static vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentL
{
if (subscr->symbol()->id() == (parentLoops[position]->doName())->id())
{
coefs.first = 1;
coeffs.first = 1;
needToCacl = false;
}
}
if (needToCacl)
getCoefsOfSubscript(coefs, subscr, parentLoops[position]->doName());
__spf_print(PRINT_ARRAY_ARCS, " <%d %d> ", coefs.first, coefs.second);
getCoefsOfSubscript(coeffs, subscr, parentLoops[position]->doName());
__spf_print(PRINT_ARRAY_ARCS, " <%d %d> ", coeffs.first, coeffs.second);
if (coefs.first == 0) // && coefs.second == 0)
if (coeffs.first == 0) // && coeffs.second == 0)
{
if (currRegime == REMOTE_ACC)
{
@@ -346,7 +346,7 @@ static vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentL
{
const pair<bool, string> &arrayRefString = constructArrayRefForPrint(arrayRef, dimNum, origSubscr);
__spf_print(1, "WARN: can not calculate index expression for array ref '%s' at line %d\n", arrayRefString.second.c_str(), currLine);
addInfoToVectors(loopInfo, parentLoops[position], currOrigArrayS, dimNum, coefs, UNREC_OP, numOfSubscriptions, currentW);
addInfoToVectors(loopInfo, parentLoops[position], currOrigArrayS, dimNum, coeffs, UNREC_OP, numOfSubscriptions, currentW);
if (side == LEFT)
allPositions.clear();
@@ -371,19 +371,19 @@ static vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentL
currOp.resize(numOfSubscriptions);
//add only uniq
auto itAdd = currOp[dimNum].coefficients.find(coefs);
auto itAdd = currOp[dimNum].coefficients.find(coeffs);
if (itAdd == currOp[dimNum].coefficients.end())
itAdd = currOp[dimNum].coefficients.insert(itAdd, make_pair(coefs, currentW));
itAdd = currOp[dimNum].coefficients.insert(itAdd, make_pair(coeffs, currentW));
}
if (coefs.first < 0)
if (coeffs.first < 0)
addInfoToMap(loopInfo, parentLoops[position], currOrigArrayS, arrayRef, dimNum, REMOTE_TRUE, currLine, numOfSubscriptions);
else
//if we found regular access to array - set it false
addInfoToMap(loopInfo, parentLoops[position], currOrigArrayS, arrayRef, dimNum, REMOTE_FALSE, currLine, numOfSubscriptions);
}
if (coefs.first < 0 && sharedMemoryParallelization == 0)
if (coeffs.first < 0 && sharedMemoryParallelization == 0)
{
if (currRegime == DATA_DISTR)
{
@@ -402,15 +402,15 @@ static vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentL
if (side == LEFT)
allPositions.clear();
else
addInfoToVectors(loopInfo, parentLoops[position], currOrigArrayS, dimNum, coefs, UNREC_OP, numOfSubscriptions, currentW);
addInfoToVectors(loopInfo, parentLoops[position], currOrigArrayS, dimNum, coeffs, UNREC_OP, numOfSubscriptions, currentW);
}
}
else
{
if (side == LEFT)
addInfoToVectors(loopInfo, parentLoops[position], currOrigArrayS, dimNum, coefs, WRITE_OP, numOfSubscriptions, currentW);
addInfoToVectors(loopInfo, parentLoops[position], currOrigArrayS, dimNum, coeffs, WRITE_OP, numOfSubscriptions, currentW);
else
addInfoToVectors(loopInfo, parentLoops[position], currOrigArrayS, dimNum, coefs, READ_OP, numOfSubscriptions, currentW);
addInfoToVectors(loopInfo, parentLoops[position], currOrigArrayS, dimNum, coeffs, READ_OP, numOfSubscriptions, currentW);
}
}
}
@@ -418,13 +418,13 @@ static vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentL
if (currRegime == ARRAY_ACC_CORNER)
{
int *valueSubs = new int[2];
valueSubs[0] = coefs.first;
valueSubs[1] = coefs.second;
valueSubs[0] = coeffs.first;
valueSubs[1] = coeffs.second;
#ifdef __SPF
addToCollection(__LINE__, __FILE__, valueSubs, 2);
#endif
const vector<int*> &coefs = getAttributes<SgExpression*, int*>(subscr, set<int>{ INT_VAL });
if (coefs.size() == 0)
const vector<int*> &coeffs = getAttributes<SgExpression*, int*>(subscr, set<int>{ INT_VAL });
if (coeffs.size() == 0)
{
subscr->addAttribute(INT_VAL, valueSubs, sizeof(int*));
if (position != -1 && allPositions.size() == 1 && position < parentLoops.size())

View File

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

View File

@@ -22,7 +22,7 @@
#include "graph_loops_func.h"
#include "expr_transform.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../CFGraph/CFGraph.h"
#include "CFGraph/CFGraph.h"
#include "json.hpp"
@@ -33,6 +33,7 @@ using std::set;
using std::ofstream;
using std::pair;
using std::tuple;
using SAPFOR::CFG_Settings;
using json = nlohmann::json;
@@ -326,7 +327,7 @@ static json parseAlign(const map<DIST::Array*, int>& byPos, SgSymbol* srcArr, Sg
list = list->rhs();
}
vector<pair<int, int>> coefs(srcSymbs.size());
vector<pair<int, int>> coeffs(srcSymbs.size());
list = listTgt;
while (list)
{
@@ -337,8 +338,8 @@ static json parseAlign(const map<DIST::Array*, int>& byPos, SgSymbol* srcArr, Sg
has = recSymbolFind(exp, srcSymbs[z].first, VAR_REF);
if (has)
{
getCoefsOfSubscript(coefs[z], exp, srcSymbs[z].second);
if (coefs[z].first == 0)
getCoefsOfSubscript(coeffs[z], exp, srcSymbs[z].second);
if (coeffs[z].first == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
break;
}
@@ -346,14 +347,14 @@ static json parseAlign(const map<DIST::Array*, int>& byPos, SgSymbol* srcArr, Sg
list = list->rhs();
}
for (int z = 0; z < coefs.size(); ++z)
for (int z = 0; z < coeffs.size(); ++z)
{
if (coefs[z].first == 0)
if (coeffs[z].first == 0)
continue;
if (coefs[z].second)
align["rules"].push_back({ z, coefs[z].first });
if (coeffs[z].second)
align["rules"].push_back({ z, coeffs[z].first });
else
align["rules"].push_back({ z, coefs[z].first, coefs[z].second });
align["rules"].push_back({ z, coeffs[z].first, coeffs[z].second });
}
return align;
}
@@ -507,7 +508,8 @@ static void parallelDir(const map<DIST::Array*, int>& byPos, SgExpression* spec,
if (currF == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, true, false, false, true), commonBlocks, allFuncInfo);
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop, CFG_Settings::CFG_withSPF, CFG_Settings::CFG_withDominators });
auto cfg = buildCFGforCurrentFunc(func, settings, commonBlocks, allFuncInfo);
//TODO IP analysis
unsigned countOfAccess = 0;

View File

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

View File

@@ -1,3 +1,4 @@
#include <algorithm>
#include <map>
#include <unordered_set>
#include <unordered_map>
@@ -11,50 +12,121 @@
#include "region.h"
#include "SgUtils.h"
#include "graph_loops.h"
#include "../CFGraph/CFGraph.h"
#include "CFGraph/CFGraph.h"
#include "utils.h"
using namespace std;
void Collapse(Region* region)
static unordered_set<Region*> collapsed;
static void RemoveEmptyPoints(ArrayAccessingIndexes& container)
{
ArrayAccessingIndexes resultContainer;
unordered_set<string> toRemove;
for (auto& [arrayName, accessingSet] : container)
{
vector<vector<ArrayDimension>> points;
for (auto& arrayPoint : accessingSet.GetElements())
{
if (!arrayPoint.empty())
points.push_back(arrayPoint);
}
if (points.size() < accessingSet.GetElements().size() && !points.empty())
resultContainer[arrayName] = points;
if (points.empty())
toRemove.insert(arrayName);
}
for (const string& name : toRemove)
container.erase(name);
for (auto& [arrayName, accessingSet] : resultContainer)
container[arrayName] = accessingSet;
}
static void Collapse(Region* region)
{
if (region->getBasickBlocks().empty())
return;
for (auto& [arrayName, arrayRanges] : region->getHeader()->array_out)
bool firstRegion = true;
for (Region* basickBlock : region->getBasickBlocks())
{
for (Region* byBlock : region->getBasickBlocks())
if (basickBlock->getNextRegions().empty())
{
AccessingSet intersection = byBlock->array_def[arrayName].Intersect(arrayRanges);
region->array_def[arrayName] = region->array_def[arrayName].Union(intersection);
if (firstRegion)
{
region->array_def = basickBlock->array_out;
firstRegion = false;
}
else
{
unordered_set<string> toErease;
for (auto& [arrayName, arrayRanges] : region->array_def)
{
if (basickBlock->array_out.find(arrayName) != basickBlock->array_out.end())
arrayRanges = arrayRanges.Intersect(basickBlock->array_out[arrayName]);
else
{
arrayRanges = AccessingSet();
toErease.insert(arrayName);
}
}
for (string arrayName : toErease)
region->array_def.erase(arrayName);
}
}
}
for (auto& byBlock : region->getBasickBlocks())
{
for (auto& [arrayName, arrayRanges] : byBlock->array_use)
{
AccessingSet diff = byBlock->array_use[arrayName].Diff(byBlock->array_in[arrayName]);
region->array_use[arrayName] = region->array_use[arrayName].Union(diff);
}
}
ArrayAccessingIndexes useUnion;
RegionInstruction instruction;
instruction.def = move(region->array_def);
for (auto& byBlock : region->getBasickBlocks())
for (auto& [arrayName, arrayRanges] : byBlock->array_use)
useUnion[arrayName] = useUnion[arrayName].Union(byBlock->array_use[arrayName]);
{
for (auto& instruction : byBlock->instructions)
{
for (auto& [arrayName, _] : instruction.use)
{
AccessingSet diff = instruction.use[arrayName].Diff(instruction.in[arrayName]);
region->array_use[arrayName] = region->array_use[arrayName].Union(diff);
}
}
}
for (auto& [arrayName, arrayRanges] : useUnion)
region->array_priv[arrayName] = useUnion[arrayName].Diff(region->array_use[arrayName]);
for (Region* prevBlock : region->getHeader()->getPrevRegions())
ArrayAccessingIndexes useUnionB;
for (auto& byBlock : region->getBasickBlocks())
for (auto& instruction : byBlock->instructions)
for (auto& [arrayName, _] : instruction.use)
useUnionB[arrayName] = useUnionB[arrayName].Union(instruction.use[arrayName]);
for (auto& [arrayName, _] : useUnionB)
region->array_priv[arrayName] = useUnionB[arrayName].Diff(region->array_use[arrayName]);
instruction.use = move(region->array_use);
for (Region* prevBlock : region->getHeader()->getPrevRegions())
{
prevBlock->replaceInNextRegions(region, region->getHeader());
region->addPrevRegion(prevBlock);
}
for (Region* nextBlock : region->getHeader()->getNextRegions())
{
nextBlock->replaceInPrevRegions(region, region->getHeader());
region->addNextRegion(nextBlock);
}
region->instructions.push_back(instruction);
}
static void SolveDataFlowIteratively(Region* DFG)
static void SolveDataFlowIteratively(Region* DFG)
{
unordered_set<Region*> worklist(DFG->getBasickBlocks());
auto blocks = DFG->getBasickBlocks();
std::unordered_set<Region*> worklist(blocks.begin(), blocks.end());
do
{
Region* b = *worklist.begin();
@@ -72,12 +144,13 @@ static void SolveDataFlowIteratively(Region* DFG)
if (prevBlock->array_out.empty())
{
newIn.clear();
continue;
break;
}
for (const auto& [arrayName, accessSet] : prevBlock->array_out)
{
if (newIn.find(arrayName) != newIn.end())
newIn[arrayName] = newIn[arrayName].Intersect(accessSet);
newIn[arrayName] = newIn[arrayName].Intersect(accessSet);
else
newIn[arrayName] = AccessingSet();
}
@@ -86,7 +159,8 @@ static void SolveDataFlowIteratively(Region* DFG)
b->array_in = move(newIn);
ArrayAccessingIndexes newOut;
if (b->array_def.empty())
if (b->array_def.empty())
newOut = b->array_in;
else if (b->array_in.empty())
newOut = b->array_def;
@@ -102,40 +176,236 @@ static void SolveDataFlowIteratively(Region* DFG)
}
/* can not differ */
if (newOut != b->array_out)
if (newOut != b->array_out)
b->array_out = newOut;
else
worklist.erase(b);
}
while (!worklist.empty());
} while (!worklist.empty());
}
static void SolveForBasickBlock(Region* block)
{
ArrayAccessingIndexes newIn;
bool flagFirst = true;
for (Region* prevBlock : block->getPrevRegions())
{
if (flagFirst)
{
newIn = prevBlock->array_out;
flagFirst = false;
}
else
{
if (prevBlock->array_out.empty())
{
newIn.clear();
break;
}
for (const auto& [arrayName, accessSet] : prevBlock->array_out)
{
if (newIn.find(arrayName) != newIn.end())
newIn[arrayName] = newIn[arrayName].Intersect(accessSet);
else
newIn[arrayName] = AccessingSet();
}
}
}
if (block->instructions.empty())
block->instructions.push_back(RegionInstruction());
block->instructions[0].in = move(newIn);
for (int i = 0; i < block->instructions.size(); i++)
{
auto& instruction = block->instructions[i];
if (i > 0)
instruction.in = block->instructions[i - 1].out;
ArrayAccessingIndexes newOut;
if (instruction.def.empty())
newOut = instruction.in;
else if (instruction.in.empty())
newOut = instruction.def;
else
{
for (auto& [arrayName, accessSet] : instruction.def)
{
if (instruction.in.find(arrayName) != instruction.in.end())
newOut[arrayName] = instruction.def[arrayName].Union(instruction.in[arrayName]);
else
newOut[arrayName] = accessSet;
}
for (auto& [arrayName, accessSet] : instruction.in)
{
if (newOut.find(arrayName) == newOut.end())
{
newOut[arrayName] = accessSet;
}
}
}
instruction.out = move(newOut);
}
if (!block->instructions.empty())
block->array_out = block->instructions.back().out;
}
static void SolveDataFlowTopologically(Region* DFG)
{
for (Region* b : DFG->getBasickBlocks())
{
collapsed.insert(b);
SolveForBasickBlock(b);
}
}
static void SolveDataFlow(Region* DFG)
{
if (!DFG)
return;
SolveDataFlowIteratively(DFG);
for (Region* subRegion : DFG->getSubRegions())
{
SolveDataFlow(subRegion);
DFG->addBasickBlocks(subRegion);
}
vector<Region*>& blocks = DFG->getBasickBlocks();
auto pos = remove_if(blocks.begin(), blocks.end(), [](Region* r) { return collapsed.find(r) != collapsed.end(); });
blocks.erase(pos, blocks.end());
TopologySort(DFG->getBasickBlocks(), DFG->getHeader());
SolveDataFlowTopologically(DFG);
Collapse(DFG);
}
map<LoopGraph*, ArrayAccessingIndexes> findPrivateArrays(map<string, vector<LoopGraph*>> &loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
{
map<LoopGraph*, ArrayAccessingIndexes> result;
for (const auto& [loopName, loops] : loopGraph)
static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>& declaredDims)
{
declaredDims.clear();
if (!arrayRef || !arrayRef->symbol() || !isSgArrayType(arrayRef->symbol()->type()))
return false;
SgArrayType* arrayType = (SgArrayType*)arrayRef->symbol()->type();
int dimCount = arrayType->dimension();
for (int i = 0; i < dimCount; i++)
{
for (const auto& loop : loops)
SgExpression* sizeExpr = arrayType->sizeInDim(i);
SgConstantSymb* constValSymb = isSgConstantSymb(sizeExpr->symbol());
string strDimLength;
if (sizeExpr && sizeExpr->variant() == INT_VAL)
strDimLength = sizeExpr->unparse();
else if (constValSymb)
strDimLength = constValSymb->constantValue()->unparse();
else
return false;
if (strDimLength == "0")
return false;
declaredDims.push_back((uint64_t)stoi(strDimLength));
}
return true;
}
static bool CheckDimensionLength(const AccessingSet& array)
{
if (array.GetElements().empty())
return false;
size_t dimCount = array.GetElements()[0].size();
SgArrayRefExp* arrayRef = array.GetElements()[0][0].array;
if (!arrayRef)
return false;
vector<uint64_t> declaredDims(dimCount);
if (!getArrayDeclaredDimensions(arrayRef, declaredDims))
return false;
vector<ArrayDimension> testArray(dimCount);
for (size_t i = 0; i < dimCount; i++)
{
testArray[i] = { 1, 1, declaredDims[i], nullptr };
}
AccessingSet diff = AccessingSet({ testArray }).Diff(array);
return diff.GetElements().empty();
}
static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set<SgStatement*>& insertedPrivates)
{
SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR);
spfStat->setlineNumber(loop->loop->lineNumber());
spfStat->setFileName(loop->loop->fileName());
SgExpression* toAdd = new SgExpression(EXPR_LIST, new SgExpression(ACC_PRIVATE_OP), NULL, NULL);
set<SgSymbol*> arraysToInsert;
for (const auto& [_, accessingSet] : privates)
{
if (!CheckDimensionLength(accessingSet))
continue;
for (const auto& arrayElement : accessingSet.GetElements())
{
for (const auto& [funcInfo, blocks]: FullIR)
{
Region* loopRegion = new Region(loop, blocks);
SolveDataFlow(loopRegion);
result[loop] = loopRegion->array_priv;
delete(loopRegion);
}
if (arrayElement.empty())
continue;
arraysToInsert.insert(arrayElement[0].array->symbol());
}
}
return result;
spfStat->setExpression(0, *toAdd);
toAdd = toAdd->lhs();
bool first = true;
for (auto& elem : arraysToInsert)
{
if (first)
{
toAdd->setLhs(new SgExpression(EXPR_LIST));
toAdd = toAdd->lhs();
first = false;
}
else
{
toAdd->setRhs(new SgExpression(EXPR_LIST));
toAdd = toAdd->rhs();
}
toAdd->setLhs(new SgVarRefExp(elem));
}
if (arraysToInsert.size() != 0)
{
loop->loop->insertStmtBefore(*spfStat, *loop->loop->controlParent());
insertedPrivates.insert(spfStat);
}
}
void FindPrivateArrays(map<string, vector<LoopGraph*>>& loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR, set<SgStatement*>& insertedPrivates)
{
map<LoopGraph*, ArrayAccessingIndexes> result;
for (const auto& [fileName, loops] : loopGraph)
{
SgFile::switchToFile(fileName);
for (const auto& loop : loops)
{
if (!loop->isFor())
continue;
SgStatement* search_func = loop->loop->GetOriginal();
while (search_func && (!isSgProgHedrStmt(search_func)))
search_func = search_func->controlParent();
for (const auto& [funcInfo, blocks] : FullIR)
{
if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func)
{
Region* loopRegion = new Region(loop, blocks);
if (loopRegion->getBasickBlocks().size() <= 1)
{
delete(loopRegion);
continue;
}
SolveDataFlow(loopRegion);
RemoveEmptyPoints(loopRegion->array_priv);
result[loop] = loopRegion->array_priv;
delete(loopRegion);
}
}
if (result.find(loop) != result.end() && !result[loop].empty())
AddPrivateArraysToLoop(loop, result[loop], insertedPrivates);
}
}
}

View File

@@ -2,13 +2,12 @@
#include <vector>
#include <map>
#include <set>
#include <unordered_set>
#include "range_structures.h"
#include "region.h"
#include "graph_loops.h"
#include "../CFGraph/CFGraph.h"
#include "CFGraph/CFGraph.h"
void Collapse(Region* region);
std::map<LoopGraph*, ArrayAccessingIndexes> findPrivateArrays(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR);
void FindPrivateArrays(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR, std::set<SgStatement*>& insertedPrivates);
std::pair<SAPFOR::BasicBlock*, std::unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const std::vector<SAPFOR::BasicBlock*> blocks);

View File

@@ -29,7 +29,7 @@ static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const A
vector<uint64_t> partSolution = FindParticularSolution(dim1, dim2);
if (partSolution.empty())
return NULL;
int64_t x0 = partSolution[0], y0 = partSolution[1];
/* x = x_0 + c * t */
/* y = y_0 + d * t */
@@ -44,10 +44,10 @@ static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const A
uint64_t tMax = min(tXMax, tYMax);
if (tMin > tMax)
return NULL;
uint64_t start3 = dim1.start + x0 * dim1.step;
uint64_t step3 = c * dim1.step;
ArrayDimension* result = new(ArrayDimension){ start3, step3, tMax + 1 };
ArrayDimension* result = new(ArrayDimension){ start3, step3, tMax + 1 , dim1.array };
return result;
}
@@ -57,25 +57,20 @@ static vector<ArrayDimension> DimensionDifference(const ArrayDimension& dim1, co
ArrayDimension* intersection = DimensionIntersection(dim1, dim2);
if (!intersection)
return { dim1 };
vector<ArrayDimension> result;
/* add the part before intersection */
if (dim1.start < intersection->start)
result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step });
if (dim1.start < intersection->start)
result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step, dim1.array });
/* add the parts between intersection steps */
uint64_t start = (intersection->start - dim1.start) / dim1.step;
uint64_t interValue = intersection->start;
for (int64_t i = start; dim1.start + i * dim1.step <= intersection->start + intersection->step * (intersection->tripCount - 1); i++)
if (intersection->step > dim1.step)
{
uint64_t centerValue = dim1.start + i * dim1.step;
if (centerValue == interValue)
uint64_t start = (intersection->start - dim1.start) / dim1.step;
uint64_t interValue = intersection->start;
for (int64_t i = start; interValue <= intersection->start + intersection->step * (intersection->tripCount - 1); i++)
{
if (i - start > 1)
{
result.push_back({ dim1.start + (start + 1) * dim1.step, dim1.step, i - start - 1 });
start = i;
}
result.push_back({ interValue + dim1.step, dim1.step, intersection->step / dim1.step, dim1.array });
interValue += intersection->step;
}
}
@@ -85,7 +80,7 @@ static vector<ArrayDimension> DimensionDifference(const ArrayDimension& dim1, co
/* first value after intersection */
uint64_t right_start = intersection->start + intersection->step * (intersection->tripCount - 1) + dim1.step;
uint64_t tripCount = (dim1.start + dim1.step * dim1.tripCount - right_start) / dim1.step;
result.push_back({ right_start, dim1.step, tripCount });
result.push_back({ right_start, dim1.step, tripCount, dim1.array });
}
delete(intersection);
return result;
@@ -114,7 +109,7 @@ static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>&
{
if (firstElement.empty() || secondElement.empty())
return {};
size_t dimAmount = firstElement.size();
/* check if there is no intersecction */
for (size_t i = 0; i < dimAmount; i++)
@@ -137,14 +132,16 @@ static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>&
static vector<vector<ArrayDimension>> ElementsDifference(const vector<ArrayDimension>& firstElement,
const vector<ArrayDimension>& secondElement)
{
if (firstElement.empty() || secondElement.empty())
if (firstElement.empty())
return {};
if (secondElement.empty())
return { firstElement };
vector<ArrayDimension> intersection = ElementsIntersection(firstElement, secondElement);
vector<vector<ArrayDimension>> result;
if (intersection.empty())
return { firstElement };
for (int i = 0; i < firstElement.size(); i++)
{
auto dimDiff = DimensionDifference(firstElement[i], secondElement[i]);
@@ -193,7 +190,7 @@ bool AccessingSet::ContainsElement(const vector<ArrayDimension>& element) const
{
vector<vector<ArrayDimension>> tails;
FindUncovered(element, tails);
return !tails.empty();
return tails.empty();
}
void AccessingSet::FindCoveredBy(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const
@@ -216,6 +213,10 @@ void AccessingSet::Insert(const vector<ArrayDimension>& element)
}
AccessingSet AccessingSet::Union(const AccessingSet& source) {
if (source.GetElements().empty())
return *this;
if (allElements.empty())
return source;
AccessingSet result;
for (auto& element : source.GetElements())
result.Insert(element);
@@ -253,13 +254,15 @@ AccessingSet AccessingSet::Diff(const AccessingSet& secondSet) const
return *this;
AccessingSet intersection = this->Intersect(secondSet);
AccessingSet uncovered = *this;
vector<vector<ArrayDimension>> result;
for (const auto& element : intersection.GetElements())
vector<vector<ArrayDimension>> uncovered;
for (const auto& element : allElements)
{
vector<vector<ArrayDimension>> current_uncovered;
uncovered.FindUncovered(element, current_uncovered);
uncovered = AccessingSet(current_uncovered);
intersection.FindUncovered(element, current_uncovered);
uncovered.insert(uncovered.end(),
std::move_iterator(current_uncovered.begin()),
std::move_iterator(current_uncovered.end())
);
}
return uncovered;
}
@@ -290,4 +293,4 @@ bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& r
return true;
return false;
}
}

View File

@@ -6,9 +6,12 @@
#include <string>
#include <cstdint>
#include "SgUtils.h"
struct ArrayDimension
{
uint64_t start, step, tripCount;
SgArrayRefExp* array;
};
class AccessingSet {

View File

@@ -1,13 +1,16 @@
#include<vector>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<string>
#include <algorithm>
#include <vector>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <numeric>
#include <iostream>
#include "range_structures.h"
#include "region.h"
#include "..\Transformations\ExpressionSubstitution\expr_transform.h"
#include "SgUtils.h"
using namespace std;
@@ -61,14 +64,14 @@ static void BuildLoopIndex(map<string, LoopGraph*>& loopForIndex, LoopGraph* loo
static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, LoopGraph*>& loopForIndex) {
unordered_set<SAPFOR::Argument*> args = { block->getInstructions()[pos]->getInstruction()->getArg1() };
for (int i = pos - 1; i >= 0; i--)
for (int i = pos - 1; i >= 0; i--)
{
SAPFOR::Argument* res = block->getInstructions()[i]->getInstruction()->getResult();
if (res && args.find(res) != args.end())
if (res && args.find(res) != args.end())
{
SAPFOR::Argument* arg1 = block->getInstructions()[i]->getInstruction()->getArg1();
SAPFOR::Argument* arg2 = block->getInstructions()[i]->getInstruction()->getArg2();
if (arg1)
if (arg1)
{
string name = arg1->getValue();
int idx = name.find('%');
@@ -92,7 +95,7 @@ static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, Loop
return "";
}
static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use) {
static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use, Region* region) {
auto instructions = block->getInstructions();
map<string, LoopGraph*> loopForIndex;
BuildLoopIndex(loopForIndex, loop);
@@ -104,15 +107,37 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
auto operation = instruction->getInstruction()->getOperation();
auto type = instruction->getInstruction()->getArg1()->getType();
if (operation == SAPFOR::CFG_OP::ASSIGN && instruction->getInstruction()->getResult()->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY)
{
SgStatement* op = instruction->getInstruction()->getOperator();
if (op && op->expr(0) && isArrayRef(op->expr(0)) && op->expr(0)->symbol() && op->expr(0)->type())
{
if (isSgArrayType(op->expr(0)->symbol()->type()))
{
SgArrayType* arrayType = (SgArrayType*)op->expr(0)->symbol()->type();
int dimCount = ((SgArrayType*)op->expr(0)->symbol()->type())->dimension();
vector<ArrayDimension> point;
for (int i = 0; i < dimCount; i++)
{
string strDimLength = arrayType->sizeInDim(i)->unparse();
if (arrayType->sizeInDim(i)->variant() == INT_VAL && strDimLength != "0")
point.push_back({ 1ULL, 1ULL, (uint64_t)stoi(strDimLength), (SgArrayRefExp*)op->expr(0) });
}
if (point.size() == dimCount)
{
def[instruction->getInstruction()->getResult()->getValue()] = AccessingSet({ point });
RegionInstruction regionInstruction;
regionInstruction.def[instruction->getInstruction()->getResult()->getValue()] = AccessingSet({ point });
}
}
}
}
if ((operation == SAPFOR::CFG_OP::STORE || operation == SAPFOR::CFG_OP::LOAD) && type == SAPFOR::CFG_ARG_TYPE::ARRAY)
{
vector<SAPFOR::Argument*> index_vars;
vector<int> refPos;
string array_name;
if (operation == SAPFOR::CFG_OP::STORE)
array_name = instruction->getInstruction()->getArg1()->getValue();
else
array_name = instruction->getInstruction()->getArg2()->getValue();
string array_name = instruction->getInstruction()->getArg1()->getValue();
int j = i - 1;
while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF)
@@ -127,75 +152,132 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
vector<ArrayDimension> accessPoint(n);
auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression());
vector<pair<int, int>> coefsForDims;
int fillCount = 0;
vector<pair<int, int>> coeffsForDims;
int subs = ref->numberOfSubscripts();
for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i)
{
const vector<int*>& coefs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
if (coefs.size() == 1)
const vector<int*>& coeffs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
if (coeffs.size() == 1)
{
const pair<int, int> coef(coefs[0][0], coefs[0][1]);
coefsForDims.push_back(coef);
const pair<int, int> coef(coeffs[0][0], coeffs[0][1]);
coeffsForDims.push_back(coef);
}
}
coeffsForDims = { coeffsForDims.rbegin(), coeffsForDims.rend() };
if(coefsForDims.empty())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
while (!index_vars.empty())
while (!index_vars.empty() && !refPos.empty() && !coeffsForDims.empty())
{
auto var = index_vars.back();
int currentVarPos = refPos.back();
pair<int, int> currentCoefs = coefsForDims.back();
ArrayDimension current_dim;
if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST)
current_dim = { stoul(var->getValue()), 1, 1 };
current_dim = { stoul(var->getValue()), 1, 1, ref };
else
{
string name, full_name = var->getValue();
int pos = full_name.find('%');
LoopGraph* currentLoop;
if (pos != -1)
if (pos != -1)
{
name = full_name.substr(pos + 1);
if (loopForIndex.find(name) != loopForIndex.end())
currentLoop = loopForIndex[name];
currentLoop = loopForIndex[name];
else
return -1;
}
else
else
{
name = FindIndexName(currentVarPos, block, loopForIndex);
if (name == "")
return -1;
if (loopForIndex.find(name) != loopForIndex.end())
currentLoop = loopForIndex[name];
currentLoop = loopForIndex[name];
else
return -1;
}
uint64_t start = currentLoop->startVal * currentCoefs.first + currentCoefs.second;
uint64_t step = currentCoefs.first;
current_dim = { start, step, (uint64_t)currentLoop->calculatedCountOfIters };
uint64_t start = coeffsForDims.back().second * currentLoop->startVal + coeffsForDims.back().first;
uint64_t step = currentLoop->stepVal;
uint64_t iters = currentLoop->calculatedCountOfIters;
current_dim = { start, step, iters, ref };
}
accessPoint[n - index_vars.size()] = current_dim;
if (current_dim.start != 0 && current_dim.step != 0 && current_dim.tripCount != 0)
{
accessPoint[n - index_vars.size()] = current_dim;
fillCount++;
}
index_vars.pop_back();
refPos.pop_back();
coefsForDims.pop_back();
coeffsForDims.pop_back();
}
if (operation == SAPFOR::CFG_OP::STORE)
def[array_name].Insert(accessPoint);
else
use[array_name].Insert(accessPoint);
if (fillCount == accessPoint.size())
{
RegionInstruction instruction;
if (operation == SAPFOR::CFG_OP::STORE)
{
def[array_name].Insert(accessPoint);
instruction.def[array_name] = { { accessPoint } };
}
else
{
instruction.use[array_name] = { { accessPoint } };
if (def.find(array_name) == def.end())
use[array_name].Insert(accessPoint);
else
{
AccessingSet element({ accessPoint });
use[array_name] = use[array_name].Union(element.Diff(def[array_name]));
}
}
region->instructions.push_back(instruction);
}
}
}
return 0;
}
static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const unordered_set<SAPFOR::BasicBlock*>& blockSet, unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
{
for (SAPFOR::BasicBlock* block : blockSet)
{
bool isCycleBlock = false;
for (SAPFOR::BasicBlock* prevBlock : block->getPrev())
isCycleBlock = isCycleBlock || (blockSet.find(prevBlock) != blockSet.end());
if (isCycleBlock)
{
bbToRegion[block]->removeNextRegion(bbToRegion[header]);
bbToRegion[header]->removePrevRegion(bbToRegion[block]);
}
}
}
static void DFS(Region* block, vector<Region*>& result, unordered_set<Region*> cycleBlocks)
{
for (Region* nextBlock : block->getNextRegions())
{
if (cycleBlocks.find(nextBlock) != cycleBlocks.end())
DFS(nextBlock, result, cycleBlocks);
}
result.push_back(block);
}
void TopologySort(std::vector<Region*>& basikBlocks, Region* header)
{
vector<Region*> result;
unordered_set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end());
DFS(header, result, cycleBlocks);
reverse(result.begin(), result.end());
basikBlocks = result;
}
static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet)
{
for (SAPFOR::BasicBlock* block : blockSet)
@@ -203,32 +285,37 @@ static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegi
for (SAPFOR::BasicBlock* nextBlock : block->getNext())
if (bbToRegion.find(nextBlock) != bbToRegion.end())
bbToRegion[block]->addNextRegion(bbToRegion[nextBlock]);
for (SAPFOR::BasicBlock* prevBlock : block->getPrev())
if (bbToRegion.find(prevBlock) != bbToRegion.end())
bbToRegion[block]->addPrevRegion(bbToRegion[prevBlock]);
}
}
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, const unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
{
Region* region = new Region;
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks);
RemoveHeaderConnection(header, blockSet, bbToRegion);
if (bbToRegion.find(header) != bbToRegion.end())
region->setHeader(bbToRegion.at(header));
region->setHeader(bbToRegion.at(header));
else
{
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return NULL;
}
for (SAPFOR::BasicBlock* block : blockSet)
if (bbToRegion.find(block) != bbToRegion.end())
region->addBasickBlocks(bbToRegion.at(block));
for (LoopGraph* childLoop : loop->children)
{
if (!childLoop->isFor())
continue;
region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion));
}
TopologySort(region->getBasickBlocks(), region->getHeader());
return region;
}
@@ -239,13 +326,19 @@ Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks)
for (auto poiner : blockSet)
{
bbToRegion[poiner] = new Region(*poiner);
this->basickBlocks.insert(bbToRegion[poiner]);
GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use);
this->basickBlocks.push_back(bbToRegion[poiner]);
GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use, bbToRegion[poiner]);
}
this->header = bbToRegion[header];
SetConnections(bbToRegion, blockSet);
RemoveHeaderConnection(header, blockSet, bbToRegion);
//create subRegions
for (LoopGraph* childLoop : loop->children)
{
if (!childLoop->isFor())
continue;
subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion));
}
}
TopologySort(basickBlocks, this->header);
}

View File

@@ -6,7 +6,12 @@
#include <string>
#include "graph_loops.h"
#include "../CFGraph/CFGraph.h"
#include "CFGraph/CFGraph.h"
struct RegionInstruction
{
ArrayAccessingIndexes def, use, in, out;
};
class Region : public SAPFOR::BasicBlock {
public:
@@ -20,13 +25,25 @@ public:
void setHeader(Region* region) { header = region; }
std::unordered_set<Region*>& getBasickBlocks() { return basickBlocks; }
std::vector<Region*>& getBasickBlocks() { return basickBlocks; }
void addBasickBlocks(Region* region) { basickBlocks.insert(region); }
void addBasickBlocks(Region* region) { basickBlocks.push_back(region); }
const std::unordered_set<Region*>& getPrevRegions() { return prevRegions; }
std::unordered_set<Region*> getNextRegions() { return nextRegions; }
std::unordered_set<Region*>& getNextRegions() { return nextRegions; }
void removeNextRegion(Region* region)
{
if (nextRegions.find(region) != nextRegions.end())
nextRegions.erase(region);
}
void removePrevRegion(Region* region)
{
if (prevRegions.find(region) != prevRegions.end())
prevRegions.erase(region);
}
void addPrevRegion(Region* region) { prevRegions.insert(region); }
@@ -48,13 +65,18 @@ public:
void addSubRegions(Region* region) { subRegions.insert(region); }
std::vector<RegionInstruction> instructions;
ArrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv;
private:
std::unordered_set<Region*> subRegions, basickBlocks;
std::vector<Region*> basickBlocks;
std::unordered_set<Region*> subRegions;
/*next Region which is BB for current BB Region*/
std::unordered_set<Region*> nextRegions;
/*prev Regions which is BBs for current BB Region*/
std::unordered_set<Region*> prevRegions;
Region* header;
};
void TopologySort(std::vector<Region*>& basikBlocks, Region* header);

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);
if (mod_gpu) /*ACC*/
UnparseTo_CufAndCu_Files(file, fout_cuf, fout_C_cu, fout_info);
UnparseTo_CufAndCu_Files(file, fout_cuf, fout_C_cu, fout_info, fout_name);
const string fileN = file->filename();
set<SgStatement*> toRemove;

View File

@@ -40,13 +40,13 @@
#include "ProjectManipulation/ConvertFiles.h"
#include "LoopAnalyzer/loop_analyzer.h"
#include "LoopAnalyzer/implicit_loops_analyzer.h"
#include "GraphCall/graph_calls_func.h"
#include "GraphLoop/graph_loops_func.h"
#include "DynamicAnalysis/gCov_parser_func.h"
#include "DynamicAnalysis/createParallelRegions.h"
#include "ArrayConstantPropagation/propagation.h"
#include "DirectiveProcessing/directive_analyzer.h"
#include "DirectiveProcessing/directive_creator.h"
#include "DirectiveProcessing/insert_directive.h"
@@ -90,13 +90,13 @@
#include "Transformations/DeadCodeRemoving/dead_code.h"
#include "Transformations/RenameSymbols/rename_symbols.h"
#include "Transformations/FunctionInlining/inliner.h"
#include "Transformations/MoveOperators/move_operators.h"
#include "ProjectParameters/projectParameters.h"
#include "CFGraph/IR.h"
#include "CFGraph/RD_subst.h"
#include "CFGraph/CFGraph.h"
#include "CFGraph/IR_SSAForm.h"
#include "CFGraph/live_variable_analysis.h"
#include "CFGraph/private_variables_analysis.h"
@@ -281,7 +281,8 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
if (isSPF_stat(st)) // except sapfor parallel regions and if attributes dont move
if (st->variant() != SPF_PARALLEL_REG_DIR && st->variant() != SPF_END_PARALLEL_REG_DIR)
toDel.push_back(st);
if (insertedPrivates.find(st) == insertedPrivates.end())
toDel.push_back(st);
for (auto& elem : toDel)
elem->deleteStmt();
@@ -941,6 +942,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
internalExit = err;
}
}
else if (curr_regime == MOVE_OPERATORS)
moveOperators(file, loopGraph, fullIR, countOfTransform);
else if (curr_regime == PRIVATE_REMOVING_ANALYSIS)
{
auto itFound = loopGraph.find(file->filename());
@@ -1021,19 +1024,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
if(func->funcPointer->variant() != ENTRY_STAT)
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)
findPrivateArrays(loopGraph, fullIR);
else if (curr_regime == TEST_PASS)
{
//test pass
@@ -1050,7 +1040,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
PRIVATE_REMOVING,
PRIVATE_ARRAYS_EXPANSION,
PRIVATE_ARRAYS_SHRINKING,
REMOVE_DEAD_CODE };
REMOVE_DEAD_CODE,
MOVE_OPERATORS };
if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end())
{
@@ -1294,7 +1285,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
detectCopies(allFuncInfo);
fillInterfaceBlock(allFuncInfo);
intentInsertToInterfaces(allFuncInfo);
createInterfacesForAssumedSize(allFuncInfo);
//this call is only for testing
//setPureStatus(allFuncInfo);
@@ -1903,7 +1893,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
findParameters(parametersOfProject, fullIR, declaredArrays);
else if (curr_regime == BUILD_IR)
{
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings());
for (auto& byFunc : CFG_forFile)
fullIR[byFunc.first].insert(fullIR[byFunc.first].end(), byFunc.second.begin(), byFunc.second.end());
@@ -1928,6 +1918,13 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
calculateStatsForPredictor(allFuncInfo, gCovInfo);
parseDvmDirForPredictor(declaredArrays, commonBlocks, allFuncInfo, gCovInfo);
}
else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS)
transformAssumedSizeParameters(allFuncInfo);
else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS)
FindPrivateArrays(loopGraph, fullIR, insertedPrivates);
else if (curr_regime == ARRAY_PROPAGATION)
ArrayConstantPropagation(project);
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.;
@@ -2163,6 +2160,8 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
runAnalysis(*project, REMOVE_COPIES, false);
runAnalysis(*project, SWAP_LOOPS, false);
runPass(TRANSFORM_ASSUMED_SIZE_PARAMETERS, proj_name, folderName);
if (folderName || consoleMode)
runAnalysis(*project, UNPARSE_FILE, true, additionalName.c_str(), folderName);
}
@@ -2344,6 +2343,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case INSERT_NO_DISTR_FLAGS_FROM_GUI:
case PRIVATE_REMOVING:
case RENAME_INLCUDES:
case MOVE_OPERATORS:
runAnalysis(*project, curr_regime, true, "", folderName);
break;
case INLINE_PROCEDURES:
@@ -2383,6 +2383,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case SUBST_EXPR_RD_AND_UNPARSE:
case SUBST_EXPR_AND_UNPARSE:
case REMOVE_DEAD_CODE_AND_UNPARSE:
case FIND_PRIVATE_ARRAYS:
if (folderName)
runAnalysis(*project, UNPARSE_FILE, true, "", folderName);
else
@@ -2523,8 +2524,8 @@ int main(int argc, char **argv)
out_free_form = 1;
out_line_unlimit = 1;
}
else if (string(curr_arg) == "-sh")
staticShadowAnalysis = 1;
/*else if (string(curr_arg) == "-sh")
staticShadowAnalysis = 1;*/
else if (string(curr_arg) == "-shWidth")
{
i++;
@@ -2644,8 +2645,11 @@ int main(int argc, char **argv)
}
}
if (curr_regime == INSERT_PARALLEL_DIRS_NODIST)
if (curr_regime == INSERT_PARALLEL_DIRS_NODIST || curr_regime == FIND_PRIVATE_ARRAYS)
{
ignoreArrayDistributeState = true;
sharedMemoryParallelization = 1;
}
if (runAsClient)
{

View File

@@ -122,6 +122,8 @@ enum passes {
CREATE_INTER_TREE,
INSERT_INTER_TREE,
MOVE_OPERATORS,
SHADOW_GROUPING,
INLINE_PROCEDURES,
FILL_PARALLEL_REG_IR,
@@ -182,11 +184,13 @@ enum passes {
SET_IMPLICIT_NONE,
RENAME_INLCUDES,
FIND_IMPLICIT_LOOPS,
BUILD_IR_SSA_FORM,
FIND_PRIVATE_ARRAYS_ANALYSIS,
FIND_PRIVATE_ARRAYS,
TRANSFORM_ASSUMED_SIZE_PARAMETERS,
ARRAY_PROPAGATION,
TEST_PASS,
EMPTY_PASS
};
@@ -319,6 +323,7 @@ static void setPassValues()
passNames[CHECK_PAR_REG_DIR] = "CHECK_PAR_REG_DIR";
passNames[CREATE_INTER_TREE] = "CREATE_INTER_TREE";
passNames[INSERT_INTER_TREE] = "INSERT_INTER_TREE";
passNames[MOVE_OPERATORS] = "MOVE_OPERATORS";
passNames[CREATE_PARALLEL_REGIONS] = "CREATE_PARALLEL_REGIONS";
passNames[PRIVATE_REMOVING_ANALYSIS] = "PRIVATE_REMOVING_ANALYSIS";
passNames[PRIVATE_REMOVING] = "PRIVATE_REMOVING";
@@ -371,10 +376,12 @@ static void setPassValues()
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
passNames[RENAME_INLCUDES] = "RENAME_INLCUDES";
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_ANALYSIS] = "FIND_PRIVATE_ARRAYS_ANALYSIS";
passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS";
passNames[TRANSFORM_ASSUMED_SIZE_PARAMETERS] = "TRANSFORM_ASSUMED_SIZE_PARAMETERS";
passNames[ARRAY_PROPAGATION] = "ARRAY_PROPAGATION";
passNames[TEST_PASS] = "TEST_PASS";
}

View File

@@ -19,7 +19,7 @@
extern std::map<std::string, std::string> shortFileNames;
static int activeState = 0;
int staticShadowAnalysis = 0;
int staticShadowAnalysis = 1;
int staticPrivateAnalysis = 0;
int keepDvmDirectives = 0;
int keepFiles = 0;
@@ -175,13 +175,14 @@ std::set<std::tuple<std::string, int, std::string>> parametersOfProject; // [fil
//for GET_MIN_MAX_BLOCK_DIST
std::pair<int, int> min_max_block = std::make_pair(-1, -1);
//
//for FIND_PRIVATE_ARRAYS
std::set<SgStatement*> insertedPrivates;
//
const char* passNames[EMPTY_PASS + 1];
const char* optionNames[EMPTY_OPTION + 1];
bool passNamesWasInit = false;
std::map<PTR_BFND, std::pair<std::string, int>> sgStats;
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,12 +6,13 @@
#include <set>
#include <algorithm>
#include "../../CFGraph/CFGraph.h"
#include "../CFGraph/CFGraph.h"
using std::map;
using std::string;
using std::vector;
using std::set;
using SAPFOR::CFG_Settings;
using std::remove_if;
@@ -424,7 +425,8 @@ int removeDeadCode(SgStatement* func,
if (intervalDelEnd->lineNumber() < prog->lineNumber() || intervalDelEnd->lineNumber() > prog->lastNodeOfStmt()->lineNumber())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, false, false, false, false), commonBlocks, allFuncs);
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop });
auto cfg = buildCFGforCurrentFunc(func, settings, commonBlocks, allFuncs);
if(cfg.size() != 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);

View File

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

View File

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

View File

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

View File

@@ -6,11 +6,14 @@ bool checkOutCalls(const std::set<std::string>& outCalls);
std::map<SgStatement*, std::set<std::string>> fillFromIntent(SgStatement* header);
void intentInsert(const 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 setPureStatus(const std::set<FuncInfo*>& funcInfo);
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 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

@@ -18,69 +18,66 @@ using std::tuple;
/// main function:
// renew unions for all common blocks in the file
static void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBlocks,
map<string, deque<CommConstraint>>& newCommonDecls, map<string, map<string, deque<CommConstraint>>>& commDecls,
set<string>& badCommon, map<string, set<string>>& notUsedVars, vector<SgStatement*>& programUnits);
//void BuildNewCommDecls
// get names of variables and array elements, which were referenced in programm unit
static set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNames);
static void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarNames, set<string>& used);
//set<string> getUses
//void getUsesFromExpr
// splits arrays into elements and replaces not used vars with empty constraints
static bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& namesOfUsedVars);
//bool splitType
// create constraits set
static deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints, const set<string>& namesOfUsedVars, set<string>& notUsedVars);
//deque<CommConstraint> makeConstraints
// build union
static bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B, const set<string>& namesOfUsedVars, pair<CommConstraint, CommConstraint>& problemConstraints);
static bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>& B, deque<CommConstraint>& newU, pair<CommConstraint, CommConstraint>& problemConstraints);
static bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommConstraint, CommConstraint>& problemConstraints);
//bool buildConstraintsUnion
//bool docheckUnequalConstraints
//bool check
/// small help functions:
static string getParentName(const string& name);
static bool equalDims(const CommConstraint& a, const CommConstraint& b);
static bool equalConstraints(const CommConstraint& a, const CommConstraint& b);
static void addElem(deque<CommConstraint>& comm, const CommConstraint& elem);
//////
//string getParentName
//bool equalDims
//bool equalConstraints
//void addElem
// change names of variables in 'constraints'
static void fixNames(deque<CommConstraint>& constraints, const string& commName);
//void fixNames
////// step2: transformation
/// main function
// peform transformation on every program unit in the file
static void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, deque<CommConstraint>>& newCommonDecls,
map<string, map<string, deque<CommConstraint>>>& commDecls, const set<string>& badCommon, map<string, set<string>>& notUsedVars);
//void fixFunctions
// get pairs of names (namesOldToNew) for renaming
static bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDecl, map<string, string>& namesOldToNew);
//bool getNamesOldToNew
// create new symbols for new variables in new common declaration (constraints)
static void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* file, SgStatement* func, string commName,
map<string, SgSymbol*>& symbs, vector<SgSymbol*>& needNewDecl);
//void makeCommVarSymbs
// delete from program unit all references to names in commVarNames
static void deleteOldVars(SgStatement* firstSt, const set<string>& commVarNames);
//void deleteOldVars
// calls fixExpression for each statement, replaces names in data statement
static void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>& newVarSymbs, const map<string, string>& namesOldToNew);
//void renameVariables
// replacing variables or array elements in expression expr if their names are in namesOldToNew
static SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbol*>& newSymbs, const map<string, string>& namesOldToNew);
//SgExpression* fixExpression
// make new exprList exprssion for new declaration decl with symbols from newSymbs
static SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, const map<string, SgSymbol*>& newSymbs,
SgFile* file, SgStatement* firstSt);
//SgExpression* makeExprListForCommon
// replace old common declarations with new ones
static void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& commListExprs);
//void rewriteCommon
/// help functions:
static SgExpression* makeIdxFromStr(const string& str);
//SgExpression* makeIdxFromStr(const string& str);
// make new expression of array element
static SgExpression* newArrElemExpr(const string& newName, const map<string, SgSymbol*>& newSymbs);
static bool variablePositionComp(const Variable* lhs, const Variable* rhs);
//SgExpression* newArrElemExpr
//bool variablePositionComp
//////
CommConstraint::CommConstraint(const Variable* var, bool u, const string& funcName, const string& fileName)
{
used = u;
@@ -125,7 +122,6 @@ CommConstraint::CommConstraint(const Variable* var, bool u, const string& funcNa
}
}
CommConstraint::CommConstraint(const string& name, SgType* t, bool u) : used(u), type(t), identifier(name)
{
typeVariant = type->variant();
@@ -139,8 +135,7 @@ CommConstraint::CommConstraint(const string& name, SgType* t, bool u, vector<Dec
size = getSizeOfType(type);
}
string getParentName(const string& name)
static string getParentName(const string& name)
{
size_t len = name.find("%");
size_t posB = name.find("(");
@@ -154,8 +149,7 @@ string getParentName(const string& name)
return name.substr(0, len);
}
void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarNames, set<string>& used)
static void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarNames, set<string>& used)
{
if (expr == NULL)
return;
@@ -194,8 +188,7 @@ void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarNames, set<
getUsesFromExpr(expr->rhs(), commonVarNames, used);
}
set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNames)
static set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNames)
{
set<string> used;
SgStatement* lastSt = firstSt->lastNodeOfStmt();
@@ -212,8 +205,7 @@ set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNames)
return used;
}
bool equalDims(const CommConstraint& a, const CommConstraint& b)
static bool equalDims(const CommConstraint& a, const CommConstraint& b)
{
const vector<pair<int, int>>& adim = a.arrayInfo->GetSizes();
const vector<pair<int, int>>& bdim = b.arrayInfo->GetSizes();
@@ -224,11 +216,12 @@ bool equalDims(const CommConstraint& a, const CommConstraint& b)
if (adim[i].second - adim[i].first != bdim[i].second - bdim[i].first)
return false;
}
return true;
}
// TODO: add attributes to CommConstraints, check if a and b have equal attributes
bool equalConstraints(const CommConstraint& a, const CommConstraint& b)
static bool equalConstraints(const CommConstraint& a, const CommConstraint& b)
{
if ((a.arrayInfo != NULL && b.arrayInfo == NULL) || ((a.arrayInfo == NULL && b.arrayInfo != NULL)))
return false;
@@ -239,8 +232,7 @@ bool equalConstraints(const CommConstraint& a, const CommConstraint& b)
return true;
}
void addElem(deque<CommConstraint>& comm, const CommConstraint& elem)
static void addElem(deque<CommConstraint>& comm, const CommConstraint& elem)
{
if (elem.typeVariant == 0 && !comm.empty() && comm.back().typeVariant == 0)
comm.back().size += elem.size;
@@ -248,9 +240,8 @@ void addElem(deque<CommConstraint>& comm, const CommConstraint& elem)
comm.push_back(elem);
}
// TODO: check attributes: do not split arrays with pointer or target attributes if check_use == true
bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& namesOfUsedVars = {})
static bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& namesOfUsedVars = {})
{
CommConstraint var = d.front();
string name = var.identifier;
@@ -298,8 +289,7 @@ bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& name
}
}
deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints, const set<string>& namesOfUsedVars, set<string>& notUsedVars)
static deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints, const set<string>& namesOfUsedVars, set<string>& notUsedVars)
{
deque<CommConstraint> res;
while (!constraints.empty())
@@ -316,8 +306,7 @@ deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints, const
return res;
}
bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommConstraint, CommConstraint>& problemConstraints)
static bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommConstraint, CommConstraint>& problemConstraints)
{
while (!A.empty() && !B.empty())
{
@@ -356,8 +345,8 @@ bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommConstrai
return true;
}
bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>& B, deque<CommConstraint>& newU, pair<CommConstraint, CommConstraint>& problemConstraints)
static bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>& B, deque<CommConstraint>& newU,
pair<CommConstraint, CommConstraint>& problemConstraints)
{
if (U.front().typeVariant == 0)
{
@@ -380,8 +369,8 @@ bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>&
return true;
}
bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B, const set<string>& namesOfUsedVars, pair<CommConstraint, CommConstraint>& problemConstraints)
static bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B,
const set<string>& namesOfUsedVars, pair<CommConstraint, CommConstraint>& problemConstraints)
{
deque<CommConstraint> newU;
while (!U.empty() && !B.empty())
@@ -436,8 +425,8 @@ bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B, co
return true;
}
bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDecl, map<string, string>& namesOldToNew)
//TODO: check this: newDecl and oldDecl => do these variables need references?
static bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDecl, map<string, string>& namesOldToNew)
{
bool needChange = false;
map<string, string> rename;
@@ -502,16 +491,18 @@ bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDe
newDecl.pop_front();
}
}
if (!oldDecl.empty() || !newDecl.empty())
needChange = true;
if (needChange)
namesOldToNew.insert(rename.begin(), rename.end());
return needChange;
}
void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* file, SgStatement* func, string commName,
map<string, SgSymbol*>& symbs, vector<SgSymbol*>& needNewDecl)
static void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* file, SgStatement* func, const string& commName,
map<string, SgSymbol*>& symbs, vector<SgSymbol*>& needNewDecl)
{
for (const CommConstraint& var : constraints)
{
@@ -524,8 +515,7 @@ void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* file, Sg
}
}
void deleteOldVars(SgStatement* firstSt, const set<string>& commVarNames)
static void deleteOldVars(SgStatement* firstSt, const set<string>& commVarNames)
{
SgStatement* lastSt = firstSt->lastNodeOfStmt();
vector<SgStatement*> stmtsToDelete;
@@ -571,12 +561,12 @@ void deleteOldVars(SgStatement* firstSt, const set<string>& commVarNames)
}
// TODO: delete common variables form attributes statements (like DIM_STAT)
}
for (SgStatement* st : stmtsToDelete)
st->deleteStmt();
}
SgExpression* makeIdxFromStr(const string& str)
static SgExpression* makeIdxFromStr(const string& str)
{
vector<SgExpression*> items;
int num = 0;
@@ -591,13 +581,13 @@ SgExpression* makeIdxFromStr(const string& str)
num = 0;
}
}
reverse(items.begin(), items.end());
SgExpression* exprList = makeExprList(items, false);
return exprList;
}
SgExpression* newArrElemExpr(const string& newName, const map<string, SgSymbol*>& newSymbs)
static SgExpression* newArrElemExpr(const string& newName, const map<string, SgSymbol*>& newSymbs)
{
size_t pos = newName.find('(');
SgExpression* newExpr = new SgArrayRefExp(*newSymbs.at(newName.substr(0, pos)));
@@ -605,11 +595,11 @@ SgExpression* newArrElemExpr(const string& newName, const map<string, SgSymbol*>
return newExpr;
}
SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbol*>& newSymbs, const map<string, string>& namesOldToNew)
static SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbol*>& newSymbs, const map<string, string>& namesOldToNew)
{
if (expr == NULL)
return NULL;
if (expr->variant() == VAR_REF || expr->variant() == ARRAY_REF)
{
string name = expr->symbol()->identifier();
@@ -645,17 +635,18 @@ SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbol*>& ne
}
}
}
SgExpression* lhs = fixExpression(expr->lhs(), newSymbs, namesOldToNew);
if (lhs != NULL)
expr->setLhs(lhs);
SgExpression* rhs = fixExpression(expr->rhs(), newSymbs, namesOldToNew);
if (rhs != NULL)
expr->setRhs(rhs);
return NULL;
}
void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>& newVarSymbs, const map<string, string>& namesOldToNew)
static void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>& newVarSymbs, const map<string, string>& namesOldToNew)
{
SgStatement* lastSt = firstSt->lastNodeOfStmt();
for (SgStatement* curSt = firstSt; curSt != NULL && curSt != lastSt; curSt = curSt->lexNext())
@@ -703,8 +694,7 @@ void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>& newVarS
}
}
SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, const map<string, SgSymbol*>& newSymbs,
static SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, const map<string, SgSymbol*>& newSymbs,
SgFile* file, SgStatement* firstSt)
{
vector<SgExpression*> items;
@@ -738,8 +728,7 @@ SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, const map
return exprList;
}
void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& commListExprs)
static void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& commListExprs)
{
vector<SgStatement*> commonStmtsToDelete;
for (SgStatement* st = firstSt; st != firstSt->lastDeclaration()->lexNext(); st = st->lexNext())
@@ -790,12 +779,12 @@ void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& commListExp
commonStmtsToDelete.push_back(st);
}
}
for (SgStatement* st : commonStmtsToDelete)
st->deleteStmt();
}
void fixNames(deque<CommConstraint>& constraints, const string& commName)
static void fixNames(deque<CommConstraint>& constraints, const string& commName)
{
for (auto& var : constraints)
{
@@ -810,26 +799,26 @@ void fixNames(deque<CommConstraint>& constraints, const string& commName)
}
}
bool variablePositionComp(const Variable* lhs, const Variable* rhs)
static bool variablePositionComp(const Variable* lhs, const Variable* rhs)
{
return lhs->getPosition() < rhs->getPosition();
}
void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, deque<CommConstraint>>& newCommonDecls,
map<string, map<string, deque<CommConstraint>>>& commDecls, const set<string>& badCommon, map<string, set<string>>& notUsedVars)
static void fixFunctions(SgFile* file, const vector<SgStatement*>& programUnits, map<string, deque<CommConstraint>>& newCommonDecls,
map<string, map<string, deque<CommConstraint>>>& commDecls, const set<string>& badCommon, map<string, set<string>>& notUsedVars)
{
for (SgStatement* unitSt : programUnits)
{
string funcName = unitSt->symbol()->identifier();
if (commDecls.find(funcName) == commDecls.end())
continue;
SgStatement* firstSt = unitSt;
map<string, SgExpression*> commListExprs;
map<string, SgSymbol*> newVarSymbs; // new symbols for new variables
map<string, string> namesOldToNew; // for ranaming: old name -> new name
vector<SgSymbol*> needNewDecl;
for (auto& common : commDecls[funcName])
{
string commName = common.first;
@@ -840,9 +829,11 @@ void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, d
bool needChange = getNamesOldToNew(newDecl, common.second, namesOldToNew);
if (!needChange)
continue;
makeCommVarSymbs(newDecl, file, firstSt, commName, newVarSymbs, needNewDecl);
commListExprs[commName] = makeExprListForCommon(newDecl, newVarSymbs, file, firstSt);
}
if (!commListExprs.empty())
{
for (const auto& item : commListExprs)
@@ -856,10 +847,9 @@ void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, d
}
}
void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBlocks,
map<string, deque<CommConstraint>>& newCommonDecls, map<string, map<string, deque<CommConstraint>>>& commDecls,
set<string>& badCommon, map<string, set<string>>& notUsedVars, vector<SgStatement*>& programUnits)
static void buildNewCommDecls(SgFile* file, const map<string, CommonBlock*>& allCommonBlocks,
map<string, deque<CommConstraint>>& newCommonDecls, map<string, map<string, deque<CommConstraint>>>& commDecls,
set<string>& badCommon, map<string, set<string>>& notUsedVars, vector<SgStatement*>& programUnits)
{
string fileName = file->filename();
SgStatement* curSt = file->firstStatement();
@@ -898,7 +888,8 @@ void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBl
constraints.push_back(newConstr);
}
if (hasChar && hasNotChar) // TDOO: make proper warning message or separate such common blocks
__spf_print(1, "common block '%s' ('%s':%d) contains variables of symbolic and numeric types. It is required to divide\n", commName.c_str(), fileName.c_str(), constraints.back().uses.back().lineNum);
__spf_print(1, "common block '%s' ('%s':%d) contains variables of symbolic and numeric types. It is required to divide\n",
commName.c_str(), fileName.c_str(), constraints.back().uses.back().getLineNum());
if (hasChar)
{
badCommon.insert(commName);
@@ -915,7 +906,7 @@ void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBl
for (auto x : problemConstraints.first.uses) // TODO: make proper warning message
for (auto y : problemConstraints.second.uses)
__spf_print(1, "variables '%s' and '%s' in one storage association (common block '%s') have different types (files - %s:%d and %s:%d)\n",
x.varName.c_str(), y.varName.c_str(), commName.c_str(), x.fileName.c_str(), x.lineNum, y.fileName.c_str(), y.lineNum);
x.getVarName(), y.getVarName(), commName.c_str(), x.getFileName(), x.getLineNum(), y.getFileName(), y.getLineNum());
}
}
curSt = curSt->lastNodeOfStmt();
@@ -927,7 +918,7 @@ void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBl
// main function
void fixCommonBlocks(const map<string, vector<FuncInfo*>> allFuncInfo, const map<string, CommonBlock*> allCommonBlocks, SgProject* project) // TODO: separate into 2 steps?
void fixCommonBlocks(const map<string, vector<FuncInfo*>>& allFuncInfo, const map<string, CommonBlock*>& allCommonBlocks, SgProject* project) // TODO: separate into 2 steps?
{
int filesNum = project->numberOfFiles();
map<string, map<string, map<string, deque<CommConstraint>>>> commDecls; // file_name -> function_name -> common block name -> old declaration of common block
@@ -941,10 +932,12 @@ void fixCommonBlocks(const map<string, vector<FuncInfo*>> allFuncInfo, const map
SgFile* file = &project->file(i);
string fileName = file->filename();
file->switchToFile(fileName);
BuildNewCommDecls(file, allCommonBlocks, newCommonDecls, commDecls[fileName], badCommon, notUsedVars, programUnitsInFile[fileName]);
buildNewCommDecls(file, allCommonBlocks, newCommonDecls, commDecls[fileName], badCommon, notUsedVars, programUnitsInFile[fileName]);
}
for (auto& elem : newCommonDecls)
fixNames(elem.second, elem.first);
for (int i = 0; i < filesNum; i++) // second step
{
SgFile* file = &project->file(i);

View File

@@ -16,12 +16,18 @@
struct DeclInfo // for error messages
{
private:
std::string varName;
std::string fileName;
int lineNum;
public:
DeclInfo() : varName(""), fileName(""), lineNum(0) {};
DeclInfo(const std::string& vn, const std::string& fn, int ln) : varName(vn), fileName(fn), lineNum(ln) {};
const char* getVarName() const { return varName.c_str(); }
const char* getFileName() const { return fileName.c_str(); }
int getLineNum() const { return lineNum; }
};
struct CommConstraint // TODO: add variable attributes
@@ -42,4 +48,4 @@ struct CommConstraint // TODO: add variable attributes
};
void fixCommonBlocks(const std::map<std::string, std::vector<FuncInfo*>> allFuncInfo, const std::map<std::string, CommonBlock*> allCommonBlocks, SgProject* project);
void fixCommonBlocks(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, const std::map<std::string, CommonBlock*>& allCommonBlocks, SgProject* project);

View File

@@ -1123,7 +1123,7 @@ static bool hasDependenciesBetweenArrays(LoopGraph* firstLoop, LoopGraph* loop,
for (int d = 0; d < dimensions; ++d)
{
//по измерениям массива отображение на цикл вложенности d
vector<set<pair<int, int>>> coefsRead[2], coefsWrite[2];
vector<set<pair<int, int>>> coeffsRead[2], coeffsWrite[2];
checkNull(currLoop[0], convertFileName(__FILE__).c_str(), __LINE__);
checkNull(currLoop[1], convertFileName(__FILE__).c_str(), __LINE__);
@@ -1133,31 +1133,31 @@ static bool hasDependenciesBetweenArrays(LoopGraph* firstLoop, LoopGraph* loop,
auto it = currLoop[k]->readOpsForLoop.find(array);
if (it != currLoop[k]->readOpsForLoop.end())
{
if (coefsRead[k].size() == 0)
coefsRead[k].resize(it->second.size());
if (coeffsRead[k].size() == 0)
coeffsRead[k].resize(it->second.size());
for (int z = 0; z < it->second.size(); ++z)
if (it->second[z].coefficients.size())
for (auto& coef : it->second[z].coefficients)
coefsRead[k][z].insert(coef.first);
coeffsRead[k][z].insert(coef.first);
}
auto itW = currLoop[k]->writeOpsForLoop.find(array);
if (itW != currLoop[k]->writeOpsForLoop.end())
{
if (coefsWrite[k].size() == 0)
coefsWrite[k].resize(itW->second.size());
if (coeffsWrite[k].size() == 0)
coeffsWrite[k].resize(itW->second.size());
for (int z = 0; z < itW->second.size(); ++z)
if (itW->second[z].coefficients.size())
for (auto& coef : itW->second[z].coefficients)
coefsWrite[k][z].insert(coef.first);
coeffsWrite[k][z].insert(coef.first);
}
}
//нет записей, значит нет зависимости
bool nulWrite = true;
for (auto& wr : coefsWrite)
for (auto& wr : coeffsWrite)
for (auto& elem : wr)
if (elem.size() != 0)
nulWrite = false;
@@ -1168,62 +1168,62 @@ static bool hasDependenciesBetweenArrays(LoopGraph* firstLoop, LoopGraph* loop,
// если чтение в одном цикле и запись (и наоборот) в другом идут по разным правилам, то пока что это зависимость.
// здесь можно уточнить.
const int len = std::max(coefsWrite[0].size(), coefsRead[0].size());
const int len = std::max(coeffsWrite[0].size(), coeffsRead[0].size());
int countW[2] = { 0, 0 };
int countR[2] = { 0, 0 };
for (int L = 0; L < 2; ++L)
for (int z = 0; z < coefsWrite[L].size(); ++z)
countW[L] += (coefsWrite[L][z].size() ? 1 : 0);
for (int z = 0; z < coeffsWrite[L].size(); ++z)
countW[L] += (coeffsWrite[L][z].size() ? 1 : 0);
for (int L = 0; L < 2; ++L)
for (int z = 0; z < coefsRead[L].size(); ++z)
countR[L] += (coefsRead[L][z].size() ? 1 : 0);
for (int z = 0; z < coeffsRead[L].size(); ++z)
countR[L] += (coeffsRead[L][z].size() ? 1 : 0);
for (int p = 0; p < len; ++p)
{
if (coefsWrite[1].size() && coefsWrite[0].size())
if (coefsWrite[0][p].size() != 0 && coefsWrite[1][p].size() != 0)
if (coefsWrite[0][p] != coefsWrite[1][p])
if (coeffsWrite[1].size() && coeffsWrite[0].size())
if (coeffsWrite[0][p].size() != 0 && coeffsWrite[1][p].size() != 0)
if (coeffsWrite[0][p] != coeffsWrite[1][p])
return true;
if (coefsRead[1].size() && coefsWrite[0].size())
if (coefsWrite[0][p].size() != 0 && coefsRead[1][p].size() != 0)
if (coefsWrite[0][p] != coefsRead[1][p])
if (coeffsRead[1].size() && coeffsWrite[0].size())
if (coeffsWrite[0][p].size() != 0 && coeffsRead[1][p].size() != 0)
if (coeffsWrite[0][p] != coeffsRead[1][p])
return true;
if (coefsWrite[1].size() && coefsRead[0].size())
if (coefsWrite[1][p].size() != 0 && coefsRead[0][p].size() != 0)
if (coefsWrite[1][p] != coefsRead[0][p])
if (coeffsWrite[1].size() && coeffsRead[0].size())
if (coeffsWrite[1][p].size() != 0 && coeffsRead[0][p].size() != 0)
if (coeffsWrite[1][p] != coeffsRead[0][p])
return true;
//отображение на разные измерения
if (coefsWrite[1].size() && coefsWrite[0].size())
if (coeffsWrite[1].size() && coeffsWrite[0].size())
{
if (coefsWrite[0][p].size() != 0 && coefsWrite[1][p].size() == 0 && countW[1] ||
coefsWrite[0][p].size() == 0 && coefsWrite[1][p].size() != 0 && countW[0])
if (coeffsWrite[0][p].size() != 0 && coeffsWrite[1][p].size() == 0 && countW[1] ||
coeffsWrite[0][p].size() == 0 && coeffsWrite[1][p].size() != 0 && countW[0])
return true;
}
if (coefsRead[1].size() && coefsWrite[0].size())
if (coeffsRead[1].size() && coeffsWrite[0].size())
{
if (coefsWrite[0][p].size() != 0 && coefsRead[1][p].size() == 0 && countR[1] ||
coefsWrite[0][p].size() == 0 && coefsRead[1][p].size() != 0 && countW[0])
if (coeffsWrite[0][p].size() != 0 && coeffsRead[1][p].size() == 0 && countR[1] ||
coeffsWrite[0][p].size() == 0 && coeffsRead[1][p].size() != 0 && countW[0])
return true;
}
if (coefsWrite[1].size() && coefsRead[1].size())
if (coeffsWrite[1].size() && coeffsRead[1].size())
{
if (coefsWrite[1][p].size() != 0 && coefsRead[0][p].size() == 0 && countR[0] ||
coefsWrite[1][p].size() == 0 && coefsRead[0][p].size() != 0 && countW[1])
if (coeffsWrite[1][p].size() != 0 && coeffsRead[0][p].size() == 0 && countR[0] ||
coeffsWrite[1][p].size() == 0 && coeffsRead[0][p].size() != 0 && countW[1])
return true;
}
//где то нет правил отображения вообще, но есть факт его наличия.
if ( ((coefsWrite[0].size() == 0 && coefsRead[0].size() == 0) && (countW[0] == 0 && countR[0] == 0))
if ( ((coeffsWrite[0].size() == 0 && coeffsRead[0].size() == 0) && (countW[0] == 0 && countR[0] == 0))
||
((coefsWrite[1].size() == 0 && coefsRead[1].size() == 0) && (countW[1] == 0 && countR[1] == 0)) )
((coeffsWrite[1].size() == 0 && coeffsRead[1].size() == 0) && (countW[1] == 0 && countR[1] == 0)) )
return true;
}

View File

@@ -6,7 +6,7 @@
#include "../LoopAnalyzer/loop_analyzer.h"
#include "expr_transform.h"
#include "errors.h"
#include "../CFGraph/CFGraph.h"
#include "CFGraph/CFGraph.h"
#include "../SageAnalysisTool/OmegaForSage/include/lang-interf.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
@@ -19,6 +19,7 @@ using std::pair;
using std::make_pair;
using std::wstring;
using std::stack;
using SAPFOR::CFG_Settings;
#define PRINT_SPLITTED_FRAGMENTS 0
@@ -315,7 +316,7 @@ static map<SgStatement*, pair<set<SgStatement*>, set<SgStatement*>>>
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
map<SAPFOR::Argument*, set<int>> outForCurr;
buildGenKillForCFG(itCFG->second, funcByName, outForFunc, gen, kill, &genForIR, &killForIR, notInitedGlobals, SAPFOR::CFG_Settings(0));
buildGenKillForCFG(itCFG->second, funcByName, outForFunc, gen, kill, &genForIR, &killForIR, notInitedGlobals, SAPFOR::CFG_Settings());
if (outForFunc.count(byFunc))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1051,7 +1052,8 @@ int splitLoops(SgFile *file, vector<LoopGraph*> &loopGraphs, vector<Messages> &m
checkNull(listExp, convertFileName(__FILE__).c_str(), __LINE__);
int deep = listExp->length();
currIR = buildCFGforCurrentFunc(loop->loop, SAPFOR::CFG_Settings(true, true), commonBlocks, allFuncInfo);
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop, CFG_Settings::CFG_withRD, CFG_Settings::CFG_withCallFrom, CFG_Settings::CFG_withDominators });
currIR = buildCFGforCurrentFunc(loop->loop, settings, commonBlocks, allFuncInfo);
totalErr = splitLoop(loop, messages, deep, depInfoForLoopGraph);
if (totalErr > 0)

View File

@@ -0,0 +1,826 @@
#include <map>
#include <unordered_set>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
#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 "move_operators.h"
using namespace std;
static vector<SAPFOR::IR_Block*> findInstructionsFromOperator(SgStatement* st, const 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;
}
const unordered_set<int> loop_tags = { FOR_NODE };
const unordered_set<int> control_tags = { IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE };
const unordered_set<int> control_end_tags = { CONTROL_END };
struct OperatorInfo {
SgStatement* stmt;
set<string> usedVars;
set<string> definedVars;
int lineNumber;
bool isMovable;
OperatorInfo(SgStatement* s) : stmt(s), lineNumber(s->lineNumber()), isMovable(true) { }
};
static bool isStatementEmbedded(SgStatement* stmt, SgStatement* parent) {
if (!stmt || !parent || stmt == parent)
return false;
if (parent->variant() == LOGIF_NODE) {
if (stmt->lineNumber() == parent->lineNumber())
return true;
SgStatement* current = parent;
SgStatement* lastNode = parent->lastNodeOfStmt();
while (current && current != lastNode) {
if (current == stmt)
return true;
if (current->isIncludedInStmt(*stmt))
return true;
current = current->lexNext();
}
}
if (parent->isIncludedInStmt(*stmt))
return true;
return false;
}
static bool isLoopBoundary(SgStatement* stmt) {
if (!stmt)
return false;
if (stmt->variant() == FOR_NODE || stmt->variant() == CONTROL_END)
return true;
return false;
}
static bool isPartOfNestedLoop(SgStatement* stmt, SgForStmt* loop) {
if (!stmt || !loop)
return false;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (!loopStart || !loopEnd)
return false;
if (stmt->lineNumber() < loopStart->lineNumber() || stmt->lineNumber() > loopEnd->lineNumber())
return false;
SgStatement* current = loopStart;
while (current && current != loopEnd) {
if (current->variant() == FOR_NODE && current != loop) {
SgForStmt* nestedLoop = (SgForStmt*)current;
SgStatement* nestedStart = nestedLoop->lexNext();
SgStatement* nestedEnd = nestedLoop->lastNodeOfStmt();
if (nestedStart && nestedEnd &&
stmt->lineNumber() >= nestedStart->lineNumber() &&
stmt->lineNumber() <= nestedEnd->lineNumber()) {
return true;
}
}
current = current->lexNext();
}
return false;
}
static bool canSafelyExtract(SgStatement* stmt, SgForStmt* loop) {
if (!stmt || !loop)
return false;
if (isLoopBoundary(stmt))
return false;
if (control_tags.find(stmt->variant()) != control_tags.end())
return false;
if (isPartOfNestedLoop(stmt, loop))
return false;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (!loopStart || !loopEnd)
return false;
SgStatement* current = loopStart;
while (current && current != loopEnd) {
if (current->variant() == LOGIF_NODE && current->lineNumber() == stmt->lineNumber())
return false;
if (control_tags.find(current->variant()) != control_tags.end())
if (isStatementEmbedded(stmt, current))
return false;
if (current == stmt)
break;
current = current->lexNext();
}
return true;
}
static vector<OperatorInfo> analyzeOperatorsInLoop(SgForStmt* loop, const vector<SAPFOR::BasicBlock*>& blocks,
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) {
vector<OperatorInfo> operators;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (!loopStart || !loopEnd)
return operators;
SgStatement* current = loopStart;
unordered_set<SgStatement*> visited;
while (current && current != loopEnd) {
if (visited.find(current) != visited.end())
break;
visited.insert(current);
if (isLoopBoundary(current)) {
current = current->lexNext();
continue;
}
if (current->variant() == FOR_NODE && current != loop) {
SgStatement* nestedEnd = current->lastNodeOfStmt();
if (nestedEnd)
current = nestedEnd->lexNext();
else
current = current->lexNext();
continue;
}
if (isSgExecutableStatement(current)) {
if (control_tags.find(current->variant()) != control_tags.end()) {
current = current->lexNext();
continue;
}
if (current->variant() != ASSIGN_STAT) {
current = current->lexNext();
continue;
}
OperatorInfo opInfo(current);
vector<SAPFOR::IR_Block*> irBlocks = findInstructionsFromOperator(current, blocks);
for (auto irBlock : irBlocks) {
if (!irBlock || !irBlock->getInstruction())
continue;
const SAPFOR::Instruction* instr = irBlock->getInstruction();
if (instr->getArg1()) {
string varName = getNameByArg(instr->getArg1());
if (!varName.empty())
opInfo.usedVars.insert(varName);
}
if (instr->getArg2()) {
string varName = getNameByArg(instr->getArg2());
if (!varName.empty())
opInfo.usedVars.insert(varName);
}
if (instr->getResult()) {
string varName = getNameByArg(instr->getResult());
if (!varName.empty())
opInfo.definedVars.insert(varName);
}
}
operators.push_back(opInfo);
}
current = current->lexNext();
}
return operators;
}
static map<string, vector<SgStatement*>> findVariableDefinitions(SgForStmt* loop, vector<OperatorInfo>& operators) {
map<string, vector<SgStatement*>> varDefinitions;
for (auto& op : operators)
for (const string& var : op.definedVars)
varDefinitions[var].push_back(op.stmt);
return varDefinitions;
}
static int calculateDistance(SgStatement* from, SgStatement* to) {
if (!from || !to)
return INT_MAX;
return abs(to->lineNumber() - from->lineNumber());
}
static SgStatement* findBestPosition(SgStatement* operatorStmt, const vector<OperatorInfo>& operators,
const map<string, vector<SgStatement*>>& varDefinitions, SgForStmt* loop) {
const OperatorInfo* opInfo = nullptr;
for (auto& op : operators) {
if (op.stmt == operatorStmt) {
opInfo = &op;
break;
}
}
if (!opInfo || !opInfo->isMovable)
return nullptr;
SgStatement* bestPos = nullptr;
int bestLine = -1;
for (const string& usedVar : opInfo->usedVars) {
if (varDefinitions.find(usedVar) != varDefinitions.end()) {
for (SgStatement* defStmt : varDefinitions.at(usedVar)) {
if (defStmt->lineNumber() < operatorStmt->lineNumber()) {
if (defStmt->controlParent() == operatorStmt->controlParent()) {
if (defStmt->lineNumber() > bestLine) {
bestLine = defStmt->lineNumber();
bestPos = defStmt;
}
}
}
}
}
}
if (!bestPos) {
bool allLoopCarried = true;
bool hasAnyDefinition = false;
for (const string& usedVar : opInfo->usedVars) {
if (varDefinitions.find(usedVar) != varDefinitions.end()) {
for (SgStatement* defStmt : varDefinitions.at(usedVar)) {
if (defStmt == operatorStmt)
continue;
hasAnyDefinition = true;
if (defStmt->lineNumber() < operatorStmt->lineNumber() &&
defStmt->controlParent() == operatorStmt->controlParent()) {
allLoopCarried = false;
break;
}
}
}
if (!allLoopCarried)
break;
}
if (allLoopCarried || (!hasAnyDefinition && !opInfo->usedVars.empty())) {
SgStatement* loopStart = loop->lexNext();
return loopStart;
}
}
return bestPos;
}
static bool canMoveTo(SgStatement* from, SgStatement* to, SgForStmt* loop) {
if (!from || !to || from == to)
return false;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (!loopStart || !loopEnd)
return false;
if (to == loopStart) {
SgStatement* fromControlParent = from->controlParent();
if (!fromControlParent) fromControlParent = loop;
return fromControlParent == loop || fromControlParent == loopStart->controlParent();
}
if (from->lineNumber() < loopStart->lineNumber() || from->lineNumber() > loopEnd->lineNumber())
return false;
if (to->lineNumber() < loopStart->lineNumber() || to->lineNumber() > loopEnd->lineNumber())
return false;
if (to->lineNumber() >= from->lineNumber())
return false;
if (from->controlParent() != to->controlParent())
return false;
SgStatement* current = to->lexNext();
while (current && current != from && current != loopEnd) {
if (control_tags.find(current->variant()) != control_tags.end()) {
SgStatement* controlEnd = current->lastNodeOfStmt();
if (controlEnd && from->lineNumber() <= controlEnd->lineNumber()) {
if (from->controlParent() == current && to->controlParent() != current) {
return false;
}
}
}
current = current->lexNext();
}
return true;
}
static vector<SgStatement*> optimizeOperatorOrder(SgForStmt* loop,
const vector<OperatorInfo>& operators,
const map<string, vector<SgStatement*>>& varDefinitions) {
vector<SgStatement*> newOrder;
for (auto& op : operators)
newOrder.push_back(op.stmt);
map<SgStatement*, const OperatorInfo*> stmtToOpInfo;
for (auto& op : operators)
stmtToOpInfo[op.stmt] = &op;
bool changed = true;
while (changed) {
changed = false;
for (int i = operators.size() - 1; i >= 0; i--) {
if (!operators[i].isMovable)
continue;
SgStatement* stmt = operators[i].stmt;
const OperatorInfo* opInfo = stmtToOpInfo[stmt];
if (!opInfo)
continue;
size_t currentPos = 0;
for (size_t j = 0; j < newOrder.size(); j++) {
if (newOrder[j] == stmt) {
currentPos = j;
break;
}
}
SgStatement* bestPos = findBestPosition(stmt, operators, varDefinitions, loop);
if (!bestPos) {
bool hasDependents = false;
for (size_t j = currentPos + 1; j < newOrder.size(); j++) {
SgStatement* candidate = newOrder[j];
const OperatorInfo* candidateOpInfo = stmtToOpInfo[candidate];
if (candidateOpInfo) {
for (const string& definedVar : opInfo->definedVars) {
if (candidateOpInfo->usedVars.find(definedVar) != candidateOpInfo->usedVars.end()) {
hasDependents = true;
break;
}
}
if (hasDependents)
break;
}
}
continue;
}
size_t targetPos = 0;
bool foundTarget = false;
if (bestPos == loop->lexNext()) {
targetPos = 0;
for (size_t j = 0; j < currentPos && j < newOrder.size(); j++) {
SgStatement* candidate = newOrder[j];
const OperatorInfo* candidateOpInfo = stmtToOpInfo[candidate];
if (candidateOpInfo) {
bool usesDefinedVar = false;
for (const string& definedVar : opInfo->definedVars) {
if (candidateOpInfo->usedVars.find(definedVar) != candidateOpInfo->usedVars.end()) {
usesDefinedVar = true;
break;
}
}
if (usesDefinedVar) {
targetPos = j;
break;
}
}
}
foundTarget = true;
if (currentPos != targetPos && canMoveTo(stmt, bestPos, loop)) {
newOrder.erase(newOrder.begin() + currentPos);
newOrder.insert(newOrder.begin() + targetPos, stmt);
changed = true;
}
} else {
size_t bestPosIdx = 0;
bool foundBestPos = false;
for (size_t j = 0; j < newOrder.size(); j++) {
if (newOrder[j] == bestPos) {
bestPosIdx = j;
foundBestPos = true;
break;
}
}
if (foundBestPos) {
targetPos = bestPosIdx + 1;
for (size_t j = bestPosIdx + 1; j < currentPos && j < newOrder.size(); j++) {
SgStatement* candidate = newOrder[j];
const OperatorInfo* candidateOpInfo = stmtToOpInfo[candidate];
if (candidateOpInfo) {
bool definesUsedVar = false;
for (const string& usedVar : opInfo->usedVars) {
if (candidateOpInfo->definedVars.find(usedVar) != candidateOpInfo->definedVars.end()) {
definesUsedVar = true;
break;
}
}
if (definesUsedVar)
targetPos = j + 1;
}
}
bool wouldBreakDependency = false;
for (size_t j = targetPos; j < currentPos && j < newOrder.size(); j++) {
SgStatement* candidate = newOrder[j];
const OperatorInfo* candidateOpInfo = stmtToOpInfo[candidate];
if (candidateOpInfo) {
for (const string& definedVar : opInfo->definedVars) {
if (candidateOpInfo->usedVars.find(definedVar) != candidateOpInfo->usedVars.end()) {
wouldBreakDependency = true;
break;
}
}
if (wouldBreakDependency)
break;
}
}
if (!wouldBreakDependency && currentPos > targetPos && canMoveTo(stmt, bestPos, loop)) {
newOrder.erase(newOrder.begin() + currentPos);
newOrder.insert(newOrder.begin() + targetPos, stmt);
changed = true;
}
}
}
}
}
bool dependencyViolation = true;
set<pair<SgStatement*, SgStatement*>> triedPairs;
while (dependencyViolation) {
dependencyViolation = false;
triedPairs.clear();
for (size_t i = 0; i < newOrder.size(); i++) {
SgStatement* stmt = newOrder[i];
const OperatorInfo* opInfo = stmtToOpInfo[stmt];
if (!opInfo)
continue;
for (size_t j = 0; j < i; j++) {
SgStatement* prevStmt = newOrder[j];
const OperatorInfo* prevOpInfo = stmtToOpInfo[prevStmt];
if (!prevOpInfo)
continue;
pair<SgStatement*, SgStatement*> key = make_pair(stmt, prevStmt);
if (triedPairs.find(key) != triedPairs.end())
continue;
bool violation = false;
for (const string& definedVar : opInfo->definedVars) {
if (prevOpInfo->usedVars.find(definedVar) != prevOpInfo->usedVars.end()) {
violation = true;
break;
}
}
if (violation) {
triedPairs.insert(key);
bool wouldCreateViolation = false;
for (size_t k = j; k < i; k++) {
SgStatement* betweenStmt = newOrder[k];
const OperatorInfo* betweenOpInfo = stmtToOpInfo[betweenStmt];
if (!betweenOpInfo)
continue;
for (const string& usedVar : opInfo->usedVars) {
if (betweenOpInfo->definedVars.find(usedVar) != betweenOpInfo->definedVars.end()) {
wouldCreateViolation = true;
break;
}
}
if (wouldCreateViolation)
break;
}
if (!wouldCreateViolation) {
newOrder.erase(newOrder.begin() + i);
newOrder.insert(newOrder.begin() + j, stmt);
dependencyViolation = true;
break;
}
}
}
if (dependencyViolation)
break;
}
}
return newOrder;
}
static bool applyOperatorReordering(SgForStmt* loop, const vector<SgStatement*>& newOrder) {
if (!loop || newOrder.empty())
return false;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (!loopStart || !loopEnd)
return false;
vector<SgStatement*> originalOrder;
SgStatement* current = loopStart;
while (current && current != loopEnd) {
if (isSgExecutableStatement(current) && current->variant() == ASSIGN_STAT)
originalOrder.push_back(current);
current = current->lexNext();
}
bool orderChanged = false;
if (originalOrder.size() == newOrder.size()) {
for (size_t i = 0; i < originalOrder.size(); i++) {
if (originalOrder[i] != newOrder[i]) {
orderChanged = true;
break;
}
}
}
else
orderChanged = true;
if (!orderChanged)
return false;
vector<SgStatement*> extractedStatements;
vector<char*> savedComments;
unordered_set<SgStatement*> extractedSet;
map<SgStatement*, int> originalLineNumbers;
map<SgStatement*, SgStatement*> stmtToExtracted;
for (SgStatement* stmt : newOrder) {
if (stmt && stmt != loop && stmt != loopEnd && extractedSet.find(stmt) == extractedSet.end()) {
if (control_tags.find(stmt->variant()) != control_tags.end())
continue;
if (!canSafelyExtract(stmt, loop))
continue;
bool isMoving = false;
for (size_t i = 0; i < originalOrder.size(); i++) {
if (originalOrder[i] == stmt) {
for (size_t j = 0; j < newOrder.size(); j++) {
if (newOrder[j] == stmt && i != j) {
isMoving = true;
break;
}
}
break;
}
}
if (!isMoving)
continue;
originalLineNumbers[stmt] = stmt->lineNumber();
savedComments.push_back(stmt->comments() ? strdup(stmt->comments()) : nullptr);
SgStatement* extracted = stmt->extractStmt();
if (extracted) {
extractedStatements.push_back(extracted);
extractedSet.insert(stmt);
stmtToExtracted[stmt] = extracted;
}
}
}
map<SgStatement*, SgStatement*> insertedStatements;
for (size_t idx = 0; idx < newOrder.size(); idx++) {
SgStatement* stmt = newOrder[idx];
if (extractedSet.find(stmt) != extractedSet.end()) {
SgStatement* stmtToInsert = stmtToExtracted[stmt];
if (!stmtToInsert)
continue;
SgStatement* insertAfter = loop;
for (int i = idx - 1; i >= 0; i--) {
SgStatement* prevStmt = newOrder[i];
if (extractedSet.find(prevStmt) != extractedSet.end()) {
if (insertedStatements.find(prevStmt) != insertedStatements.end()) {
insertAfter = insertedStatements[prevStmt];
break;
}
} else {
SgStatement* search = loop->lexNext();
while (search && search != loopEnd) {
bool skip = false;
for (size_t j = idx; j < newOrder.size(); j++) {
if (extractedSet.find(newOrder[j]) != extractedSet.end() &&
search == newOrder[j]) {
skip = true;
break;
}
}
if (skip) {
search = search->lexNext();
continue;
}
if (search == prevStmt) {
insertAfter = search;
break;
}
search = search->lexNext();
}
if (insertAfter != loop) break;
}
}
size_t commentIdx = 0;
for (size_t i = 0; i < extractedStatements.size(); i++) {
if (extractedStatements[i] == stmtToInsert) {
commentIdx = i;
break;
}
}
if (commentIdx < savedComments.size() && savedComments[commentIdx])
stmtToInsert->setComments(savedComments[commentIdx]);
if (originalLineNumbers.find(stmt) != originalLineNumbers.end())
stmtToInsert->setlineNumber(originalLineNumbers[stmt]);
SgStatement* controlParent = stmt->controlParent();
if (!controlParent)
controlParent = loop;
insertAfter->insertStmtAfter(*stmtToInsert, *controlParent);
insertedStatements[stmt] = stmtToInsert;
}
}
for (char* comment : savedComments) {
if (comment)
free(comment);
}
return true;
}
vector<SAPFOR::BasicBlock*> findFuncBlocksByFuncStatement(SgStatement *st, const 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, const 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()) {
SgForStmt *forSt = (SgForStmt*)st;
SgStatement *loopBody = forSt -> body();
SgStatement *lastLoopNode = st->lastNodeOfStmt();
unordered_set<int> blocks_nums;
while (loopBody && loopBody != lastLoopNode) {
vector<SAPFOR::IR_Block*> irBlocks = findInstructionsFromOperator(loopBody, blocks);
if (!irBlocks.empty()) {
SAPFOR::IR_Block* IR = irBlocks.front();
if (IR && IR->getBasicBlock()) {
if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end()) {
result[forSt].push_back(IR -> getBasicBlock());
blocks_nums.insert(IR -> getBasicBlock() -> getNumber());
}
}
}
loopBody = loopBody -> lexNext();
}
sort(result[forSt].begin(), result[forSt].end());
}
st = st -> lexNext();
}
return result;
}
static void processLoopRecursively(SgForStmt* loop, const vector<SAPFOR::BasicBlock*>& blocks,
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) {
if (!loop)
return;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (loopStart && loopEnd) {
SgStatement* current = loopStart;
while (current && current != loopEnd) {
if (current->variant() == FOR_NODE && current != loop) {
SgForStmt* nestedLoop = (SgForStmt*)current;
processLoopRecursively(nestedLoop, blocks, FullIR);
SgStatement* nestedEnd = nestedLoop->lastNodeOfStmt();
if (nestedEnd)
current = nestedEnd->lexNext();
else
current = current->lexNext();
}
else
current = current->lexNext();
}
}
vector<OperatorInfo> operators = analyzeOperatorsInLoop(loop, blocks, FullIR);
if (!operators.empty()) {
map<string, vector<SgStatement*>> varDefinitions = findVariableDefinitions(loop, operators);
vector<SgStatement*> newOrder = optimizeOperatorOrder(loop, operators, varDefinitions);
applyOperatorReordering(loop, newOrder);
}
}
void moveOperators(SgFile *file, map<string, vector<LoopGraph*>>& loopGraph,
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR,
int& countOfTransform) {
countOfTransform += 1;
//cout << "MOVE_OPERATORS Pass Started" << endl;
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 (auto& loopForAnalyze: loopsMapping)
processLoopRecursively(loopForAnalyze.first, loopForAnalyze.second, FullIR);
}
//cout << "MOVE_OPERATORS Pass Completed" << endl;
}

View File

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

View File

@@ -13,6 +13,7 @@ using std::set;
using std::string;
using std::vector;
using std::wstring;
using SAPFOR::CFG_Settings;
using CFG_Type = map<FuncInfo*, vector<SAPFOR::BasicBlock*>>;
using UsersDirectives = map<pair<string, int>, set<SgStatement*>>;
@@ -2207,8 +2208,8 @@ static void removePrivateAnalyze(Context *ctx)
makeDeclaration(ctx->loopStmt, vector<SgSymbol*> {receiverVar}, nullptr)
));
CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(ctx->loopStmt,
SAPFOR::CFG_Settings(true, true),
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop, CFG_Settings::CFG_withRD, CFG_Settings::CFG_withCallFrom, CFG_Settings::CFG_withDominators });
CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(ctx->loopStmt, settings,
ctx->commonBlocks, ctx->allFuncInfo);
if (CFG_ForFunc.empty())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);

View File

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

View File

@@ -17,6 +17,157 @@ using std::pair;
#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)
{
if (exp)
@@ -29,12 +180,15 @@ static void findArrays(SgExpression* exp, set<SgSymbol*>& arrays)
}
}
static void populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& arrays, SgStatement* stat)
static bool populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& arrays,
SgStatement* stat,
const string& current_file_name,
FuncInfo *current_func)
{
auto var = stat->variant();
if (var != READ_STAT && var != PRINT_STAT && var != WRITE_STAT)
return;
return false;
// check if such IO allowed in dvm:
// list should consist only of single array and format string should be *
@@ -44,22 +198,26 @@ static void populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
SgExpression* ioList = stat->expr(0);
if (!ioList)
return;
return false;
if (ioList->variant() != EXPR_LIST)
return;
return false;
if (ioList->rhs() == NULL)
{
SgExpression* arg = ioList->lhs();
if (!arg)
return;
return false;
if (!isArrayRef(arg))
return;
if (arg->lhs())
need_replace = true;
if (hasArrayRef(arg))
{
if (isArrayRef(arg) && arg->lhs())
need_replace = true;
}
else
{
return false;
}
}
else
{
@@ -74,15 +232,11 @@ static void populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
{
SgExpression* fmt = stat->expr(1);
if (!fmt || fmt->variant() != SPEC_PAIR || fmt->lhs()->variant() != KEYWORD_VAL)
{
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return;
}
if (fmt->rhs()->variant() != KEYWORD_VAL || fmt->rhs()->sunparse() != "*")
need_replace = true;
break;
}
case READ_STAT:
@@ -104,10 +258,7 @@ static void populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
{
auto *kv = spec->lhs();
if (!kv || kv->variant() != SPEC_PAIR || !kv->rhs())
{
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return;
}
if (kv->rhs()->variant() != KEYWORD_VAL || kv->rhs()->sunparse() != "*")
{
@@ -118,6 +269,7 @@ static void populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
spec = spec->rhs();
}
}
break;
}
default:
break;
@@ -125,7 +277,9 @@ static void populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
}
if (!need_replace)
return;
return false;
bool ret = false;
set<SgSymbol*> found_arrays;
@@ -136,11 +290,21 @@ static void populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
{
string array_name = string(by_symb->identifier());
DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(by_symb), array_name);
if (array_p && array_p->GetDistributeFlagVal() == Distribution::distFlag::IO_PRIV && arrays[by_symb].insert(stat).second)
__spf_print(DEBUG_TRACE, "[%d]: add array %s\n", stat->lineNumber(), array_p->GetName().c_str());
if (array_p &&
array_p->GetDistributeFlagVal() == Distribution::distFlag::IO_PRIV &&
!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");
return ret;
}
static void replaceArrayRec(SgSymbol* arr, SgSymbol* replace_by, SgExpression* exp, bool& has_read, bool& has_write, bool from_read, bool from_write)
@@ -210,7 +374,12 @@ static void replaceArrayRec(SgSymbol* arr, SgSymbol* replace_by, SgStatement* st
}
}
static void copyArrayBetweenStatements(SgSymbol* replace_symb, SgSymbol* replace_by, SgStatement* start, SgStatement* last, bool start_is_scope)
static void copyArrayBetweenStatements(SgSymbol* replace_symb,
SgSymbol* replace_by,
SgStatement* start,
SgStatement* last,
bool start_is_scope,
FuncInfo *func_info)
{
while (start->lexNext() && !isSgExecutableStatement(start->lexNext()))
start = start->lexNext();
@@ -229,10 +398,23 @@ static void copyArrayBetweenStatements(SgSymbol* replace_symb, SgSymbol* replace
auto* parent = start_is_scope ? start : start->controlParent();
if (parent && parent->lastNodeOfStmt() == start)
parent = parent->controlParent();
checkNull(parent, convertFileName(__FILE__).c_str(), __LINE__);
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)
{
// A = A_reg
@@ -243,9 +425,14 @@ static void copyArrayBetweenStatements(SgSymbol* replace_symb, SgSymbol* replace
}
}
static void replaceArrayInFragment(SgSymbol* replace_symb, const set<SgStatement*> usages, SgSymbol* replace_by, SgStatement* start, SgStatement* last, const string& filename)
static void replaceArrayInFragment(SgSymbol* replace_symb,
const set<SgStatement*> usages,
SgSymbol* replace_by,
SgStatement* start,
SgStatement* last,
FuncInfo *func_info)
{
while (start->lexNext() && !isSgExecutableStatement(start->lexNext()))
while (start->lexNext() && (!isSgExecutableStatement(start->lexNext()) || start->lexNext()->variant() == ALLOCATE_STMT))
start = start->lexNext();
set<SgStatement*> not_opened, not_closed, copied;
@@ -312,7 +499,7 @@ static void replaceArrayInFragment(SgSymbol* replace_symb, const set<SgStatement
}
__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);
copyArrayBetweenStatements(replace_symb, replace_by, scope_start, scope_end, copy_scope == scope_start, func_info);
copied.insert(copy_scope);
}
}
@@ -335,12 +522,16 @@ static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound)
STOP_STAT,
STOP_NODE,
EXIT_STMT,
EXIT_NODE
EXIT_NODE,
GOTO_NODE
};
if (border_stats.find(var) != border_stats.end())
return true;
if (stat->hasLabel())
return true;
if (last_io_bound && last_io_bound->lastNodeOfStmt() && last_io_bound->lastNodeOfStmt() == stat)
return true;
@@ -353,9 +544,9 @@ static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound)
}
void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
const map<string, vector<FuncInfo*>>& allFuncInfo,
map<string, vector<Messages>>& SPF_messages,
map<string, map<int, set<string>>>& newDeclsToInclude)
const map<string, vector<FuncInfo*>>& allFuncInfo,
map<string, vector<Messages>>& SPF_messages,
map<string, map<int, set<string>>>& newDeclsToInclude)
{
map<SgSymbol*, SgSymbol*> created_copies;
map<string, map<int, set<string>>> copied_syms;
@@ -364,26 +555,29 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
{
__spf_print(DEBUG_TRACE, "[%s]: enter region\n", region->GetName().c_str());
for (auto& linesByFile : region->GetAllLinesToModify())
for (auto& lines_by_file : region->GetAllLinesToModify())
{
const auto& filename = linesByFile.first;
const auto& current_file_name = lines_by_file.first;
if (SgFile::switchToFile(filename) < 0)
{
if (SgFile::switchToFile(current_file_name) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return;
}
for (auto& lines : linesByFile.second)
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", filename.c_str(), lines.lines.first,
__spf_print(DEBUG_TRACE, "[fragment] %s: %d:%d %d\n", current_file_name.c_str(), lines.lines.first,
lines.lines.second, lines.isImplicit());
SgStatement* curr_stmt, * end;
if (lines.isImplicit())
{
curr_stmt = current_file->SgStatementAtLine(lines.lines.first);
end = current_file->SgStatementAtLine(lines.lines.second);
@@ -399,6 +593,7 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
map<SgSymbol*, set<SgStatement*>> need_replace;
SgStatement* last_io_bound = NULL;
FuncInfo *current_func_info = NULL;
while (curr_stmt != end)
{
@@ -407,9 +602,21 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
auto var = curr_stmt->variant();
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();
while (curr_stmt && !isSgExecutableStatement(curr_stmt))
{
@@ -433,77 +640,192 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
string array_name = string(array_to_copy->identifier());
DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(array_to_copy), array_name);
bool fromModule = (array_p->GetLocation().first == DIST::l_MODULE);
const string locationName = array_p->GetLocation().second;
// at this point all considered arrays must have DIST::Array* references
if (!array_p)
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";
if (fromModule)
suffix = "_io_m";
pair<SgSymbol*, SgSymbol*> copied;
copied.first = array_to_copy;
if (SgFile::switchToFile(fileName) == -1)
switch (array_p->GetLocation().first)
{
auto* func_stmt = curr_stmt->getScopeForDeclare();
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);
SgStatement* insertPlace = NULL;
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();
for (auto iterator = func_stmt->lexNext();
!isSgExecutableStatement(iterator) || isSPF_stat(iterator) &&
!(iterator->variant() == SPF_PARALLEL_REG_DIR || iterator->variant() == SPF_END_PARALLEL_REG_DIR);
iterator && !isSgExecutableStatement(iterator);
iterator = iterator->lexNext())
{
insertPlace = iterator;
allocate_stmt_place = iterator;
}
//NULL - no decl stats in function!
if (!insertPlace)
insertPlace = func_stmt;
if (!allocate_stmt_place)
allocate_stmt_place = func_stmt;
auto st = insertPlace->controlParent();
if (st->variant() == GLOBAL)
st = insertPlace;
auto *allocate_stmt_parent = allocate_stmt_place->controlParent();
if (allocate_stmt_parent->variant() == GLOBAL)
allocate_stmt_parent = allocate_stmt_place;
auto *created_array_ref = new SgArrayRefExp(*copied_symbol.second);
auto& copied_symb = array_to_copy->copy();
copied.second = &copied_symb;
auto new_name = string(array_to_copy->identifier()) + "_io_c";
copied_symb.changeName(new_name.c_str());
auto stat = array_to_copy->makeVarDeclStmt();
auto res = CalculateInteger(stat->expr(0)->copyPtr());
res->lhs()->setSymbol(copied_symb);
stat->setExpression(0, res);
insertPlace->insertStmtAfter(*stat, *st);
}
else
{
copied = copyArray(place, array_p, linesByFile.second, suffix + to_string(region->GetId()), fileName, newDeclsToInclude, copied_syms);
}
SgStatement* decl = SgStatement::getStatementByFileAndLine(place.first, place.second);
if (decl)
decl = decl->lexNext();
if (decl)
{
string dir_str;
if (decl->comments())
auto* dim_list = new SgExprListExp();
created_array_ref->setLhs(dim_list);
int dim_len = array_p->GetSizes().size();
for (int i = 1; i <= dim_len; i++)
{
string str_comment = string(decl->comments());
if (str_comment.size() && str_comment.back() != '\n')
dir_str += "\n";
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));
call->lhs()->setRhs(new SgValueExp(i));
}
auto *dot_expr = new SgExpression(DDOT);
dot_expr->setLhs(lcall);
dot_expr->setRhs(rcall);
dim_list->setLhs(dot_expr);
if (i < dim_len)
{
auto *next = new SgExprListExp();
dim_list->setRhs(next);
dim_list = next;
}
}
dir_str += "!$SPF ANALYSIS(PROCESS_PRIVATE(" + string(copied.second->identifier()) + "))\n";
decl->addComment(dir_str.c_str());
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;
}
}
created_copies.insert({ array_to_copy, copied.second });
// can't switch back to file with array usage
if (SgFile::switchToFile(current_file_name) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
@@ -515,12 +837,9 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
{
auto it = created_copies.find(p.first);
if (it != created_copies.end())
replaceArrayInFragment(p.first, p.second, it->second, last_io_bound, curr_stmt, filename);
replaceArrayInFragment(p.first, p.second, it->second, last_io_bound, curr_stmt, current_func_info);
else
{
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return;
}
}
}
@@ -538,7 +857,17 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
}
}
populateDistributedIoArrays(need_replace, curr_stmt);
auto need_fix_io = populateDistributedIoArrays(need_replace, curr_stmt, current_file_name, current_func_info);
// 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();
}
}

View File

@@ -206,7 +206,9 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
Pass(DEF_USE_STAGE1) <= Pass(DEF_USE_STAGE2);
list({ VERIFY_DVM_DIRS, PRIVATE_CALL_GRAPH_STAGE1, PRIVATE_CALL_GRAPH_STAGE2, MACRO_EXPANSION, CONVERT_ASSIGN_TO_LOOP, DEF_USE_STAGE1, DEF_USE_STAGE2, FILL_PARALLEL_REG_IR, VERIFY_COMMON, FILL_COMMON_BLOCKS, CALL_GRAPH_IR }) <= list({ SUBST_EXPR, SUBST_EXPR_RD, BUILD_IR });
list({ VERIFY_DVM_DIRS, VERIFY_COMMON, FILL_COMMON_BLOCKS, PRIVATE_CALL_GRAPH_STAGE1, PRIVATE_CALL_GRAPH_STAGE2, MACRO_EXPANSION, CONVERT_ASSIGN_TO_LOOP, DEF_USE_STAGE1, DEF_USE_STAGE2, FILL_PARALLEL_REG_IR, CALL_GRAPH_IR }) <= list({ SUBST_EXPR, SUBST_EXPR_RD, BUILD_IR });
Pass(VERIFY_COMMON) <= Pass(FILL_COMMON_BLOCKS);
Pass(BUILD_IR) <= Pass(SUBST_EXPR) <= Pass(SUBST_EXPR_AND_UNPARSE);
@@ -217,7 +219,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
Pass(RESTORE_LOOP_FROM_ASSIGN) <= list({ SUBST_EXPR_AND_UNPARSE, SUBST_EXPR_RD_AND_UNPARSE });
Pass(GET_ALL_ARRAY_DECL) <= list({ CALL_GRAPH_IR, INSERT_NO_DISTR_FLAGS_FROM_GUI });
Pass(FILL_COMMON_BLOCKS) <= Pass(GET_ALL_ARRAY_DECL) <= list({ CALL_GRAPH_IR, INSERT_NO_DISTR_FLAGS_FROM_GUI });
Pass(LOOP_GRAPH) <= Pass(PRIVATE_CALL_GRAPH_STAGE3) <= list(FIND_FUNC_TO_INCLUDE, PRIVATE_ANALYSIS_IR) <= list({ LOOP_ANALYZER_DATA_DIST_S0, LOOP_ANALYZER_DATA_DIST_S1, ONLY_ARRAY_GRAPH, LOOP_ANALYZER_ALIGNS });
@@ -227,7 +229,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_SPF, PREPROC_ALLOCATES, GET_ALL_ARRAY_DECL, GCOV_PARSER }) <= list({ CALL_GRAPH, MACRO_EXPANSION, DEF_USE_STAGE1 });
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ GET_ALL_ARRAY_DECL, FILL_COMMON_BLOCKS, PARSE_OMP_DIRS }) <= Pass(PREPROC_SPF);
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ FILL_COMMON_BLOCKS, GET_ALL_ARRAY_DECL, PARSE_OMP_DIRS }) <= Pass(PREPROC_SPF);
Pass(CHECK_PAR_REG_DIR) <= Pass(FILL_PARALLEL_REG_IR);
@@ -316,9 +318,10 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE);
list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2, BUILD_IR }) <= Pass(BUILD_IR_SSA_FORM) <= Pass(FIND_IMPLICIT_LOOPS);
list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS);
list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS);
list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2, BUILD_IR, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS);
list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS);
passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS,
EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,

View File

@@ -934,8 +934,14 @@ void fillNonDistrArraysAsPrivate(SgStatement *st,
{
auto itD = declaredArrays.find(*itSet);
if (itD != declaredArrays.end())
if (itD->second.first->IsNotDistribute())
privatesVars.insert(itD->second.first->GetShortName());
{
const auto array = itD->second.first;
if (array->IsNotDistribute())
{
auto symb = array->GetDeclSymbol(make_pair(st->fileName(), st->lineNumber()));
privatesVars.insert(symb->identifier());
}
}
}
}
}
@@ -953,9 +959,21 @@ DIST::Array* getArrayFromDeclarated(SgStatement *st, const string &arrayName)
for (auto itSet = it->second.begin(); itSet != it->second.end() && !found; ++itSet)
{
auto itD = declaredArrays.find(*itSet);
if (itD != declaredArrays.end())
if (itD->second.first->GetShortName() == arrayName)
found = itD->second.first;
if (itD != declaredArrays.end())
{
DIST::Array* array = itD->second.first;
if (array->GetLocation().first == DIST::l_COMMON)
{
auto symb = array->GetDeclSymbol(make_pair(st->fileName(), st->lineNumber()));
if (symb && symb->identifier() == arrayName)
found = array;
}
else
{
if (array->GetShortName() == arrayName)
found = array;
}
}
}
}
return found;
@@ -1264,6 +1282,32 @@ static SgExpression* isInCommon(const vector<SgExpression*> &commonBlocks, const
return NULL;
}
//all common block in project
extern map<string, CommonBlock*> commonBlocks;
static string getCommonNameOnPos(const string& name, const int commonPos)
{
if (commonBlocks.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto it = commonBlocks.find(name);
if (it == commonBlocks.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto inPos = it->second->getGroupedVars().find(commonPos);
if (inPos == it->second->getGroupedVars().end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
set<string> namesOnPos;
for (auto& var : inPos->second)
namesOnPos.insert(var->getName());
if (namesOnPos.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return *namesOnPos.begin();
}
static map<tuple<string, string, int>, tuple<int, string, string>> tableOfUniqNames;
tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>> &commonBlocks, SgStatement *decl, SgSymbol *symb)
{
@@ -1272,6 +1316,7 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
int commonPos = 0;
SgExpression *foundCommon = NULL;
string symbCommn = "";
SgStatement *declCP = decl->controlParent();
// find symbol in parameter list of functions
@@ -1307,6 +1352,7 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
if (foundCommon)
{
inCommon = true;
symbCommn = getCommonNameOnPos(common.first, commonPos);
break;
}
}
@@ -1314,7 +1360,7 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
tuple<int, string, string> retVal;
if (inCommon)
retVal = make_tuple(commonPos, string("common_") + getCommonName(foundCommon), string(symb->identifier()));
retVal = make_tuple(commonPos, string("common_") + getCommonName(foundCommon), symbCommn);
else
retVal = make_tuple(decl->lineNumber(), string(decl->fileName()), string(symb->identifier()));

View File

@@ -337,10 +337,15 @@ const set<SgSymbol*>& getModuleSymbols(SgStatement *func)
//if function or module in contains
auto cp = func->controlParent();
if (isSgProgHedrStmt(cp) || cp->variant() == MODULE_STMT)
{
getModuleSymbols(cp, symbs);
if (func->variant() == FUNC_HEDR)
symbs.insert(func->symbol());
}
symbolsForFunc[func->symbol()->identifier()] = symbs;
return symbs;
return symbolsForFunc[func->symbol()->identifier()];
}
static void findSymbol(SgStatement* func, const string& varName, const string& locName,
@@ -349,9 +354,19 @@ static void findSymbol(SgStatement* func, const string& varName, const string& l
for (const auto& s : getModuleSymbols(func))
{
SgSymbol* orig = OriginalSymbol(s);
printf("%s == %s\n", orig->identifier(), s->identifier());
//any suitable symbol can be used
if (orig->identifier() == varName && orig->scope()->symbol()->identifier() == locName)
altNames[s->identifier()] = s;
if (orig->variant() == FUNCTION_NAME)
{
if (orig->identifier() == varName)
altNames[s->identifier()] = s;
}
else
{
if (orig->identifier() == varName && orig->scope()->symbol()->identifier() == locName)
altNames[s->identifier()] = s;
}
}
}
@@ -369,6 +384,7 @@ SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const stri
return altNames.begin()->second;
else {
__spf_print(1, "%s (%s %s) %s\n", func->symbol()->identifier(), clearName.c_str(), varName.c_str(), locName.c_str());
findSymbol(func, varName, locName, altNames);
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}

View File

@@ -390,32 +390,15 @@ void clearGlobalBuffer() { globalOutputBuffer = ""; }
const string& getGlobalBuffer() { return globalOutputBuffer; }
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
void clearGlobalMessagesBuffer()
{
//clear allocated memory
for (auto& elem : allocated)
delete[]elem;
for (auto& elem : allocatedInt)
delete[]elem;
delete []elem;
allocated.clear();
allocatedInt.clear();
SPF_messages.clear();
}
@@ -451,7 +434,7 @@ static map<string, vector<Messages>> removeCopies(map<string, vector<Messages>>
return out;
}
static void convertGlobalMessagesBuffer(short *&result, int *&resultSize)
static string convertGlobalMessagesBuffer()
{
auto copySPF_messages = removeCopies(SPF_messages);
for (auto &byFile : copySPF_messages)
@@ -489,21 +472,13 @@ static void convertGlobalMessagesBuffer(short *&result, int *&resultSize)
json all;
all["allMessages"] = allMessages;
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;
return all.dump();
}
void convertBuffers(short*& resultM, int*& resultSizeM, short*& result, int*& resultSize)
void convertBuffers(string &resultM, string &result)
{
convertGlobalMessagesBuffer(resultM, resultSizeM);
convertGlobalBuffer(result, resultSize);
resultM = convertGlobalMessagesBuffer();
result = getGlobalBuffer();
}
bool isSPF_comment(const string &bufStr)
@@ -594,8 +569,8 @@ void copyIncludes(const set<string> &allIncludeFiles, const map<string, map<int,
while (!feof(oldFile))
{
char buf[8192];
char *res = fgets(buf, 16384, oldFile);
char buf[16384];
char *res = fgets(buf, sizeof(buf), oldFile);
if (res == NULL)
break;

View File

@@ -33,7 +33,7 @@ void addToGlobalBufferAndPrint(const std::string &toPrint);
void clearGlobalBuffer();
const std::string& getGlobalBuffer();
std::wstring to_wstring(const std::string);
void convertBuffers(short*& resultM, int*& resultSizeM, short*& result, int*& resultSize);
void convertBuffers(std::string& resultM, std::string& result);
void clearGlobalMessagesBuffer();
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);

View File

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

File diff suppressed because it is too large Load Diff