111 Commits

Author SHA1 Message Date
Egor Mayorov
7390d96b1f change reordering logic 2026-04-01 17:12:55 +03:00
a1e12f5c1c Merge pull request 'egormayorov' (#78) from egormayorov into master 2026-03-27 08:29:34 +03:00
ALEXks
cad8c0913d Merge branch 'master' into egormayorov 2026-03-27 08:28:44 +03:00
ALEXks
bde804cff6 updated 2026-03-27 08:27:25 +03:00
Egor Mayorov
589680a78b fix files usage 2026-03-26 14:18:45 +03:00
ALEXks
88bac54901 fixed function prototype 2026-03-26 14:18:45 +03:00
ALEXks
0d4d2b78d8 updated 2026-03-26 14:18:45 +03:00
Egor Mayorov
bbac07202d Add swith to file usage 2026-03-26 14:18:39 +03:00
ALEXks
9325723e69 updated projects 2026-03-20 15:32:24 +03:00
ALEXks
18ac53f342 fixed inliner 2026-03-19 13:04:26 +03:00
ALEXks
0bec2c6527 assign line number to intervals for loops 2026-03-10 20:33:02 +03:00
aa56778be1 Merge pull request 'Move operators pass fixes' (#77) from egormayorov into master 2026-03-10 10:03:36 +03:00
ALEXks
0a484e77de version updated 2026-03-10 10:03:27 +03:00
Egor Mayorov
4818884d48 Remove redundant functions 2026-03-08 18:34:36 +03:00
Egor Mayorov
e172678e1b fix freezing 2026-03-08 18:28:21 +03:00
Egor Mayorov
0a977146a7 Analyze program block by block & reorder operators only in basic blocks 2026-03-05 15:55:47 +03:00
Egor Mayorov
0b50e0630a use rd 2026-03-05 15:55:47 +03:00
ALEXks
980ddeeac7 fixed build 2026-03-04 20:26:23 +03:00
788eeda22e Merge pull request 'fix search algorithm' (#76) from private_arrays2 into master 2026-03-04 20:22:08 +03:00
ALEXks
4a9cba7b96 version updated 2026-03-04 20:22:01 +03:00
42044b60f1 fix algorythm 2026-03-04 09:40:54 +03:00
ALEXks
80a1fecb1c fixed getStatementByFileAndLine 2026-03-03 09:18:15 +03:00
ALEXks
2db6bf4bdf fixed recovering of includes 2026-03-03 09:00:42 +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
44 changed files with 1989 additions and 815 deletions

View File

@@ -163,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
@@ -204,8 +208,8 @@ set(TR_INLINER src/Transformations/FunctionInlining/inliner.cpp
src/Transformations/FunctionInlining/inliner.h)
set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp
src/Transformations/RenameSymbols/rename_symbols.h)
SET(TR_SWAP_OPERATORS src/Transformations/SwapOperators/swap_operators.cpp
src/Transformations/SwapOperators/swap_operators.h)
SET(TR_MOVE_OPERATORS src/Transformations/MoveOperators/move_operators.cpp
src/Transformations/MoveOperators/move_operators.h)
set(TRANSFORMS
${TR_DEAD_CODE}
@@ -229,7 +233,7 @@ set(TRANSFORMS
${TR_EXPR_TRANSFORM}
${TR_INLINER}
${TR_RENAME_SYMBOLS}
${TR_SWAP_OPERATORS})
${TR_MOVE_OPERATORS})
set(CFG src/CFGraph/IR.cpp
src/CFGraph/IR.h
@@ -423,6 +427,7 @@ set(SOURCE_EXE
${TRANSFORMS}
${PARALLEL_REG}
${PRIV}
${ARRAY_PROP}
${FDVM}
${OMEGA}
${UTILS}
@@ -462,7 +467,7 @@ source_group (Transformations\\GlobalVariables FILES ${TR_GV})
source_group (Transformations\\ConvertToC FILES ${TR_CONV})
source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE})
source_group (Transformations\\ReplaceArraysInIO FILES ${TR_REPLACE_ARRAYS_IN_IO})
source_group (Transformations\\SwapOperators FILES ${TR_SWAP_OPERATORS})
source_group (Transformations\\MoveOperators FILES ${TR_MOVE_OPERATORS})
source_group (CreateIntervals FILES ${CREATE_INTER_T})
@@ -475,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})

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

@@ -1162,6 +1162,7 @@ map<FuncInfo*, vector<BBlock*>> buildCFG(const map<string, CommonBlock*>& common
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (!settings.withUnreachable)
for (auto& [func, blocks] : result)
removedUnreachableBlocks(blocks);

View File

@@ -105,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 withRD = false;
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 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

@@ -200,15 +200,41 @@ static void fillOutForFunc(const FuncInfo* func, const vector<SAPFOR::BasicBlock
outForFunc[func->funcName] = { defined, common_defined };
}
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)
{
@@ -236,11 +262,19 @@ 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);
}
}
}
}
@@ -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

@@ -17,7 +17,7 @@ using std::fstream;
static long int getNextTag()
{
static long int INTERVAL_TAG = 0;
return INTERVAL_TAG++;
return -(INTERVAL_TAG++);
}
//Debug funcs
@@ -413,7 +413,7 @@ static void findIntervals(SpfInterval *interval, map<int, int> &labelsRef, map<i
inter->lineFile = std::make_pair(currentSt->lineNumber(), currentSt->fileName());
inter->parent = interval;
inter->exit_levels.push_back(0);
inter->tag = getNextTag();
inter->tag = currentSt->lineNumber();//getNextTag();
interval->nested.push_back(inter);
findIntervals(inter, labelsRef, gotoStmts, currentSt);

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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -1,3 +1,4 @@
#include <algorithm>
#include <map>
#include <unordered_set>
#include <unordered_map>
@@ -12,49 +13,120 @@
#include "SgUtils.h"
#include "graph_loops.h"
#include "CFGraph/CFGraph.h"
#include "utils.h"
using namespace std;
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);
}
}
}
RegionInstruction instruction;
instruction.def = move(region->array_def);
for (auto& byBlock : region->getBasickBlocks())
{
for (auto& [arrayName, arrayRanges] : byBlock->array_use)
for (auto& instruction : byBlock->instructions)
{
AccessingSet diff = byBlock->array_use[arrayName].Diff(byBlock->array_in[arrayName]);
for (auto& [arrayName, _] : instruction.use)
{
AccessingSet diff = instruction.use[arrayName].Diff(instruction.in[arrayName]);
region->array_use[arrayName] = region->array_use[arrayName].Union(diff);
}
}
ArrayAccessingIndexes useUnion;
for (auto& byBlock : region->getBasickBlocks())
for (auto& [arrayName, arrayRanges] : byBlock->array_use)
useUnion[arrayName] = useUnion[arrayName].Union(byBlock->array_use[arrayName]);
}
for (auto& [arrayName, arrayRanges] : useUnion)
region->array_priv[arrayName] = useUnion[arrayName].Diff(region->array_use[arrayName]);
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)
{
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,8 +144,9 @@ 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())
@@ -86,6 +159,7 @@ static void SolveDataFlowIteratively(Region* DFG)
b->array_in = move(newIn);
ArrayAccessingIndexes newOut;
if (b->array_def.empty())
newOut = b->array_in;
else if (b->array_in.empty())
@@ -106,36 +180,232 @@ static void SolveDataFlowIteratively(Region* DFG)
b->array_out = newOut;
else
worklist.erase(b);
} 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);
}
while (!worklist.empty());
}
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)
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++)
{
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())
{
if (arrayElement.empty())
continue;
arraysToInsert.insert(arrayElement[0].array->symbol());
}
}
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& [loopName, loops] : loopGraph)
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);
}
}
return result;
}

View File

@@ -2,11 +2,12 @@
#include <vector>
#include <map>
#include <set>
#include <unordered_set>
#include "range_structures.h"
#include "graph_loops.h"
#include "CFGraph/CFGraph.h"
std::map<LoopGraph*, ArrayAccessingIndexes> FindPrivateArrays(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR);
void 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

@@ -47,7 +47,7 @@ static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const A
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;
}
@@ -61,21 +61,16 @@ static vector<ArrayDimension> DimensionDifference(const ArrayDimension& dim1, co
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 });
result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step, dim1.array });
/* add the parts between intersection steps */
if (intersection->step > dim1.step)
{
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++)
for (int64_t i = start; interValue <= intersection->start + intersection->step * (intersection->tripCount - 1); i++)
{
uint64_t centerValue = dim1.start + i * dim1.step;
if (centerValue == interValue)
{
if (i - start > 1)
{
result.push_back({ dim1.start + (start + 1) * dim1.step, dim1.step, i - start - 1 });
start = i;
}
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;
@@ -137,8 +132,10 @@ 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;
@@ -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;
}

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,14 @@
#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 "SgUtils.h"
using namespace std;
@@ -92,7 +93,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 +105,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,29 +150,29 @@ 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();
@@ -175,27 +198,84 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
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 };
}
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 (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)
@@ -210,10 +290,11 @@ static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegi
}
}
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));
else
@@ -227,8 +308,12 @@ static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*
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 +324,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

@@ -8,6 +8,11 @@
#include "graph_loops.h"
#include "CFGraph/CFGraph.h"
struct RegionInstruction
{
ArrayAccessingIndexes def, use, in, out;
};
class Region : public SAPFOR::BasicBlock {
public:
Region() { header = nullptr; }
@@ -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

@@ -1,4 +1,4 @@
#include "Utils/leak_detector.h"
#include "Utils/leak_detector.h"
#pragma comment(linker, "/STACK:536870912") // 512 МБ
@@ -46,6 +46,7 @@
#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"
@@ -89,7 +90,7 @@
#include "Transformations/DeadCodeRemoving/dead_code.h"
#include "Transformations/RenameSymbols/rename_symbols.h"
#include "Transformations/FunctionInlining/inliner.h"
#include "Transformations/SwapOperators/swap_operators.h"
#include "Transformations/MoveOperators/move_operators.h"
#include "ProjectParameters/projectParameters.h"
@@ -280,6 +281,7 @@ 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)
if (insertedPrivates.find(st) == insertedPrivates.end())
toDel.push_back(st);
for (auto& elem : toDel)
@@ -940,8 +942,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
internalExit = err;
}
}
else if (curr_regime == SWAP_OPERATORS)
runSwapOperators(file, loopGraph, fullIR, countOfTransform);
else if (curr_regime == MOVE_OPERATORS)
moveOperators(file, fullIR, countOfTransform);
else if (curr_regime == PRIVATE_REMOVING_ANALYSIS)
{
auto itFound = loopGraph.find(file->filename());
@@ -1022,8 +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 == FIND_PRIVATE_ARRAYS)
FindPrivateArrays(loopGraph, fullIR);
else if (curr_regime == TEST_PASS)
{
//test pass
@@ -1041,7 +1041,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
PRIVATE_ARRAYS_EXPANSION,
PRIVATE_ARRAYS_SHRINKING,
REMOVE_DEAD_CODE,
SWAP_OPERATORS };
MOVE_OPERATORS };
if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end())
{
@@ -1893,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());
@@ -1920,6 +1920,11 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
}
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.;
@@ -2338,7 +2343,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case INSERT_NO_DISTR_FLAGS_FROM_GUI:
case PRIVATE_REMOVING:
case RENAME_INLCUDES:
case SWAP_OPERATORS:
case MOVE_OPERATORS:
runAnalysis(*project, curr_regime, true, "", folderName);
break;
case INLINE_PROCEDURES:
@@ -2378,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
@@ -2518,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++;
@@ -2639,7 +2645,7 @@ 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;

View File

@@ -122,7 +122,7 @@ enum passes {
CREATE_INTER_TREE,
INSERT_INTER_TREE,
SWAP_OPERATORS,
MOVE_OPERATORS,
SHADOW_GROUPING,
INLINE_PROCEDURES,
@@ -185,9 +185,11 @@ enum passes {
SET_IMPLICIT_NONE,
RENAME_INLCUDES,
FIND_PRIVATE_ARRAYS_ANALYSIS,
FIND_PRIVATE_ARRAYS,
TRANSFORM_ASSUMED_SIZE_PARAMETERS,
ARRAY_PROPAGATION,
TEST_PASS,
EMPTY_PASS
@@ -321,7 +323,7 @@ static void setPassValues()
passNames[CHECK_PAR_REG_DIR] = "CHECK_PAR_REG_DIR";
passNames[CREATE_INTER_TREE] = "CREATE_INTER_TREE";
passNames[INSERT_INTER_TREE] = "INSERT_INTER_TREE";
passNames[SWAP_OPERATORS] = "SWAP_OPERATORS";
passNames[MOVE_OPERATORS] = "MOVE_OPERATORS";
passNames[CREATE_PARALLEL_REGIONS] = "CREATE_PARALLEL_REGIONS";
passNames[PRIVATE_REMOVING_ANALYSIS] = "PRIVATE_REMOVING_ANALYSIS";
passNames[PRIVATE_REMOVING] = "PRIVATE_REMOVING";
@@ -374,9 +376,11 @@ 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_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,6 +175,11 @@ 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;

View File

@@ -12,6 +12,7 @@ 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

@@ -1089,6 +1089,8 @@ static int clean(const string& funcName, SgStatement* funcSt, const map<string,
}
SgGotoStmt* gotoSt = new SgGotoStmt(*contLab);
if (st->label())
gotoSt->setLabel(*st->label());
st->insertStmtBefore(*gotoSt, *st->controlParent());
toDelete.push_back(st);

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,15 +491,17 @@ 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,
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,14 +799,12 @@ 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,
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)
@@ -825,11 +812,13 @@ void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, d
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,8 +847,7 @@ void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, d
}
}
void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBlocks,
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)
{
@@ -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

@@ -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,626 @@
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#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;
set<int> loop_tags = {FOR_NODE};
set<int> control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE};
set<int> control_end_tags = {CONTROL_END};
static vector<SAPFOR::IR_Block*> findInstructionsFromStatement(SgStatement* st, const vector<SAPFOR::BasicBlock*>& blocks)
{
vector<SAPFOR::IR_Block*> result;
if (!st)
return result;
const int stmtId = st->id();
for (auto* bb : blocks)
{
if (!bb)
continue;
for (auto* ir : bb->getInstructions())
{
if (!ir || !ir->getInstruction())
continue;
SgStatement* op = ir->getInstruction()->getOperator();
if (op && op->id() == stmtId)
result.push_back(ir);
}
}
sort(result.begin(), result.end(),
[](const SAPFOR::IR_Block* a, const SAPFOR::IR_Block* b) { return a->getNumber() < b->getNumber(); });
return result;
}
vector<SAPFOR::BasicBlock*> findFuncBlocksByFuncStatement(SgStatement *st, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) {
vector<SAPFOR::BasicBlock*> result;
if (!st)
return result;
Statement* forSt = (Statement*)st;
const string stmtFile = st->fileName();
const int stmtLine = st->lineNumber();
for (auto& func: FullIR) {
if (!func.first || !func.first->funcPointer)
continue;
const string funcFile = func.first->fileName;
const int funcLine = func.first->funcPointer->lineNumber();
// Important: select CFG blocks only for the same file and function header.
if (funcFile == stmtFile && funcLine == stmtLine)
{
result = func.second;
break;
}
}
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();
set<int> blocks_nums;
while (loopBody && loopBody != lastLoopNode) {
vector<SAPFOR::IR_Block*> irBlocks = findInstructionsFromStatement(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;
}
vector<SAPFOR::BasicBlock*> findBlocksInLoopsByFullIR(
SgStatement* funcStmt,
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
{
vector<SAPFOR::BasicBlock*> result;
if (!funcStmt)
return result;
const vector<SAPFOR::BasicBlock*> funcBlocks = findFuncBlocksByFuncStatement(funcStmt, FullIR);
const auto loopsMapping = findAndAnalyzeLoops(funcStmt, funcBlocks);
set<SAPFOR::BasicBlock*> uniq;
for (const auto& kv : loopsMapping)
for (auto* bb : kv.second)
if (bb)
uniq.insert(bb);
result.assign(uniq.begin(), uniq.end());
sort(result.begin(), result.end(),
[](const SAPFOR::BasicBlock* a, const SAPFOR::BasicBlock* b)
{
if (!a || !b)
return a < b;
return a->getNumber() < b->getNumber();
});
return result;
}
static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencies(const SAPFOR::BasicBlock* bb)
{
map<SgStatement*, vector<SgStatement*>> result;
if (!bb)
return result;
auto isCompoundStmt = [](SgStatement* st) -> bool
{
if (!st)
return true;
const int v = st->variant();
return loop_tags.count(v) || control_tags.count(v) || control_end_tags.count(v);
};
auto isTrackable = [](const SAPFOR::Argument* a) -> bool
{
if (!a)
return false;
const auto t = a->getType();
return t == SAPFOR::CFG_ARG_TYPE::VAR || t == SAPFOR::CFG_ARG_TYPE::REG;
};
auto argKey = [&](const SAPFOR::Argument* a) -> string
{
if (!a)
return string();
return to_string((int)a->getType()) + "#" + to_string((int)a->getMemType()) + "#" + a->getValue();
};
auto memKeyFromInstr = [&](const SAPFOR::Instruction* instr) -> string
{
if (!instr)
return string();
SgExpression* ex = instr->getExpression();
if (!ex)
return string();
auto exprKey = [&](auto&& self, SgExpression* e) -> string
{
if (!e)
return string("_");
if (auto* ar = isSgArrayRefExp(e))
{
SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr;
string key = string("A(") + (sym ? sym->identifier() : "?");
const int n = ar->numberOfSubscripts();
for (int i = 0; i < n; ++i)
{
key += ",";
key += self(self, ar->subscript(i));
}
key += ")";
return key;
}
if (e->variant() == VAR_REF || e->variant() == CONST_REF)
{
SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr;
return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")";
}
if (auto* v = isSgValueExp(e))
{
if (e->variant() == INT_VAL)
return string("I(") + to_string(v->intValue()) + ")";
if (e->variant() == BOOL_VAL)
return string("B(") + (v->boolValue() ? "1" : "0") + ")";
if (e->variant() == CHAR_VAL)
return string("CH(") + string(1, v->charValue()) + ")";
if (e->variant() == FLOAT_VAL)
return string("F(") + (v->floatValue() ? v->floatValue() : "") + ")";
if (e->variant() == DOUBLE_VAL)
return string("D(") + (v->doubleValue() ? v->doubleValue() : "") + ")";
if (e->variant() == STRING_VAL)
return string("S(") + (v->stringValue() ? v->stringValue() : "") + ")";
}
string key = string("N(") + to_string(e->variant());
if (e->lhs())
key += ",L=" + self(self, e->lhs());
if (e->rhs())
key += ",R=" + self(self, e->rhs());
key += ")";
return key;
};
return "MEMEX#" + exprKey(exprKey, ex);
};
auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool
{
if (!instr)
return true;
const auto op = instr->getOperation();
switch (op)
{
case SAPFOR::CFG_OP::F_CALL:
case SAPFOR::CFG_OP::IO_PARAM:
case SAPFOR::CFG_OP::DVM_DIR:
case SAPFOR::CFG_OP::SPF_DIR:
case SAPFOR::CFG_OP::POINTER_ASS:
case SAPFOR::CFG_OP::EXIT:
return true;
default:
return false;
}
};
auto isDef = [&](const SAPFOR::Instruction* instr) -> bool
{
if (!instr)
return false;
SAPFOR::Argument* r = instr->getResult();
if (!isTrackable(r))
return false;
const auto op = instr->getOperation();
if (op == SAPFOR::CFG_OP::STORE || op == SAPFOR::CFG_OP::REC_REF_STORE)
return false;
return true;
};
// Reaching definitions inside the BasicBlock in straight-line order:
// lastDef[var] = last operator in this block that defined it.
map<string, pair<SgStatement*, const SAPFOR::Argument*>> lastDef;
map<string, pair<SgStatement*, const SAPFOR::Argument*>> lastMemDef;
map<SgStatement*, set<SgStatement*>> depsSets;
for (auto* ir : bb->getInstructions())
{
if (!ir || !ir->getInstruction())
continue;
const SAPFOR::Instruction* instr = ir->getInstruction();
SgStatement* opStmt = instr->getOperator();
if (!opStmt)
continue;
if (isCompoundStmt(opStmt))
continue;
if (isBarrier(instr))
{
for (auto it = lastDef.begin(); it != lastDef.end();)
{
const SAPFOR::Argument* a = it->second.second;
if (!a || a->isMemGlobal() || a->isParameter())
it = lastDef.erase(it);
else
++it;
}
for (auto it = lastMemDef.begin(); it != lastMemDef.end();)
{
const SAPFOR::Argument* a = it->second.second;
if (!a || a->isMemGlobal() || a->isParameter())
it = lastMemDef.erase(it);
else
++it;
}
}
if (!result.count(opStmt))
result[opStmt] = {};
auto addDep = [&](SAPFOR::Argument* use)
{
if (!isTrackable(use))
return;
const string k = argKey(use);
auto it = lastDef.find(k);
if (it == lastDef.end())
return;
if (it->second.first && it->second.first != opStmt)
depsSets[opStmt].insert(it->second.first);
};
auto addMemDep = [&](const string& key)
{
if (key.empty())
return;
auto it = lastMemDef.find(key);
if (it == lastMemDef.end())
return;
if (it->second.first && it->second.first != opStmt)
depsSets[opStmt].insert(it->second.first);
};
addDep(instr->getArg1());
addDep(instr->getArg2());
if (instr->getOperation() == SAPFOR::CFG_OP::RANGE)
addDep(instr->getResult());
if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)
addDep(instr->getResult());
if (instr->getOperation() == SAPFOR::CFG_OP::LOAD || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD)
{
const string memKey = memKeyFromInstr(instr);
addMemDep(memKey);
}
if (isDef(instr))
{
const string dk = argKey(instr->getResult());
lastDef[dk] = { opStmt, instr->getResult() };
}
if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)
{
const string k = memKeyFromInstr(instr);
SAPFOR::Argument* base = instr->getArg1();
if (!k.empty() && base)
lastMemDef[k] = { opStmt, base };
addMemDep(k);
}
}
for (auto& kv : result)
{
SgStatement* op = kv.first;
auto it = depsSets.find(op);
if (it == depsSets.end())
continue;
kv.second.assign(it->second.begin(), it->second.end());
sort(kv.second.begin(), kv.second.end(),
[](SgStatement* a, SgStatement* b)
{
const int la = a ? a->lineNumber() : -1;
const int lb = b ? b->lineNumber() : -1;
if (la != lb)
return la < lb;
return a < b;
});
}
return result;
}
static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const char* expectedFile)
{
if (!bb)
return false;
auto isCompoundStmt = [](SgStatement* st) -> bool
{
if (!st)
return true;
const int v = st->variant();
return loop_tags.count(v) || control_tags.count(v) || control_end_tags.count(v);
};
vector<SgStatement*> ops;
ops.reserve(bb->getInstructions().size());
set<SgStatement*> seen;
for (auto* ir : bb->getInstructions())
{
if (!ir || !ir->getInstruction())
continue;
SgStatement* st = ir->getInstruction()->getOperator();
if (!st || isCompoundStmt(st))
continue;
if (seen.insert(st).second)
ops.push_back(st);
}
if (ops.size() < 2)
return false;
// Check that analyzed BB is in the same file as the expected file
const char* bbFile = ops.front()->fileName();
if (!bbFile)
bbFile = "(unknown)";
if (expectedFile && strcmp(expectedFile, bbFile) != 0)
return false;
for (auto* st : ops)
{
if (!st || !st->fileName() || strcmp(st->fileName(), bbFile) != 0)
return false;
}
SgStatement* parent = ops.front()->controlParent();
if (!parent)
return false;
for (auto* st : ops)
if (!st || st->controlParent() != parent)
return false;
set<SgStatement*> opSet(ops.begin(), ops.end());
{
SgStatement* lastNode = parent->lastNodeOfStmt();
SgStatement* cur = ops.front();
size_t idx = 0;
{
SgStatement* scan = parent->lexNext();
SgStatement* end = lastNode;
bool found = false;
set<SgStatement*> visited;
while (scan && scan != end)
{
if (!visited.insert(scan).second)
return false;
if (scan == ops.front())
{
found = true;
break;
}
scan = scan->lexNext();
}
if (!found)
return false;
}
while (cur && cur != lastNode && idx < ops.size())
{
if (cur == ops[idx])
++idx;
else if (isSgExecutableStatement(cur) && !opSet.count(cur))
return false;
if (idx == ops.size())
break;
cur = cur->lexNext();
}
if (idx != ops.size())
return false;
}
// Compute dependencies (inside BB) and build a new order by moving each statement
// as close as possible after its last dependency (if any).
const auto depsMap = analyzeBasicBlockIntraDependencies(bb);
vector<SgStatement*> order = ops;
const vector<SgStatement*> originalOrder = ops;
const int nOrig = (int)originalOrder.size();
auto indexIn = [](const vector<SgStatement*>& v, SgStatement* s) -> int
{
for (int i = 0; i < (int)v.size(); ++i)
if (v[i] == s)
return i;
return -1;
};
auto indexInOriginal = [&](SgStatement* s) -> int
{
return indexIn(originalOrder, s);
};
for (SgStatement* s : ops)
{
auto itDeps = depsMap.find(s);
if (itDeps == depsMap.end() || itDeps->second.empty())
continue;
int lastDepOrigIdx = -1;
for (SgStatement* dep : itDeps->second)
{
const int j = indexInOriginal(dep);
if (j >= 0)
lastDepOrigIdx = max(lastDepOrigIdx, j);
}
if (lastDepOrigIdx < 0)
continue;
SgStatement* successor = nullptr;
if (lastDepOrigIdx + 1 < nOrig)
successor = originalOrder[lastDepOrigIdx + 1];
int posS = indexIn(order, s);
if (posS < 0)
continue;
if (successor == nullptr)
{
if (posS == (int)order.size() - 1)
continue;
order.erase(order.begin() + posS);
order.push_back(s);
continue;
}
if (successor == s)
continue;
const int posSucc = indexIn(order, successor);
if (posSucc < 0)
continue;
if (posS + 1 == posSucc)
continue;
order.erase(order.begin() + posS);
const int posSucc2 = indexIn(order, successor);
if (posSucc2 < 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
order.insert(order.begin() + posSucc2, s);
}
bool changed = false;
for (size_t i = 0; i < ops.size(); ++i)
if (ops[i] != order[i])
{
changed = true;
break;
}
if (!changed)
return false;
SgStatement* anchor = parent;
{
SgStatement* scan = parent->lexNext();
SgStatement* end = parent->lastNodeOfStmt();
while (scan && scan != end)
{
if (scan == ops.front())
break;
anchor = scan;
scan = scan->lexNext();
}
}
// apply AST reordering
map<SgStatement*, int> savedLine;
map<SgStatement*, char*> savedComments;
map<SgStatement*, SgStatement*> extracted;
for (SgStatement* st : ops)
{
if (!st)
return false;
savedLine[st] = st->lineNumber();
savedComments[st] = st->comments() ? strdup(st->comments()) : nullptr;
SgStatement* ex = st->extractStmt();
if (!ex)
return false;
extracted[st] = ex;
}
SgStatement* insertAfter = anchor;
for (SgStatement* st : order)
{
SgStatement* ex = extracted[st];
if (!ex)
continue;
auto itC = savedComments.find(st);
if (itC != savedComments.end() && itC->second)
ex->setComments(itC->second);
auto itL = savedLine.find(st);
if (itL != savedLine.end())
ex->setlineNumber(itL->second);
insertAfter->insertStmtAfter(*ex, *parent);
insertAfter = ex;
}
for (auto& kv : savedComments)
if (kv.second)
free(kv.second);
return true;
}
void moveOperators(SgFile* file, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform) {
if (!file)
return;
if (SgFile::switchToFile(file->filename()) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i)
{
SgStatement* st = file->functions(i);
const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR);
for (auto* bb : loopBlocks)
{
if (!bb)
continue;
if (reorderOperatorsInBasicBlockUsingDeps(bb, file->filename()))
countOfTransform += 1;
}
}
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "../../GraphLoop/graph_loops.h"
#include "../../CFGraph/CFGraph.h"
void moveOperators(SgFile* file, 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

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

View File

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

View File

@@ -206,20 +206,20 @@ 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);
Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE);
list({BUILD_IR, CALL_GRAPH2}) <= Pass(SWAP_OPERATORS);
list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS);
list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING);
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 });
@@ -229,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);
@@ -318,7 +318,10 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE);
list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS);
list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS);
list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS);
list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS);
passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS,
EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,

View File

@@ -577,10 +577,20 @@ string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const ch
for (auto& incl : inclByPos.second)
inlcude += (renameIncludes ? renameInclude(incl) : incl);
if (st->comments())
st->setComments((inlcude + st->comments()).c_str());
//check inserted operators
SgStatement* toInsert = st;
do {
auto lexPrev = toInsert->lexPrev();
if (lexPrev && lexPrev->variant() > 0 && lexPrev->lineNumber() < 0)
toInsert = lexPrev;
else
st->addComment(inlcude.c_str());
break;
} while (true);
if (toInsert->comments())
toInsert->setComments((inlcude + toInsert->comments()).c_str());
else
toInsert->addComment(inlcude.c_str());
}
}
@@ -934,8 +944,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());
}
}
}
}
}
@@ -954,8 +970,20 @@ DIST::Array* getArrayFromDeclarated(SgStatement *st, const string &arrayName)
{
auto itD = declaredArrays.find(*itSet);
if (itD != declaredArrays.end())
if (itD->second.first->GetShortName() == arrayName)
found = itD->second.first;
{
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 +1292,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 +1326,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 +1362,7 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
if (foundCommon)
{
inCommon = true;
symbCommn = getCommonNameOnPos(common.first, commonPos);
break;
}
}
@@ -1314,7 +1370,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,11 +354,21 @@ 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->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;
}
}
}
SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const string& locName)
{
@@ -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

@@ -569,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

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

View File

@@ -152,7 +152,7 @@ static void setOptions(const short* options, bool isBuildParallel = false, const
intOptions[z] = -1;
}
staticShadowAnalysis = intOptions[STATIC_SHADOW_ANALYSIS];
//staticShadowAnalysis = intOptions[STATIC_SHADOW_ANALYSIS];
staticPrivateAnalysis = intOptions[STATIC_PRIVATE_ANALYSIS];
out_free_form = intOptions[FREE_FORM];
if (out_free_form == 1)
@@ -1793,6 +1793,22 @@ int SPF_RenameIncludes(void*& context, int winHandler, short* options, short* pr
return simpleTransformPass(RENAME_INLCUDES, options, projName, folderName, output, outputMessage);
}
int SPF_InsertPrivateArrayDirectives(void*& context, int winHandler, short* options, short* projName, short* folderName, string& output, string& outputMessage)
{
MessageManager::clearCache();
MessageManager::setWinHandler(winHandler);
ignoreArrayDistributeState = true;
sharedMemoryParallelization = 1;
return simpleTransformPass(FIND_PRIVATE_ARRAYS, options, projName, folderName, output, outputMessage);
}
int SPF_MoveOperators(void*& context, int winHandler, short* options, short* projName, short* folderName, string& output, string& outputMessage)
{
MessageManager::clearCache();
MessageManager::setWinHandler(winHandler);
return simpleTransformPass(MOVE_OPERATORS, options, projName, folderName, output, outputMessage);
}
static inline void convertBackSlash(char *str, int strL)
{
for (int z = 0; z < strL; ++z)
@@ -2499,6 +2515,10 @@ const wstring Sapfor_RunTransformation(const char* transformName_c, const char*
retCode = SPF_InsertImplicitNone(context, winHandler, optSh, projSh, fold, output, outputMessage);
else if (whichRun == "SPF_RenameIncludes")
retCode = SPF_RenameIncludes(context, winHandler, optSh, projSh, fold, output, outputMessage);
else if (whichRun == "SPF_InsertPrivateArrayDirectives")
retCode = SPF_InsertPrivateArrayDirectives(context, winHandler, optSh, projSh, fold, output, outputMessage);
else if (whichRun == "SPF_MoveOperators")
retCode = SPF_MoveOperators(context, winHandler, optSh, projSh, fold, output, outputMessage);
else if (whichRun == "SPF_CreateParallelVariant")
{
vector<string> splited;