38 Commits

Author SHA1 Message Date
Egor Mayorov
aa6608e7d3 attempt to build new ast 2025-10-08 23:14:19 +03:00
ALEXks
3fa3299b06 version updated 2025-10-08 23:07:54 +03:00
641e68d748 REMOVE_DIST_ARRAYS_FROM_IO: consider write/read statements with nested loops 2025-10-08 23:07:54 +03:00
afc88bf056 REMOVE_DIST_ARRAYS_FROM_IO: use more general isSgVarListDeclStmt and isSgNestedVarListDeclStmt functions 2025-10-08 23:07:54 +03:00
d6d16fed2d REMOVE_DIST_ARRAYS_FROM_IO: consider labels and goto statements while inserting copy statements 2025-10-08 23:07:54 +03:00
2f0fecd14d REMOVE_DIST_ARRAYS_FROM_IO: consider array declarations from common blocks and dimension statements 2025-10-08 23:07:54 +03:00
f5b5aba32f cmake: change default optimization level to O3 2025-10-08 23:07:54 +03:00
50b4965354 cmake: set -O2 optimization level only if CMAKE_BUILD_TYPE is not specified 2025-10-08 23:07:54 +03:00
ALEXks
864ef699b7 refactored 2025-10-08 23:07:54 +03:00
ALEXks
09c343a71f cleanup 2025-10-08 23:07:54 +03:00
ALEXks
593c6e928c added json to global results 2025-10-08 23:07:54 +03:00
ALEXks
e9166d8c99 trivial, version updated 2025-10-08 23:07:54 +03:00
657175a728 REMOVE_DIST_ARRAYS_FROM_IO: revert hotfix for issue with generated intent statements 2025-10-08 23:07:54 +03:00
99b884b221 REMOVE_DIST_ARRAYS_FROM_IO: regard generated intent statements, carefully detect assumed-shape arrays 2025-10-08 23:07:54 +03:00
55ccd825c7 REMOVE_DIST_ARRAYS_FROM_IO: do not process arrays from headers, copy from correct declarations, improve style 2025-10-08 23:07:54 +03:00
93a9ccf902 REMOVE_DIST_ARRAYS_FROM_IO: remove debug prints 2025-10-08 23:07:54 +03:00
3c119c884b REMOVE_DIST_ARRAYS_FROM_IO: handle assumed-size and assumed-shape arrays 2025-10-08 23:07:54 +03:00
ALEXks
dc7555c052 dvm updated 2025-10-08 23:07:54 +03:00
ALEXks
b7b17368a3 changed line numbers to negative for INTENT and INTRINSIC 2025-10-08 23:07:54 +03:00
ALEXks
5998ca49b1 updated dvm for SAPFOR 2025-10-08 23:07:54 +03:00
ALEXks
fff3467f56 fixed DIST::IO_PRIV detection 2025-10-08 23:07:54 +03:00
ALEXks
d9a2fce7ab fixed expression calculation, fixed addArg 2025-10-08 23:07:54 +03:00
ALEXks
da51f8484c fixed replace_dist_array pass: added more file switching 2025-10-08 23:07:54 +03:00
ALEXks
c61e18a044 fixed region inserter 2025-10-08 23:07:54 +03:00
ALEXks
27b7ea965e fixed transformation 2025-10-08 23:07:54 +03:00
ALEXks
d110be6d01 added TRANSFORM_ASSUMED_SIZE_PARAMETERS pass, fixed shared memory parallelization 2025-10-08 23:07:54 +03:00
ALEXks
c567cb0a42 improved cmake 2025-10-08 23:07:54 +03:00
b298cc03bf moved to transformations 2025-07-09 14:46:38 +03:00
Egor Mayorov
8c6a55463c swap operators in AST 2025-07-09 14:46:38 +03:00
Egor Mayorov
32a4a7fd0a Use more complex algorythm for building new order of statements 2025-07-09 14:46:38 +03:00
Egor Mayorov
507305ac3a update in new order 2025-07-09 14:46:38 +03:00
Egor Mayorov
a3939ed274 biulding new order 2025-07-09 14:46:38 +03:00
Egor Mayorov
95ef954b6e some loop analysis done 2025-07-09 14:46:38 +03:00
Egor Mayorov
243b1f5bdb Add _bin to gitignore 2025-07-09 14:46:38 +03:00
Egor Mayorov
5fb2bd79df Some actions simplify analyzing IR 2025-07-09 14:46:37 +03:00
Egor Mayorov
d33659290e Pass with output file added 2025-07-09 14:46:37 +03:00
Egor Mayorov
b8a6c92ca8 change pass deps 2025-07-09 14:46:37 +03:00
Egor Mayorov
1028e20177 New pass 2025-07-09 14:46:37 +03:00
56 changed files with 889 additions and 3136 deletions

View File

@@ -161,15 +161,7 @@ set(PARALLEL_REG src/ParallelizationRegions/ParRegions.cpp
src/ParallelizationRegions/expand_extract_reg.cpp src/ParallelizationRegions/expand_extract_reg.cpp
src/ParallelizationRegions/expand_extract_reg.h src/ParallelizationRegions/expand_extract_reg.h
src/ParallelizationRegions/resolve_par_reg_conflicts.cpp src/ParallelizationRegions/resolve_par_reg_conflicts.cpp
src/ParallelizationRegions/resolve_par_reg_conflicts.h src/ParallelizationRegions/resolve_par_reg_conflicts.h)
src/ParallelizationRegions/uniq_name_creator.cpp
src/ParallelizationRegions/uniq_name_creator.h)
set(ARRAY_PROP src/ArrayConstantPropagation/propagation.cpp
src/ArrayConstantPropagation/propagation.h
)
set(MERGE_REGIONS src/ParallelizationRegions/merge_regions.cpp
src/ParallelizationRegions/merge_regions.h)
set(TR_DEAD_CODE src/Transformations/DeadCodeRemoving/dead_code.cpp set(TR_DEAD_CODE src/Transformations/DeadCodeRemoving/dead_code.cpp
src/Transformations/DeadCodeRemoving/dead_code.h) src/Transformations/DeadCodeRemoving/dead_code.h)
@@ -211,9 +203,9 @@ set(TR_EXPR_TRANSFORM src/Transformations/ExpressionSubstitution/control_flow_gr
set(TR_INLINER src/Transformations/FunctionInlining/inliner.cpp set(TR_INLINER src/Transformations/FunctionInlining/inliner.cpp
src/Transformations/FunctionInlining/inliner.h) src/Transformations/FunctionInlining/inliner.h)
set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp
src/Transformations/RenameSymbols/rename_symbols.h) src/Transformations/RenameSymbols/rename_symbols.h)
SET(TR_MOVE_OPERATORS src/Transformations/MoveOperators/move_operators.cpp SET(TR_SWAP_OPERATORS src/Transformations/SwapOperators/swap_operators.cpp
src/Transformations/MoveOperators/move_operators.h) src/Transformations/SwapOperators/swap_operators.h)
set(TRANSFORMS set(TRANSFORMS
${TR_DEAD_CODE} ${TR_DEAD_CODE}
@@ -237,7 +229,7 @@ set(TRANSFORMS
${TR_EXPR_TRANSFORM} ${TR_EXPR_TRANSFORM}
${TR_INLINER} ${TR_INLINER}
${TR_RENAME_SYMBOLS} ${TR_RENAME_SYMBOLS}
${TR_MOVE_OPERATORS}) ${TR_SWAP_OPERATORS})
set(CFG src/CFGraph/IR.cpp set(CFG src/CFGraph/IR.cpp
src/CFGraph/IR.h src/CFGraph/IR.h
@@ -430,9 +422,7 @@ set(SOURCE_EXE
${LOOP_ANALYZER} ${LOOP_ANALYZER}
${TRANSFORMS} ${TRANSFORMS}
${PARALLEL_REG} ${PARALLEL_REG}
${MERGE_REGIONS}
${PRIV} ${PRIV}
${ARRAY_PROP}
${FDVM} ${FDVM}
${OMEGA} ${OMEGA}
${UTILS} ${UTILS}
@@ -472,7 +462,7 @@ source_group (Transformations\\GlobalVariables FILES ${TR_GV})
source_group (Transformations\\ConvertToC FILES ${TR_CONV}) source_group (Transformations\\ConvertToC FILES ${TR_CONV})
source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE}) source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE})
source_group (Transformations\\ReplaceArraysInIO FILES ${TR_REPLACE_ARRAYS_IN_IO}) source_group (Transformations\\ReplaceArraysInIO FILES ${TR_REPLACE_ARRAYS_IN_IO})
source_group (Transformations\\MoveOperators FILES ${TR_MOVE_OPERATORS}) source_group (Transformations\\SwapOperators FILES ${TR_SWAP_OPERATORS})
source_group (CreateIntervals FILES ${CREATE_INTER_T}) source_group (CreateIntervals FILES ${CREATE_INTER_T})
@@ -484,9 +474,7 @@ source_group (GraphCall FILES ${GR_CALL})
source_group (GraphLoop FILES ${GR_LOOP}) source_group (GraphLoop FILES ${GR_LOOP})
source_group (LoopAnalyzer FILES ${LOOP_ANALYZER}) source_group (LoopAnalyzer FILES ${LOOP_ANALYZER})
source_group (ParallelizationRegions FILES ${PARALLEL_REG}) source_group (ParallelizationRegions FILES ${PARALLEL_REG})
source_group (MergeRegions FILES ${MERGE_REGIONS})
source_group (PrivateAnalyzer FILES ${PRIV}) source_group (PrivateAnalyzer FILES ${PRIV})
source_group (ArrayConstantPropagation FILES ${ARRAY_PROP})
source_group (FDVM_Compiler FILES ${FDVM}) source_group (FDVM_Compiler FILES ${FDVM})
source_group (SageExtension FILES ${OMEGA}) source_group (SageExtension FILES ${OMEGA})
source_group (Utils FILES ${UTILS}) source_group (Utils FILES ${UTILS})

View File

@@ -1,380 +0,0 @@
#include "propagation.h"
#include "../Utils/SgUtils.h"
#include <iostream>
#include <functional>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
namespace {
struct MyHash {
size_t operator()(const SgSymbol* s) const {
return std::hash<std::string_view>{}(s->identifier());
}
};
struct MyEq {
bool operator()(const SgSymbol* a, const SgSymbol* b) const {
return std::strcmp(a->identifier(), b->identifier()) == 0;
}
};
}
SgStatement* declPlace = NULL;
unordered_set<SgStatement*> changed;
unordered_set<SgSymbol*, MyHash, MyEq> variablesToAdd;
unordered_set<SgStatement*> positionsToAdd;
unordered_set<SgStatement*> statementsToRemove;
unordered_map<string, vector<pair<SgStatement*, SgStatement*>>> expToChange;
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++;
SgStatement* funcStart = declPlace->controlParent();
SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *funcStart);
variablesToAdd.insert(varSymbol);
positionsToAdd.insert(declPlace);
return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr());
}
static SgStatement* FindLastDeclStatement(SgStatement* funcStart)
{
SgStatement* endSt = funcStart->lastNodeOfStmt();
SgStatement* cur = funcStart->lexNext();
SgStatement* lastDecl = funcStart;
const set<int> declVariants = { VAR_DECL, VAR_DECL_90, ALLOCATABLE_STMT, DIM_STAT,
EXTERN_STAT, COMM_STAT, HPF_TEMPLATE_STAT, DVM_VAR_DECL, STRUCT_DECL };
while (cur && cur != endSt)
{
if (cur->variant() == INTERFACE_STMT)
cur = cur->lastNodeOfStmt();
if (declVariants.find(cur->variant()) != declVariants.end())
lastDecl = cur;
else if (isSgExecutableStatement(cur))
break;
cur = cur->lexNext();
}
return lastDecl;
}
static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unordered_set<SgSymbol*, MyHash, MyEq>& symbols)
{
if (symbols.empty())
return;
const string commonBlockName = "__propagation_common__";
SgStatement* funcEnd = funcStart->lastNodeOfStmt();
SgStatement* commonStat = NULL;
SgExpression* commonList = NULL;
for (SgStatement* cur = funcStart->lexNext();
cur && cur != funcEnd; cur = cur->lexNext())
{
if (cur->variant() != COMM_STAT)
continue;
for (SgExpression* exp = cur->expr(0); exp; exp = exp->rhs())
{
if (exp->variant() != COMM_LIST)
continue;
const char* id = exp->symbol() ? exp->symbol()->identifier() : NULL;
string existingName = id ? string(id) : string("spf_unnamed");
if (existingName == commonBlockName)
{
commonStat = cur;
commonList = exp;
break;
}
}
if (commonStat)
break;
}
vector<SgExpression*> varRefs;
for (SgSymbol* sym : symbols)
{
if (!sym || sym->variant() != VARIABLE_NAME || string(sym->identifier()) == commonBlockName)
continue;
SgSymbol* symToAdd = new SgSymbol(VARIABLE_NAME, sym->identifier(), *sym->type(), *funcStart);
varRefs.push_back(new SgVarRefExp(symToAdd));
}
SgExpression* varList = makeExprList(varRefs, false);
SgStatement* insertAfter = FindLastDeclStatement(funcStart);
for (SgSymbol* sym : symbols)
{
SgStatement* declStmt = sym->makeVarDeclStmt();
if (!declStmt)
continue;
if (SgVarDeclStmt* vds = isSgVarDeclStmt(declStmt))
vds->setVariant(VAR_DECL_90);
declStmt->setFileName(funcStart->fileName());
declStmt->setFileId(funcStart->getFileId());
declStmt->setProject(funcStart->getProject());
declStmt->setlineNumber(getNextNegativeLineNumber());
insertAfter->insertStmtAfter(*declStmt, *funcStart);
insertAfter = declStmt;
statementsToRemove.insert(declStmt);
}
if (!commonList)
{
SgSymbol* commonSymbol = new SgSymbol(COMMON_NAME, commonBlockName.c_str());
commonList = new SgExpression(COMM_LIST, varList, NULL, commonSymbol);
commonStat = new SgStatement(COMM_STAT);
commonStat->setFileName(funcStart->fileName());
commonStat->setFileId(funcStart->getFileId());
commonStat->setProject(funcStart->getProject());
commonStat->setlineNumber(getNextNegativeLineNumber());
commonStat->setExpression(0, commonList);
SgStatement* lastDecl = FindLastDeclStatement(funcStart);
lastDecl->insertStmtAfter(*commonStat, *funcStart);
statementsToRemove.insert(commonStat);
}
else
{
commonList->setLhs(varList);
}
}
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()))
{
expUnparsed = exp->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType())
{
arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType());
}
positionsToAdd.insert(declPlace);
SgSymbol* builder = arrayToVariable[expUnparsed]->symbol();
auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent());
auto* newVarExp = new SgVarRefExp(sym);
expToChange[st->fileName()].push_back({ st , st->copyPtr() });
st->setExpression(1, newVarExp);
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());
positionsToAdd.insert(declPlace);
SgSymbol* builder = arrayToVariable[expUnparsed]->symbol();
auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent());
toAdd = new SgVarRefExp(sym);
if (toAdd)
{
if (i == 0)
{
expToChange[st->fileName()].push_back({ st , st->copyPtr() });;
exp->setLhs(toAdd);
}
else
{
expToChange[st->fileName()].push_back({ st , st->copyPtr() });;
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;
if (changed.find(st) != changed.end())
return;
string expUnparsed = exp->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType())
{
arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType());
}
positionsToAdd.insert(declPlace);
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());
changed.insert(st);
statementsToRemove.insert(newStatement);
}
static void TransformBorder(SgStatement* st, SgExpression* exp, unordered_map<string, SgExpression*>& arrayToVariable, int& variableNumber)
{
SgStatement* firstStatement = declPlace->lexPrev();
st = st->lexPrev();
string array = exp->unparse();
if (arrayToVariable.find(array) == arrayToVariable.end())
arrayToVariable[array] = CreateVar(variableNumber, exp->symbol()->type()->baseType());
while (st != firstStatement)
{
if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{
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()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber);
}
st = st->lexPrev();
}
}
static void CheckVariable(SgStatement* st, SgExpression* exp, unordered_map<string, SgExpression*>& arrayToVariable, int& variableNumber)
{
SgStatement* firstStatement = declPlace->lexPrev();
st = st->lexPrev();
string varName = exp->unparse();
while (st != firstStatement)
{
if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol())
{
TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber);
positionsToAdd.insert(declPlace);
}
if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{
if (st->expr(1))
{
TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber);
positionsToAdd.insert(declPlace);
}
if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{
TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber);
positionsToAdd.insert(declPlace);
}
}
st = st->lexPrev();
}
}
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;
SgFile::switchToFile(file->filename());
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() == FOR_NODE)
{
SgExpression* lowerBound = st->expr(0)->lhs();
SgExpression* upperBound = st->expr(0)->rhs();
SgStatement* boundCopy = NULL;
string lowerBoundUnparsed = lowerBound->unparse(), upperBoundUnparsed = upperBound->unparse();
if (upperBound->variant() == ARRAY_REF && upperBound->symbol()->type()->baseType() && CheckConstIndexes(upperBound->lhs()))
{
boundCopy = st->copyPtr();
TransformBorder(st, upperBound, arrayToVariable, variableNumber);
st->expr(0)->setRhs(arrayToVariable[upperBoundUnparsed]->copyPtr());
expToChange[st->fileName()].push_back({ st ,boundCopy });;
positionsToAdd.insert(declPlace);
}
else if (upperBound->variant() == VAR_REF)
CheckVariable(st, upperBound, arrayToVariable, variableNumber);
if (lowerBound->variant() == ARRAY_REF && lowerBound->symbol()->type()->baseType() && CheckConstIndexes(lowerBound->lhs()))
{
boundCopy = st->copyPtr();
TransformBorder(st, lowerBound, arrayToVariable, variableNumber);
st->expr(0)->setLhs(arrayToVariable[lowerBoundUnparsed]->copyPtr());
expToChange[st->fileName()].push_back({ st , boundCopy });;
positionsToAdd.insert(declPlace);
}
else if (lowerBound->variant() == VAR_REF)
CheckVariable(st, lowerBound, arrayToVariable, variableNumber);
}
}
}
}
unordered_set<SgStatement*> funcStarts;
for (SgStatement* st : positionsToAdd)
{
SgFile::switchToFile(st->fileName());
SgStatement* scope = st->controlParent();
if (scope)
funcStarts.insert(scope);
}
for (const auto& st : funcStarts)
{
SgFile::switchToFile(st->fileName());
InsertCommonAndDeclsForFunction(st, variablesToAdd);
}
}

View File

@@ -1,20 +0,0 @@
#pragma once
#include "../Utils/SgUtils.h"
#include <string>
#include <vector>
using namespace std;
struct ExprRestoreEntry
{
enum Kind { kStatementExpr, kExprChild };
Kind kind;
SgStatement* stmt;
int stmtExprIndex;
SgExpression* parent;
bool childIsRhs;
SgExpression* savedCopy;
};
void arrayConstantPropagation(SgProject& project);

View File

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

View File

@@ -105,52 +105,23 @@ namespace SAPFOR
struct CFG_Settings 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 atLeastOneIterInLoop = false;
bool withRD = false; bool withRD = true;
bool withRegisters = false; bool withRegisters = false;
bool withSPF = false; bool withSPF = false;
bool withDVM = false; bool withDVM = false;
bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock
bool withCallFrom = false; bool withCallFrom = true;
bool withDominators = false; bool withDominators = true;
bool withUnreachable = false;
explicit CFG_Settings(const std::set<setting> &settings = { CFG_withRD, CFG_withCallFrom, CFG_withDominators }) explicit CFG_Settings(int) { }
{
for (auto& set : settings) explicit CFG_Settings(bool atLeastOneIterInLoop = false, bool withRD = true, bool withRegisters = false,
{ bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false,
if (set == CFG_atLeastOneIterInLoop) bool withCallFrom = true, bool withDominators = true) :
atLeastOneIterInLoop = true; atLeastOneIterInLoop(atLeastOneIterInLoop), withRD(withRD), withRegisters(withRegisters), withDVM(withDVM), withSPF(withSPF),
else if (set == CFG_withRD) withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom), withDominators(withDominators)
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,46 +200,20 @@ static void fillOutForFunc(const FuncInfo* func, const vector<SAPFOR::BasicBlock
outForFunc[func->funcName] = { defined, common_defined }; outForFunc[func->funcName] = { defined, common_defined };
} }
static bool isInstructionSpfParameter(SAPFOR::Instruction* instr) static void getDefsFromBlock(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& res,
{
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 vector<pair<const Variable*, CommonBlock*>>& commonVars,
const FuncInfo* func) const FuncInfo* func)
{ {
vector<SAPFOR::Argument*> lastParamRef; vector<SAPFOR::Argument*> lastParamRef;
for (const auto &ir_block : block->getInstructions()) for (auto ir_block : block->getInstructions())
{ {
SAPFOR::Instruction* instr = ir_block->getInstruction(); SAPFOR::Instruction* instr = ir_block->getInstruction();
if (isInstructionSpfParameter(instr))
continue;
SAPFOR::CFG_OP instr_operation = instr->getOperation(); SAPFOR::CFG_OP instr_operation = instr->getOperation();
if (instr_operation == SAPFOR::CFG_OP::PARAM) if (instr_operation == SAPFOR::CFG_OP::PARAM)
{ {
SAPFOR::Argument* arg = instr->getArg1(); SAPFOR::Argument* arg = instr->getArg1();
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR) if(arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
addPlaceWithDef(commonVars, func, arg, instr); addPlaceWithDef(commonVars, func, arg, instr);
lastParamRef.push_back(arg); lastParamRef.push_back(arg);
@@ -262,20 +236,12 @@ static void getDefsFromBlock(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>&
int last_instr_num = block->getInstructions().back()->getNumber(); int last_instr_num = block->getInstructions().back()->getNumber();
for (const auto& def : block->getRD_Out()) for (const auto& def : block->getRD_Out())
{
for (int place : def.second) for (int place : def.second)
{
if (place >= first_instr_num && place <= last_instr_num && def.first->getType() == SAPFOR::CFG_ARG_TYPE::VAR) 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); res.insert(def.first);
addPlaceWithDef(commonVars, func, def.first, instr); addPlaceWithDef(commonVars, func, def.first, block->getInstructions()[place - first_instr_num]->getInstruction());
} }
}
}
} }
// recursively analyze FOR loops // recursively analyze FOR loops
@@ -300,7 +266,7 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
SAPFOR::BasicBlock* head_block = NULL; SAPFOR::BasicBlock* head_block = NULL;
int loop_start = loop->lineNum, loop_end = loop->lineNumAfterLoop; int loop_start = loop->lineNum, loop_end = loop->lineNumAfterLoop;
for (const auto &bb : blocks) for (auto bb : blocks)
{ {
if (!bb || (bb->getInstructions().size() == 0)) if (!bb || (bb->getInstructions().size() == 0))
continue; continue;
@@ -321,12 +287,6 @@ 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) if (!head_block)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -388,7 +348,7 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
getDefsFromBlock(*loop_it, changeValueOnExit, commonVars, func); getDefsFromBlock(*loop_it, changeValueOnExit, commonVars, func);
for (const auto &bb : currentLoop) for (auto bb : currentLoop)
{ {
//fill LiveWhenLoopEnds //fill LiveWhenLoopEnds
bool has_next_outside_body = false; bool has_next_outside_body = false;

View File

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

View File

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

View File

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

View File

@@ -336,24 +336,9 @@ namespace Distribution
if (pos != STRING::npos) if (pos != STRING::npos)
{ {
name.erase(pos, shortName.size()); name.erase(pos, shortName.size());
shortName = newName;
name += 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(); GenUniqKey();
} }
@@ -557,44 +542,6 @@ namespace Distribution
return NULL; 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; } Symbol* GetDeclSymbol() const { return declSymbol; }
void SetDeclSymbol(Symbol *s) { declSymbol = s; } 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) static DIST::Array* findBestInEqual(vector<DIST::Array*> &arrays, DIST::GraphCSR<int, double, attrType> &reducedG, DIST::Arrays<int> &allArrays)
{ {
DIST::Array *retVal = NULL; DIST::Array *retVal = NULL;
vector<vector<attrType>> coeffsByDims; vector<vector<attrType>> coefsByDims;
for (auto &array : arrays) for (auto &array : arrays)
{ {
vector<int> verts; vector<int> verts;
@@ -285,7 +285,7 @@ static DIST::Array* findBestInEqual(vector<DIST::Array*> &arrays, DIST::GraphCSR
{ {
retVal = array; retVal = array;
for (auto &V : verts) for (auto &V : verts)
coeffsByDims.push_back(reducedG.GetAllAttributes(V)); coefsByDims.push_back(reducedG.GetAllAttributes(V));
} }
else else
{ {
@@ -294,11 +294,11 @@ static DIST::Array* findBestInEqual(vector<DIST::Array*> &arrays, DIST::GraphCSR
toCmp.push_back(reducedG.GetAllAttributes(V)); toCmp.push_back(reducedG.GetAllAttributes(V));
for (int z = 0; z < toCmp.size(); ++z) for (int z = 0; z < toCmp.size(); ++z)
{ {
if (toCmp[z].size() && coeffsByDims[z].size()) if (toCmp[z].size() && coefsByDims[z].size())
{ {
if (toCmp[z].back().first.first > coeffsByDims[z].back().first.first) if (toCmp[z].back().first.first > coefsByDims[z].back().first.first)
{ {
coeffsByDims = toCmp; coefsByDims = toCmp;
retVal = array; retVal = array;
break; break;
} }

View File

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

View File

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

View File

@@ -1289,9 +1289,6 @@ static set<DIST::Array*>
SgStatement* declStat = NULL; SgStatement* declStat = NULL;
if (realArray->GetLocation().first == DIST::l_PARAMETER)
continue;
if (realArray->GetLocation().first == DIST::l_COMMON) if (realArray->GetLocation().first == DIST::l_COMMON)
{ {
commonArrays.insert(realArray); commonArrays.insert(realArray);

View File

@@ -723,7 +723,7 @@ static void fillIn(FuncInfo *currF, SgExpression *ex, const map<string, int> &pa
{ {
if (ex) if (ex)
{ {
if (!isInFuncPar && (ex->variant() == VAR_REF || ex->variant() == ARRAY_REF)) if (!isInFuncPar && (ex->variant() == VAR_REF || isArrayRef(ex)))
{ {
const char *name = ex->symbol()->identifier(); const char *name = ex->symbol()->identifier();
if (name && name != string("")) if (name && name != string(""))
@@ -800,58 +800,29 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co
static map<string, vector<int>> supportedKeyWordArg = { {"system_clock", { OUT_BIT, OUT_BIT, OUT_BIT } } }; static map<string, vector<int>> supportedKeyWordArg = { {"system_clock", { OUT_BIT, OUT_BIT, OUT_BIT } } };
map<string, int> parNamesMain; map<string, int> parNames;
map<string, int> parNamesContains;
for (int i = 0; i < currF->funcParams.identificators.size(); ++i) for (int i = 0; i < currF->funcParams.identificators.size(); ++i)
parNamesMain[currF->funcParams.identificators[i]] = i; parNames[currF->funcParams.identificators[i]] = i;
map<string, int>& parNames = parNamesMain;
bool isContainsFunctions = false;
for (auto st = start; st != last; st = st->lexNext()) for (auto st = start; st != last; st = st->lexNext())
{ {
if (st->variant() == CONTAINS_STMT) { if (st->variant() == CONTAINS_STMT)
isContainsFunctions = true; break;
continue;
}
if (isContainsFunctions) {
if (st->variant() == PROC_HEDR || st->variant() == FUNC_HEDR) {
parNamesContains = parNamesMain;
SgProgHedrStmt* hedr = (SgProgHedrStmt*)st;
int numOfParams = hedr->numberOfParameters();
if (numOfParams > 0)
{
for (int i = 0; i < numOfParams; ++i)
{
auto it = parNamesContains.find(hedr->parameter(i)->identifier());
if (it != parNamesContains.end())
parNamesContains.erase(it);
}
}
parNames = parNamesContains;
}
}
if (st->variant() == ENTRY_STAT) if (st->variant() == ENTRY_STAT)
continue; continue;
if (isSgExecutableStatement(st) == NULL) { if (isSgExecutableStatement(st) == NULL) {
if (!isContainsFunctions) checkInTypeDescription(st->expr(0), currF, parNames);
checkInTypeDescription(st->expr(0), currF, parNames);
continue; continue;
} }
if (st->lineNumber() <= 0) if (st->lineNumber() <= 0)
continue; continue;
//XXX: use parameters removing in block ... isContainsFunctions ... if (activeOps.size() && activeOps.find(st) == activeOps.end())
//TODO need to use IR for parameters checking continue;
/*if (activeOps.size() && activeOps.find(st) == activeOps.end())
continue; */
if (st->variant() == ASSIGN_STAT) if (st->variant() == ASSIGN_STAT)
{ {
@@ -880,7 +851,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co
for (auto ex = read->itemList(); ex; ex = ex->rhs()) for (auto ex = read->itemList(); ex; ex = ex->rhs())
{ {
SgExpression* item = ex->lhs(); SgExpression* item = ex->lhs();
if (item && (item->variant() == VAR_REF || item->variant() == ARRAY_REF)) if (item->variant() == VAR_REF || isArrayRef(item))
{ {
string symb = ""; string symb = "";
if (item->symbol()) if (item->symbol())
@@ -901,7 +872,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co
if (item->rhs()) if (item->rhs())
queue.push(item->rhs()); queue.push(item->rhs());
if (item->variant() == VAR_REF || item->variant() == ARRAY_REF) if (item->variant() == VAR_REF || isArrayRef(item))
{ {
string symb = ""; string symb = "";
if (item->symbol()) if (item->symbol())

View File

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

View File

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

View File

@@ -24,7 +24,6 @@ using std::make_pair;
using std::map; using std::map;
using std::set; using std::set;
using std::wstring; using std::wstring;
using std::tuple;
extern void createMapLoopGraph(map<int, LoopGraph*> &sortedLoopGraph, const vector<LoopGraph*> *loopGraph); extern void createMapLoopGraph(map<int, LoopGraph*> &sortedLoopGraph, const vector<LoopGraph*> *loopGraph);
@@ -955,65 +954,4 @@ void calculateLinesOfCode(vector<ParallelRegion*> &allRegions)
__spf_print(1, " Count of lines in region '%s' = %d\n", elem->GetName().c_str(), lineCounter); __spf_print(1, " Count of lines in region '%s' = %d\n", elem->GetName().c_str(), lineCounter);
} }
}
void propagateRegionInfo(map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const vector<ParallelRegion*> &parallelRegions)
{
bool modified = true;
while (modified)
{
modified = false;
for (auto &array_pair: declaredArrays)
{
auto array = array_pair.second.first;
if (array->GetLocation().first == DIST::l_PARAMETER)
{
set<DIST::Array*> realArrayRef;
getAllArrayRefs(array, array, realArrayRef, arrayLinksByFuncCalls);
auto regs = array->GetRegionsName();
for (auto& ref : realArrayRef)
{
auto regsRef = ref->GetRegionsName();
for (auto& reg : regsRef)
{
if (regs.count(reg) == 0)
{
array->SetRegionPlace(reg);
modified = true;
}
}
}
}
}
}
bool hasNonDefaultReg = false;
for (auto& elem : parallelRegions)
{
string regName = elem->GetName();
convertToLower(regName);
if (regName != "default")
hasNonDefaultReg = true;
}
if (hasNonDefaultReg)
{
for (auto array : declaredArrays)
{
if (array.second.first->GetRegionsName().size() == 0)
array.second.first->SetDistributeFlag(DIST::NO_DISTR);
else if (array.second.first->GetRegionsName().size() == 1)
{
string regName = *array.second.first->GetRegionsName().begin();
convertToLower(regName);
if (regName == "default")
array.second.first->SetDistributeFlag(DIST::NO_DISTR);
}
}
}
} }

View File

@@ -10,7 +10,3 @@ int printParalleRegions(const char *fileName, std::vector<ParallelRegion*> &regi
bool buildGraphFromUserDirectives(const std::vector<Statement*> &userDvmAlignDirs, DIST::GraphCSR<int, double, attrType> &G, DIST::Arrays<int> &allArrays, const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls, const std::set<DIST::Array*>& alignedArrays, std::set<DIST::Array*>& addedArrays, const std::map<std::string, std::vector<FuncInfo*>>& funcsByFile); bool buildGraphFromUserDirectives(const std::vector<Statement*> &userDvmAlignDirs, DIST::GraphCSR<int, double, attrType> &G, DIST::Arrays<int> &allArrays, const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls, const std::set<DIST::Array*>& alignedArrays, std::set<DIST::Array*>& addedArrays, const std::map<std::string, std::vector<FuncInfo*>>& funcsByFile);
void clearRegionStaticData(); void clearRegionStaticData();
void calculateLinesOfCode(std::vector<ParallelRegion*> &allRegions); void calculateLinesOfCode(std::vector<ParallelRegion*> &allRegions);
void propagateRegionInfo(std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCall,
const std::vector<ParallelRegion*>& parallelRegions);

View File

@@ -1,624 +0,0 @@
#include "leak_detector.h"
#include <set>
#include <map>
#include "merge_regions.h"
using std::map;
using std::set;
using std::pair;
using std::string;
using std::vector;
//TODO: need to create new clause!!
static void parseMergeDirective(const char *comment,
vector<pair<string, string>> &parsed_mapping)
{
while (comment)
{
auto *line_end = strchr(comment, '\n');
static const char prefix[] = "!!spf transform(merge_arrays(";
static const auto compare_chars = sizeof(prefix) - 1;
if (strlen(comment) >= compare_chars)
{
std::string comment_cmp(comment, compare_chars);
convertToLower(comment_cmp);
if (comment_cmp == prefix)
{
auto* pair_start = comment + compare_chars;
auto* comma = strchr(pair_start, ',');
if (comma)
{
auto* close_br = strchr(comma + 1, ')');
if (close_br)
{
parsed_mapping.emplace_back(
string(pair_start, comma - pair_start),
string(comma + 1, close_br - comma - 1));
}
}
}
}
comment = line_end;
if (comment)
comment++;
}
}
static string getNonDefaultRegion(DIST::Array *a)
{
string result;
if (!a)
return result;
for (const auto &reg_name : a->GetRegionsName())
{
if (reg_name != "default")
{
if (!result.empty())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
result = reg_name;
}
}
return result;
}
static bool hasSameSizes(DIST::Array *a, DIST::Array *b)
{
for (auto *array : {a, b})
{
for (const auto &p : array->GetSizes())
{
if (p.first < 0 || p.second < 0)
return false;
}
}
return a->GetSizes() == b->GetSizes() && a->GetTypeSize() == b->GetTypeSize();
}
static bool checkSimilarTemplates(vector<ParallelRegion *> &regions,
const map<string, string> &new_region_mapping)
{
// new region -> old regions
map<string, set<string>> new_region_inverse_mapping;
for (const auto &p : new_region_mapping)
new_region_inverse_mapping[p.second].insert(p.first);
for (const auto &new_reg : new_region_inverse_mapping)
{
DIST::Array *template_array = nullptr;
string first_reg_name;
for (const auto &old_region_name : new_reg.second)
{
auto *old_reg = getRegionByName(regions, old_region_name);
if (!old_reg)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const auto &distr_rules = old_reg->GetDataDir().GetDistrRules();
if (distr_rules.size() != 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto *current_template = distr_rules.front().first;
if (template_array)
{
if (!hasSameSizes(template_array, current_template))
{
__spf_print(1, "Templates of %s and %s has different sizes\n",
first_reg_name.c_str(),
old_region_name.c_str());
return false;
}
// else everything OK
}
else
{
template_array = current_template;
first_reg_name = old_region_name;
}
}
}
return true;
}
static bool hasSameAlignment(const std::set<const AlignRule *> &align_a,
const std::set<const AlignRule *> &align_b)
{
if (align_a.size() != 1 || align_b.size() != 1)
return false;
const auto *rule_a = *align_a.begin();
const auto *rule_b = *align_b.begin();
if (rule_a->alignRule != rule_b->alignRule)
return false;
return true;
}
static void printExpr(SgExpression *e, string pad)
{
if (!e)
return;
__spf_print(1, "%s%d: %s\n", pad.c_str(), e->variant(), e->unparse());
printExpr(e->lhs(), pad + " ");
printExpr(e->rhs(), pad + " ");
}
static pair<vector<SgStatement *>, SgSymbol *> generateDeclaration(const string &array_name, const string &common_block_name,
const vector<pair<int, int>> &sizes, SgType *type, SgStatement *scope)
{
auto *array_symbol = new SgSymbol(VARIABLE_NAME, array_name.c_str(), new SgType(T_ARRAY), scope);
auto *decl = new SgDeclarationStatement(VAR_DECL);
decl->setExpression(1, new SgTypeExp(*type));
SgExpression *subs = new SgExprListExp();
auto *array_ref = new SgArrayRefExp(*array_symbol, *subs);
for (int i = 0; i < sizes.size(); i++)
{
const auto &p = sizes[i];
auto *d = new SgExpression(DDOT, new SgValueExp(p.first), new SgValueExp(p.second));
subs->setLhs(d);
if (i + 1 < sizes.size())
{
subs->setRhs(new SgExprListExp());
subs = subs->rhs();
}
}
decl->setExpression(0, array_ref);
auto comm = new SgStatement(COMM_STAT);
comm->setExpression(0, new SgExpression(COMM_LIST,
new SgVarRefExp(array_symbol),
NULL,
new SgSymbol(COMMON_NAME, common_block_name.c_str())));
return {{decl, comm}, array_symbol};
}
static SgExpression* findExprWithVariant(SgExpression* exp, int variant)
{
if (exp)
{
if (exp->variant() == variant)
return exp;
auto *l = findExprWithVariant(exp->lhs(), variant);
if (l)
return l;
auto *r = findExprWithVariant(exp->rhs(), variant);
if (r)
return r;
}
return NULL;
}
SgType* GetArrayType(DIST::Array *array)
{
if (!array)
return NULL;
for (const auto& decl_place : array->GetDeclInfo())
{
if (SgFile::switchToFile(decl_place.first) != -1)
{
auto* decl = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second);
if (decl)
{
for (int i = 0; i < 3; i++)
{
auto* found_type = isSgTypeExp(findExprWithVariant(decl->expr(i), TYPE_OP));
if (found_type)
return found_type->type();
}
}
}
}
return NULL;
}
SgSymbol *insertDeclIfNeeded(const string &array_name,
const string &common_block_name,
DIST::Array *example_array,
FuncInfo *dest,
map<FuncInfo *, map<string, SgSymbol *>> &inserted_arrays)
{
auto *type = GetArrayType(example_array);
if (!type)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (SgFile::switchToFile(dest->fileName) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto &by_func = inserted_arrays[dest];
auto it = by_func.find(array_name);
if (it != by_func.end())
return it->second;
SgStatement *st = dest->funcPointer;
auto *end = st->lastNodeOfStmt();
st = st->lexNext();
while (st != end && !isSgExecutableStatement(st))
{
st = st->lexNext();
}
auto generated = generateDeclaration(array_name, common_block_name,
example_array->GetSizes(),
type, dest->funcPointer);
for (auto *new_stmt : generated.first)
st->insertStmtBefore(*new_stmt, *dest->funcPointer);
by_func[array_name] = generated.second;
return generated.second;
}
static pair<string, string> createNewArray(DIST::Array *example_array, const string &base_name,
const map<string, vector<FuncInfo *>> &allFuncInfo,
map<FuncInfo *, map<string, SgSymbol *>> &inserted_arrays)
{
auto common_block_name = base_name + "_merge_r";
auto array_name = base_name;
for (const auto &by_file : allFuncInfo)
{
for (auto *func_info : by_file.second)
{
if (func_info->isMain)
{
insertDeclIfNeeded(
array_name,
common_block_name,
example_array,
func_info,
inserted_arrays);
}
}
}
return std::make_pair(array_name, common_block_name);
}
static void replaceArrayRec(SgExpression *e,
const set<string> &arrays_to_replace,
SgSymbol **func_symbol_hint,
const pair<string, string> &replace_by,
DIST::Array *example_array,
FuncInfo *func,
map<FuncInfo *, map<string, SgSymbol *>> &inserted_arrays)
{
if (!e)
return;
if (isArrayRef(e) && arrays_to_replace.find(e->symbol()->identifier()) != arrays_to_replace.end())
{
if (!(*func_symbol_hint))
{
*func_symbol_hint = insertDeclIfNeeded(
replace_by.first, replace_by.second,
example_array,
func,
inserted_arrays);
}
e->setSymbol(*func_symbol_hint);
}
replaceArrayRec(
e->lhs(),
arrays_to_replace,
func_symbol_hint,
replace_by,
example_array,
func,
inserted_arrays);
replaceArrayRec(
e->rhs(),
arrays_to_replace,
func_symbol_hint,
replace_by,
example_array,
func,
inserted_arrays);
}
static void replaceRegion(SgStatement* st, const map<string, string> &new_region_mapping)
{
if (!st)
return;
if(isSPF_stat(st) && st->variant() == SPF_PARALLEL_REG_DIR)
{
auto it = new_region_mapping.find(st->symbol()->identifier());
if (it != new_region_mapping.end())
st->setSymbol(*(new SgSymbol(CONST_NAME, it->second.c_str())));
}
}
void mergeRegions(vector<ParallelRegion *> &regions, const map<string, vector<FuncInfo *>> &allFuncInfo)
{
for (const auto *region : regions)
{
__spf_print(1, "region %s\n", region->GetName().c_str());
const auto &dirs = region->GetDataDir();
__spf_print(1, " distr rules: %d\n", dirs.distrRules.size());
const auto &currentVariant = region->GetCurrentVariant();
int distr_idx = 0;
for (const auto &distr : dirs.distrRules)
{
const auto &dist_rule = distr.second.back().distRule;
string sizes;
for (const auto &p : distr.first->GetSizes())
{
if (!sizes.empty())
sizes.push_back(',');
sizes += std::to_string(p.first) + ":" + std::to_string(p.second);
}
__spf_print(1, " DIST %s(%s)", distr.first->GetName().c_str(), sizes.c_str());
for (const auto &dim : dist_rule)
__spf_print(1, " %c", dim == dist::BLOCK ? 'B' : '*');
__spf_print(1, "\n");
distr_idx++;
}
__spf_print(1, " align rules: %d\n", dirs.alignRules.size());
for (const auto &align : dirs.alignRules)
{
string sub_a, sub_b;
int i = 0;
for (const auto coefs : align.alignRule)
{
if (!sub_a.empty())
sub_a.push_back(',');
sub_a += std::to_string(coefs.first) + "*i" +
std::to_string(i) + "+" + std::to_string(coefs.second);
i++;
}
for (const auto coefs : align.alignRuleWith)
{
if (!sub_b.empty())
sub_b.push_back(',');
sub_b += std::to_string(coefs.second.first) + "*i" +
std::to_string(coefs.first) + "+" + std::to_string(coefs.second.second);
}
__spf_print(1, " ALIGN %s(%s) WITH %s(%s)\n",
align.alignArray->GetName().c_str(), sub_a.c_str(),
align.alignWith->GetName().c_str(), sub_b.c_str());
}
}
// parse directives
// new array name -> current arrays
map<string, set<DIST::Array *>> arrays_to_merge;
map<DIST::Array *, set<const AlignRule *>> array_alignment;
for (const auto &by_file : allFuncInfo)
{
const auto current_file_name = by_file.first;
if (SgFile::switchToFile(current_file_name) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto *func_info : by_file.second)
{
SgStatement *curr_stmt = func_info->funcPointer;
if (!curr_stmt)
continue;
auto *stmt_end = curr_stmt->lastDeclaration();
if (!stmt_end)
continue;
stmt_end = stmt_end->lexNext();
for (; curr_stmt && curr_stmt != stmt_end; curr_stmt = curr_stmt->lexNext())
{
if (curr_stmt->comments())
{
vector<pair<string, string>> parsed_mapping;
parseMergeDirective(curr_stmt->comments(), parsed_mapping);
for (const auto &p : parsed_mapping)
{
auto *found_array = getArrayFromDeclarated(curr_stmt, p.first);
if (found_array)
{
arrays_to_merge[p.second].insert(found_array);
array_alignment[found_array] = {};
}
}
}
}
}
}
// find alignment rules for array
for (const auto *region : regions)
{
const auto &dirs = region->GetDataDir();
for (const auto &align : dirs.alignRules)
{
auto it = array_alignment.find(align.alignArray);
if (it != array_alignment.end())
it->second.insert(&align);
}
}
// old region -> new region
map<string, string> new_region_mapping;
// new array -> new region
map<string, string> arrays_new_region_mapping;
vector<string> created_region_names;
for (const auto &by_new_array : arrays_to_merge)
{
string new_region_name;
for (auto *current_array : by_new_array.second)
{
auto current_array_region = getNonDefaultRegion(current_array);
auto it = new_region_mapping.find(current_array_region);
if (it != new_region_mapping.end())
{
if (new_region_name.empty())
new_region_name = it->second;
else if (new_region_name != it->second)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
if (new_region_name.empty())
{
new_region_name = "merged_reg_" + std::to_string(created_region_names.size());
created_region_names.push_back(new_region_name);
}
for (auto *current_array : by_new_array.second)
{
auto current_array_region = getNonDefaultRegion(current_array);
new_region_mapping[current_array_region] = new_region_name;
}
arrays_new_region_mapping[by_new_array.first] = new_region_name;
}
if (!checkSimilarTemplates(regions, new_region_mapping))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
map<FuncInfo *, map<string, SgSymbol *>> inserted_arrays;
for (const auto &by_dest_array : arrays_to_merge)
{
const auto &copy_arrays = by_dest_array.second;
if (copy_arrays.empty())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto *first_element = *copy_arrays.begin();
auto first_elem_rules_it = array_alignment.find(first_element);
if (first_elem_rules_it == array_alignment.end())
continue;
const auto &first_elem_rules = first_elem_rules_it->second;
for (auto *array_to_merge : copy_arrays)
{
auto array_rules_it = array_alignment.find(array_to_merge);
if (array_rules_it == array_alignment.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const auto &array_rules = array_rules_it->second;
if (!hasSameSizes(array_to_merge, first_element) || !hasSameAlignment(first_elem_rules, array_rules))
{
__spf_print(1, "Arrays %s and %s has different sizes or align rules\n",
array_to_merge->GetName().c_str(),
first_element->GetName().c_str());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
__spf_print(1, "merge into %s (%s):\n", by_dest_array.first.c_str(), arrays_new_region_mapping[by_dest_array.first].c_str());
for (auto *array_to_merge : copy_arrays)
__spf_print(1, "%s\n", array_to_merge->GetName().c_str());
auto created_array_info = createNewArray(first_element, by_dest_array.first, allFuncInfo, inserted_arrays);
set<string> arrays_to_replace;
for (auto *array_to_merge : copy_arrays)
arrays_to_replace.insert(array_to_merge->GetShortName());
for (const auto &by_file : allFuncInfo)
{
if (SgFile::switchToFile(by_file.first) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto *func_info : by_file.second)
{
SgSymbol *func_symbol_hint = nullptr;
SgStatement *st = func_info->funcPointer;
auto *func_end = st->lastNodeOfStmt();
st = st->lexNext();
while (st && !isSgExecutableStatement(st) && st != func_end)
st = st->lexNext();
while (st && st != func_end)
{
for (int i = 0; i < 3; i++)
{
replaceArrayRec(
st->expr(i),
arrays_to_replace,
&func_symbol_hint,
created_array_info,
first_element,
func_info,
inserted_arrays);
}
replaceRegion(st, new_region_mapping);
st = st->lexNext();
}
}
}
}
}

View File

@@ -1,8 +0,0 @@
#include "../GraphCall/graph_calls.h"
#include "ParRegions.h"
#include <string>
#include <vector>
#include <map>
void mergeRegions(std::vector<ParallelRegion*> &regions, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo);

View File

@@ -19,7 +19,6 @@
#include "SgUtils.h" #include "SgUtils.h"
#include "expr_transform.h" #include "expr_transform.h"
#include "FunctionPurifying/function_purifying.h" #include "FunctionPurifying/function_purifying.h"
#include "uniq_name_creator.h"
using std::map; using std::map;
using std::pair; using std::pair;
@@ -72,7 +71,7 @@ static bool isSPF_reg(SgStatement *st)
return st->variant() == SPF_PARALLEL_REG_DIR || st->variant() == SPF_END_PARALLEL_REG_DIR; return st->variant() == SPF_PARALLEL_REG_DIR || st->variant() == SPF_END_PARALLEL_REG_DIR;
} }
const vector<const Variable*> getArraySynonyms(DIST::Array *array) static const vector<const Variable*> getArraySynonyms(DIST::Array *array)
{ {
auto arrayBlock = allUsedCommonArrays.find(array); auto arrayBlock = allUsedCommonArrays.find(array);
if (arrayBlock == allUsedCommonArrays.end()) if (arrayBlock == allUsedCommonArrays.end())
@@ -128,16 +127,15 @@ static string getStringDeclaration(SgSymbol *symb)
return decl; return decl;
} }
static void insertStringDeclarations(SgStatement *insertPlace, DIST::Array *array, UniqueNameCreator& unique_name_creator) static void insertStringDeclarations(SgStatement *insertPlace, DIST::Array *array)
{ {
auto varsOnPos = getArraySynonyms(array); auto varsOnPos = getArraySynonyms(array);
if (varsOnPos.size() && varsOnPos[0]->getName() == array->GetShortName()) if (varsOnPos.size() && varsOnPos[0]->getName() == array->GetShortName())
{ {
string newArrName, commName;
unique_name_creator.GetUniqueName(array, newArrName, commName);
SgSymbol *varSymb = varsOnPos[0]->getSymbol(); SgSymbol *varSymb = varsOnPos[0]->getSymbol();
string varName = varSymb->identifier(); string varName = varSymb->identifier();
varSymb->changeName(newArrName.c_str()); string newName = varName + "_c";
varSymb->changeName(newName.c_str());
string decl = getStringDeclaration(varsOnPos[0]->getSymbol()); string decl = getStringDeclaration(varsOnPos[0]->getSymbol());
varSymb->changeName(varName.c_str()); varSymb->changeName(varName.c_str());
insertPlace->addComment(decl.c_str()); insertPlace->addComment(decl.c_str());
@@ -664,11 +662,12 @@ static void replaceFuncCalls(const ParallelRegionLines &lines, const map<string,
static map<string, map<DIST::Array*, SgStatement*>> createdCommonBlocks; // file -> array -> new common statement static map<string, map<DIST::Array*, SgStatement*>> createdCommonBlocks; // file -> array -> new common statement
static map<string, map<DIST::Array*, pair<SgSymbol*, SgSymbol*>>> createdCommonArrays; // file -> array -> (orig, copy) static map<string, map<DIST::Array*, pair<SgSymbol*, SgSymbol*>>> createdCommonArrays; // file -> array -> (orig, copy)
static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array, UniqueNameCreator& unique_name_creator) static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array)
{ {
string newArrName, commBlockName; auto varsOnPos = getArraySynonyms(array);
if (!varsOnPos.size())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
unique_name_creator.GetUniqueName(array, newArrName, commBlockName);
string fileName = file->filename(); string fileName = file->filename();
if (SgFile::switchToFile(fileName) != -1) if (SgFile::switchToFile(fileName) != -1)
@@ -684,6 +683,7 @@ static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array, UniqueNa
// creating new common-block statement // creating new common-block statement
//TODO: consistence with declaration //TODO: consistence with declaration
//string commBlockName = checkSymbNameAndCorrect(array->GetShortName() + "_r"); //string commBlockName = checkSymbNameAndCorrect(array->GetShortName() + "_r");
string commBlockName = array->GetShortName() + "_r";
SgStatement *commDecl = new SgStatement(COMM_STAT); SgStatement *commDecl = new SgStatement(COMM_STAT);
SgSymbol *commSymb = new SgSymbol(VARIABLE_NAME, commBlockName.c_str()); SgSymbol *commSymb = new SgSymbol(VARIABLE_NAME, commBlockName.c_str());
@@ -705,6 +705,7 @@ static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array, UniqueNa
{ {
//TODO: consistence with declaration //TODO: consistence with declaration
//string newArrName = checkSymbNameAndCorrect(varsOnPos[0]->getName() + "_c"); //string newArrName = checkSymbNameAndCorrect(varsOnPos[0]->getName() + "_c");
string newArrName = varsOnPos[0]->getName() + "_c";
newArrSymb = new SgSymbol(VARIABLE_NAME, newArrName.c_str(), file->firstStatement()); newArrSymb = new SgSymbol(VARIABLE_NAME, newArrName.c_str(), file->firstStatement());
SgType *type = new SgType(T_ARRAY); SgType *type = new SgType(T_ARRAY);
@@ -750,7 +751,7 @@ static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array, UniqueNa
// func -> arrays; funcs where new common statement inserted // func -> arrays; funcs where new common statement inserted
static map<FuncInfo*, set<DIST::Array*>> insertedCommonBlocks; static map<FuncInfo*, set<DIST::Array*>> insertedCommonBlocks;
static void insertCommonBlock(FuncInfo *func, DIST::Array *array, UniqueNameCreator& unique_name_creator) static void insertCommonBlock(FuncInfo *func, DIST::Array *array)
{ {
SgFile *file = func->funcPointer->GetOriginal()->getFile(); SgFile *file = func->funcPointer->GetOriginal()->getFile();
SgStatement *insertPlace = NULL; SgStatement *insertPlace = NULL;
@@ -766,7 +767,7 @@ static void insertCommonBlock(FuncInfo *func, DIST::Array *array, UniqueNameCrea
if (!insertPlace) if (!insertPlace)
insertPlace = func->funcPointer->GetOriginal(); insertPlace = func->funcPointer->GetOriginal();
SgStatement *commDecl = createCommonBlock(file, array, unique_name_creator); SgStatement *commDecl = createCommonBlock(file, array);
SgStatement *copyDecl = commDecl->copyPtr(); SgStatement *copyDecl = commDecl->copyPtr();
auto st = insertPlace->controlParent(); auto st = insertPlace->controlParent();
@@ -778,7 +779,7 @@ static void insertCommonBlock(FuncInfo *func, DIST::Array *array, UniqueNameCrea
insertPlace->lexNext()->setlineNumber(nextLine); insertPlace->lexNext()->setlineNumber(nextLine);
// create declaration via comment // create declaration via comment
insertStringDeclarations(insertPlace->lexNext(), array, unique_name_creator); insertStringDeclarations(insertPlace->lexNext(), array);
} }
// file -> lines -> arrays; lines where arrays copying is inserted // file -> lines -> arrays; lines where arrays copying is inserted
@@ -1096,7 +1097,6 @@ pair<SgSymbol*, SgSymbol*> copyArray(const pair<string, int> &place,
static void copyFunction(ParallelRegion *region, static void copyFunction(ParallelRegion *region,
FuncInfo *func, FuncInfo *func,
const map<string, FuncInfo*> &funcMap, const map<string, FuncInfo*> &funcMap,
UniqueNameCreator& unique_name_creator,
const string &suffix = "") const string &suffix = "")
{ {
if (SgFile::switchToFile(func->fileName) != -1) if (SgFile::switchToFile(func->fileName) != -1)
@@ -1146,14 +1146,14 @@ static void copyFunction(ParallelRegion *region,
if (origStat->variant() == COMM_STAT) if (origStat->variant() == COMM_STAT)
{ {
for (auto &arrayBlock : allUsedCommonArrays) for (auto &arrayBlock : allUsedCommonArrays)
createCommonBlock(file, arrayBlock.first, unique_name_creator); createCommonBlock(file, arrayBlock.first);
auto usedCommonArrays = region->GetUsedCommonArrays().find(func); auto usedCommonArrays = region->GetUsedCommonArrays().find(func);
if (usedCommonArrays != region->GetUsedCommonArrays().end()) if (usedCommonArrays != region->GetUsedCommonArrays().end())
{ {
for (auto &arrayLines : usedCommonArrays->second) for (auto &arrayLines : usedCommonArrays->second)
{ {
SgStatement *commDecl = createCommonBlock(file, arrayLines.first, unique_name_creator); SgStatement *commDecl = createCommonBlock(file, arrayLines.first);
SgStatement *copyDecl = commDecl->copyPtr(); SgStatement *copyDecl = commDecl->copyPtr();
while (!isSgExecutableStatement(copyStat) || isSPF_stat(copyStat)) while (!isSgExecutableStatement(copyStat) || isSPF_stat(copyStat))
@@ -1163,7 +1163,7 @@ static void copyFunction(ParallelRegion *region,
copyStat->insertStmtAfter(*copyDecl, *copyStat->controlParent()); copyStat->insertStmtAfter(*copyDecl, *copyStat->controlParent());
// making declaration of new common array symbol via comment through files // making declaration of new common array symbol via comment through files
insertStringDeclarations(copyStat->lexNext(), arrayLines.first, unique_name_creator); insertStringDeclarations(copyStat->lexNext(), arrayLines.first);
} }
auto it = createdCommonArrays.find(file->filename()); auto it = createdCommonArrays.find(file->filename());
@@ -1619,8 +1619,6 @@ int resolveParRegions(vector<ParallelRegion*> &regions, const map<string, vector
map<string, FuncInfo*> funcMap; map<string, FuncInfo*> funcMap;
createMapOfFunc(allFuncInfo, funcMap); createMapOfFunc(allFuncInfo, funcMap);
UniqueNameCreator unique_name_creator(allFuncInfo);
if (sharedMemoryParallelization == 0) if (sharedMemoryParallelization == 0)
{ {
map<string, map<int, set<string>>> copied; map<string, map<int, set<string>>> copied;
@@ -1690,7 +1688,7 @@ int resolveParRegions(vector<ParallelRegion*> &regions, const map<string, vector
if (itt == it->second.end() && arrayBlock.first->GetShortName() == varsOnPos[0]->getName()) if (itt == it->second.end() && arrayBlock.first->GetShortName() == varsOnPos[0]->getName())
{ {
// need to insert common-block // need to insert common-block
insertCommonBlock(func, arrayBlock.first, unique_name_creator); insertCommonBlock(func, arrayBlock.first);
it->second.insert(arrayBlock.first); it->second.insert(arrayBlock.first);
} }
} }
@@ -1783,7 +1781,7 @@ int resolveParRegions(vector<ParallelRegion*> &regions, const map<string, vector
if (itt == it->second.end() && arrayBlock.first->GetShortName() == varsOnPos[0]->getName()) if (itt == it->second.end() && arrayBlock.first->GetShortName() == varsOnPos[0]->getName())
{ {
// need to insert common-block // need to insert common-block
insertCommonBlock(func, arrayBlock.first, unique_name_creator); insertCommonBlock(func, arrayBlock.first);
it->second.insert(arrayBlock.first); it->second.insert(arrayBlock.first);
} }
} }
@@ -1815,7 +1813,7 @@ int resolveParRegions(vector<ParallelRegion*> &regions, const map<string, vector
if (usedCommonArrays != region->GetUsedCommonArrays().end()) if (usedCommonArrays != region->GetUsedCommonArrays().end())
{ {
for (auto &arrayBlock : allUsedCommonArrays) for (auto &arrayBlock : allUsedCommonArrays)
createCommonBlock(file, arrayBlock.first, unique_name_creator); createCommonBlock(file, arrayBlock.first);
auto it = insertedCommonBlocks.find(func); auto it = insertedCommonBlocks.find(func);
if (it == insertedCommonBlocks.end()) if (it == insertedCommonBlocks.end())
@@ -1827,7 +1825,7 @@ int resolveParRegions(vector<ParallelRegion*> &regions, const map<string, vector
if (itt == it->second.end()) if (itt == it->second.end())
{ {
// need to insert common-block // need to insert common-block
insertCommonBlock(func, arrayLines.first, unique_name_creator); insertCommonBlock(func, arrayLines.first);
it->second.insert(arrayLines.first); it->second.insert(arrayLines.first);
// replace common arrays to new common arrays in executable code section // replace common arrays to new common arrays in executable code section
@@ -1860,7 +1858,7 @@ int resolveParRegions(vector<ParallelRegion*> &regions, const map<string, vector
// need copy function for every region, the exeption is defalut region // need copy function for every region, the exeption is defalut region
for (auto &regionId : func->callRegions) for (auto &regionId : func->callRegions)
if (regionId) if (regionId)
copyFunction(getRegionById(regions, regionId), func, funcMap, unique_name_creator, string("_r") + to_string(regionId)); copyFunction(getRegionById(regions, regionId), func, funcMap, string("_r") + to_string(regionId));
} }
} }
} }

View File

@@ -21,6 +21,4 @@ std::pair<SgSymbol*, SgSymbol*> copyArray(const std::pair<std::string, int>& pla
const std::string& suffix, const std::string& suffix,
std::string& filename, std::string& filename,
std::map<std::string, std::map<int, std::set<std::string>>>& newDeclsToInclude, std::map<std::string, std::map<int, std::set<std::string>>>& newDeclsToInclude,
std::map<std::string, std::map<int, std::set<std::string>>>& copied); std::map<std::string, std::map<int, std::set<std::string>>>& copied);
const std::vector<const Variable*> getArraySynonyms(DIST::Array* array);

View File

@@ -1,98 +0,0 @@
#include "leak_detector.h"
#include <set>
#include <map>
#include <string>
#include "SgUtils.h"
#include "uniq_name_creator.h"
#include "resolve_par_reg_conflicts.h"
using namespace::std;
static const string COMMON_ARRAY_SUFFIX = "_c";
static const string COMMON_BLOCK_SUFFIX = "_r";
void UniqueNameCreator::GetSymbolsRec(SgExpression* exp, set<string>& add_to)
{
if (!exp)
return;
if (isArrayRef(exp) && exp->symbol() && exp->symbol()->identifier())
add_to.emplace(exp->symbol()->identifier());
GetSymbolsRec(exp->lhs(), add_to);
GetSymbolsRec(exp->rhs(), add_to);
}
void UniqueNameCreator::FillDeclarations()
{
allDeclarations.clear();
auto* file_before = current_file;
for (const auto& by_file : funcInfo)
{
if (SgFile::switchToFile(by_file.first) != -1)
{
for (const auto* by_func : by_file.second)
{
SgStatement* st = by_func->funcPointer;
if (st)
st = st->lexNext();
while (st)
{
for (int i = 0; i < 3; i++)
GetSymbolsRec(st->expr(i), allDeclarations);
st = st->lexNext();
}
}
}
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
SgFile::switchToFile(file_before->filename());
declarationsAnalyzed = true;
}
void UniqueNameCreator::GetUniqueName(DIST::Array* array, string& array_name, string& common_block_name)
{
auto varsOnPos = getArraySynonyms(array);
if (!varsOnPos.size())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto array_plain_name = varsOnPos[0]->getName();
auto it = generatedNames.find(array);
if (it != generatedNames.end())
{
array_name.assign(it->second.first);
common_block_name.assign(it->second.second);
return;
}
if (!declarationsAnalyzed)
FillDeclarations();
int v = 1;
auto created_array_name = array_plain_name + COMMON_ARRAY_SUFFIX;
auto created_common_name = array_plain_name + COMMON_BLOCK_SUFFIX;
while (allDeclarations.find(created_array_name) != allDeclarations.end() ||
allDeclarations.find(created_common_name) != allDeclarations.end())
{
created_array_name = array_plain_name + "_v" + std::to_string(v) + COMMON_ARRAY_SUFFIX;
created_common_name = array_plain_name + "_v" + std::to_string(v) + COMMON_BLOCK_SUFFIX;
v++;
}
allDeclarations.insert(created_array_name);
allDeclarations.insert(created_common_name);
generatedNames.emplace(array, std::make_pair(created_array_name, created_common_name));
array_name.assign(created_array_name);
common_block_name.assign(created_common_name);
}

View File

@@ -1,26 +0,0 @@
#pragma once
#include <map>
#include <set>
#include <string>
#include "GraphCall/graph_calls.h"
class UniqueNameCreator
{
std::map<std::string, std::vector<FuncInfo*>> funcInfo;
std::set<std::string> allDeclarations;
bool declarationsAnalyzed = false;
std::map<const DIST::Array*, std::pair<std::string, std::string>> generatedNames;
static void GetSymbolsRec(SgExpression* exp, std::set<std::string>& add_to);
void FillDeclarations();
public:
UniqueNameCreator(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo)
{
declarationsAnalyzed = false;
funcInfo = allFuncInfo;
}
void GetUniqueName(DIST::Array* array, std::string& array_name, std::string& common_block_name);
};

View File

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

View File

@@ -1,4 +1,3 @@
#include <algorithm>
#include <map> #include <map>
#include <unordered_set> #include <unordered_set>
#include <unordered_map> #include <unordered_map>
@@ -7,133 +6,55 @@
#include <numeric> #include <numeric>
#include <iostream> #include <iostream>
#include "ArrayConstantPropagation/propagation.h"
#include "CFGraph/CFGraph.h"
#include "Distribution/Array.h"
#include "graph_loops.h"
#include "private_arrays_search.h" #include "private_arrays_search.h"
#include "range_structures.h" #include "range_structures.h"
#include "region.h" #include "region.h"
#include "SgUtils.h" #include "SgUtils.h"
#include "utils.h" #include "graph_loops.h"
#include "Utils/AstWrapper.h" #include "CFGraph/CFGraph.h"
using namespace std; using namespace std;
extern std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays;
extern unordered_set<SgStatement*> statementsToRemove;
extern unordered_map<string, vector<pair<SgStatement*, SgStatement*>>> expToChange;
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.empty())
resultContainer[arrayName] = points;
else
toRemove.insert(arrayName);
}
for (const string& name : toRemove)
container.erase(name);
for (auto& [arrayName, accessingSet] : resultContainer)
container[arrayName] = accessingSet;
}
static void Collapse(Region* region) static void Collapse(Region* region)
{ {
if (region->getBasickBlocks().empty()) if (region->getBasickBlocks().empty())
return; return;
bool firstRegion = true; for (auto& [arrayName, arrayRanges] : region->getHeader()->array_out)
for (Region* basickBlock : region->getBasickBlocks())
{ {
if (basickBlock->getNextRegions().empty()) for (Region* byBlock : region->getBasickBlocks())
{ {
if (firstRegion) AccessingSet intersection = byBlock->array_def[arrayName].Intersect(arrayRanges);
{ region->array_def[arrayName] = region->array_def[arrayName].Union(intersection);
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; for (auto& byBlock : region->getBasickBlocks())
instruction.def = move(region->array_def);
for (auto& byBlock : region->getBasickBlocks())
{ {
for (auto& instruction : byBlock->instructions) for (auto& [arrayName, arrayRanges] : byBlock->array_use)
{ {
for (auto& [arrayName, _] : instruction.use) AccessingSet diff = byBlock->array_use[arrayName].Diff(byBlock->array_in[arrayName]);
{ region->array_use[arrayName] = region->array_use[arrayName].Union(diff);
AccessingSet diff = instruction.use[arrayName].Diff(instruction.in[arrayName]);
region->array_use[arrayName] = region->array_use[arrayName].Union(diff);
}
} }
} }
ArrayAccessingIndexes useUnion;
ArrayAccessingIndexes useUnionB;
for (auto& byBlock : region->getBasickBlocks()) for (auto& byBlock : region->getBasickBlocks())
for (auto& instruction : byBlock->instructions) for (auto& [arrayName, arrayRanges] : byBlock->array_use)
for (auto& [arrayName, _] : instruction.use) useUnion[arrayName] = useUnion[arrayName].Union(byBlock->array_use[arrayName]);
useUnionB[arrayName] = useUnionB[arrayName].Union(instruction.use[arrayName]);
for (auto& [arrayName, _] : useUnionB) for (auto& [arrayName, arrayRanges] : useUnion)
region->array_priv[arrayName] = useUnionB[arrayName].Diff(region->array_use[arrayName]); region->array_priv[arrayName] = useUnion[arrayName].Diff(region->array_use[arrayName]);
instruction.use = move(region->array_use); for (Region* prevBlock : region->getHeader()->getPrevRegions())
for (Region* prevBlock : region->getHeader()->getPrevRegions())
{
prevBlock->replaceInNextRegions(region, region->getHeader()); prevBlock->replaceInNextRegions(region, region->getHeader());
region->addPrevRegion(prevBlock);
}
for (Region* nextBlock : region->getHeader()->getNextRegions()) for (Region* nextBlock : region->getHeader()->getNextRegions())
{
nextBlock->replaceInPrevRegions(region, region->getHeader()); nextBlock->replaceInPrevRegions(region, region->getHeader());
region->addNextRegion(nextBlock);
}
region->instructions.push_back(instruction);
} }
static void SolveDataFlowIteratively(Region* DFG) static void SolveDataFlowIteratively(Region* DFG)
{ {
auto blocks = DFG->getBasickBlocks(); unordered_set<Region*> worklist(DFG->getBasickBlocks());
std::unordered_set<Region*> worklist(blocks.begin(), blocks.end());
do do
{ {
Region* b = *worklist.begin(); Region* b = *worklist.begin();
@@ -151,13 +72,12 @@ static void SolveDataFlowIteratively(Region* DFG)
if (prevBlock->array_out.empty()) if (prevBlock->array_out.empty())
{ {
newIn.clear(); newIn.clear();
break; continue;
} }
for (const auto& [arrayName, accessSet] : prevBlock->array_out) for (const auto& [arrayName, accessSet] : prevBlock->array_out)
{ {
if (newIn.find(arrayName) != newIn.end()) if (newIn.find(arrayName) != newIn.end())
newIn[arrayName] = newIn[arrayName].Intersect(accessSet); newIn[arrayName] = newIn[arrayName].Intersect(accessSet);
else else
newIn[arrayName] = AccessingSet(); newIn[arrayName] = AccessingSet();
} }
@@ -166,8 +86,7 @@ static void SolveDataFlowIteratively(Region* DFG)
b->array_in = move(newIn); b->array_in = move(newIn);
ArrayAccessingIndexes newOut; ArrayAccessingIndexes newOut;
if (b->array_def.empty())
if (b->array_def.empty())
newOut = b->array_in; newOut = b->array_in;
else if (b->array_in.empty()) else if (b->array_in.empty())
newOut = b->array_def; newOut = b->array_def;
@@ -183,299 +102,40 @@ static void SolveDataFlowIteratively(Region* DFG)
} }
/* can not differ */ /* can not differ */
if (newOut != b->array_out) if (newOut != b->array_out)
b->array_out = newOut; b->array_out = newOut;
else else
worklist.erase(b); worklist.erase(b);
} while (!worklist.empty()); }
} while (!worklist.empty());
static void SolveForBasickBlock(Region* block)
{
ArrayAccessingIndexes newIn;
bool flagFirst = true;
for (Region* prevBlock : block->getPrevRegions())
{
if (flagFirst)
{
newIn = prevBlock->array_out;
flagFirst = false;
}
else
{
if (prevBlock->array_out.empty())
{
newIn.clear();
break;
}
for (const auto& [arrayName, accessSet] : prevBlock->array_out)
{
if (newIn.find(arrayName) != newIn.end())
newIn[arrayName] = newIn[arrayName].Intersect(accessSet);
else
newIn[arrayName] = AccessingSet();
}
}
}
if (block->instructions.empty())
block->instructions.push_back(RegionInstruction());
block->instructions[0].in = move(newIn);
for (int i = 0; i < block->instructions.size(); i++)
{
auto& instruction = block->instructions[i];
if (i > 0)
instruction.in = block->instructions[i - 1].out;
ArrayAccessingIndexes newOut;
if (instruction.def.empty())
newOut = instruction.in;
else if (instruction.in.empty())
newOut = instruction.def;
else
{
for (auto& [arrayName, accessSet] : instruction.def)
{
if (instruction.in.find(arrayName) != instruction.in.end())
newOut[arrayName] = instruction.def[arrayName].Union(instruction.in[arrayName]);
else
newOut[arrayName] = accessSet;
}
for (auto& [arrayName, accessSet] : instruction.in)
{
if (newOut.find(arrayName) == newOut.end())
{
newOut[arrayName] = accessSet;
}
}
}
instruction.out = move(newOut);
}
if (!block->instructions.empty())
block->array_out = block->instructions.back().out;
}
static void SolveDataFlowTopologically(Region* DFG)
{
for (Region* b : DFG->getBasickBlocks())
{
collapsed.insert(b);
SolveForBasickBlock(b);
}
} }
static void SolveDataFlow(Region* DFG) static void SolveDataFlow(Region* DFG)
{ {
if (!DFG) if (!DFG)
return; return;
SolveDataFlowIteratively(DFG);
for (Region* subRegion : DFG->getSubRegions()) for (Region* subRegion : DFG->getSubRegions())
{
SolveDataFlow(subRegion); 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); Collapse(DFG);
} }
static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>& declaredDims) map<LoopGraph*, ArrayAccessingIndexes> FindPrivateArrays(map<string, vector<LoopGraph*>> &loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
{ {
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());
SgSubscriptExp* subscriptExpr = isSgSubscriptExp(sizeExpr);
uint64_t dimLength;
if (sizeExpr && sizeExpr->variant() == INT_VAL)
dimLength = stol(sizeExpr->unparse());
else if (constValSymb)
dimLength = stol(constValSymb->constantValue()->unparse());
else if (subscriptExpr)
{
dimLength = stol(subscriptExpr->rhs()->unparse()) - stol(subscriptExpr->lhs()->unparse());
}
else
return false;
if (dimLength == 0)
return false;
declaredDims.push_back(dimLength);
}
return true;
}
static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym)
{
if (!arrSym)
return nullptr;
for (auto& [key, val] : declaredArrays)
{
DIST::Array* distArr = val.first;
if (!distArr)
continue;
Symbol* declSym = distArr->GetDeclSymbol();
if (!declSym)
continue;
SgSymbol* sgDecl = declSym->GetOriginal();
if (sgDecl && isEqSymbols(sgDecl, arrSym))
return distArr;
}
return nullptr;
}
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 || !arrayRef->symbol())
return false;
vector<uint64_t> declaredDims;
declaredDims.reserve(dimCount);
DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol());
if (distArr && distArr->GetDimSize() == (int)dimCount)
{
const auto& sizes = distArr->GetSizes();
bool valid = true;
for (size_t i = 0; i < dimCount && valid; ++i)
{
int lo = sizes[i].first;
int hi = sizes[i].second;
if (lo > hi)
valid = false;
else
declaredDims.push_back((uint64_t)(hi - lo + 1));
}
if (valid && declaredDims.size() == dimCount)
{
vector<ArrayDimension> testArray(dimCount);
for (size_t i = 0; i < dimCount; i++)
testArray[i] = { 1, 1, declaredDims[i], nullptr };
return AccessingSet({ testArray }).Diff(array).GetElements().empty();
}
}
return false;
}
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;
std::cout << "First bp\n";
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; map<LoopGraph*, ArrayAccessingIndexes> result;
for (const auto& [fileName, loops] : loopGraph) for (const auto& [loopName, loops] : loopGraph)
{ {
SgFile::switchToFile(fileName);
for (const auto& loop : loops) for (const auto& loop : loops)
{ {
if (!loop->isFor()) for (const auto& [funcInfo, blocks]: FullIR)
continue; {
SgStatement* search_func = loop->loop->GetOriginal(); Region* loopRegion = new Region(loop, blocks);
SolveDataFlow(loopRegion);
while (search_func && (!isSgProgHedrStmt(search_func))) result[loop] = loopRegion->array_priv;
search_func = search_func->controlParent(); delete(loopRegion);
for (const auto& [funcInfo, blocks] : FullIR)
{
if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func)
{
Region* loopRegion;
try
{
loopRegion = new Region(loop, blocks);
}
catch (...)
{
continue;
}
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;
for (SgStatement* st : statementsToRemove) }
{
SgFile::switchToFile(st->fileName());
st->deleteStmt();
}
for (auto& [filename, statements] : expToChange)
{
SgFile::switchToFile(filename);
for (auto& [statement, statementCopy] : statements)
{
statement->insertStmtBefore(*statementCopy, *statement->controlParent());
statement->deleteStmt();
}
}
}

View File

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

View File

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

View File

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

View File

@@ -1,14 +1,13 @@
#include <algorithm> #include<vector>
#include <vector> #include<map>
#include <map> #include<unordered_set>
#include <unordered_set> #include<unordered_map>
#include <unordered_map> #include<string>
#include <string>
#include <numeric> #include <numeric>
#include <iostream>
#include "range_structures.h" #include "range_structures.h"
#include "region.h" #include "region.h"
#include "SgUtils.h" #include "SgUtils.h"
using namespace std; using namespace std;
@@ -23,7 +22,7 @@ static bool isParentStmt(SgStatement* stmt, SgStatement* parent)
} }
/*returns head block and loop*/ /*returns head block and loop*/
static pair<SAPFOR::BasicBlock*, unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const vector<SAPFOR::BasicBlock*> blocks) pair<SAPFOR::BasicBlock*, unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const vector<SAPFOR::BasicBlock*> blocks)
{ {
unordered_set<SAPFOR::BasicBlock*> block_loop; unordered_set<SAPFOR::BasicBlock*> block_loop;
SAPFOR::BasicBlock* head_block = nullptr; SAPFOR::BasicBlock* head_block = nullptr;
@@ -62,14 +61,14 @@ static void BuildLoopIndex(map<string, LoopGraph*>& loopForIndex, LoopGraph* loo
static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, LoopGraph*>& loopForIndex) { static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, LoopGraph*>& loopForIndex) {
unordered_set<SAPFOR::Argument*> args = { block->getInstructions()[pos]->getInstruction()->getArg1() }; unordered_set<SAPFOR::Argument*> args = { block->getInstructions()[pos]->getInstruction()->getArg1() };
for (int i = pos - 1; i >= 0; i--) for (int i = pos - 1; i >= 0; i--)
{ {
SAPFOR::Argument* res = block->getInstructions()[i]->getInstruction()->getResult(); SAPFOR::Argument* res = block->getInstructions()[i]->getInstruction()->getResult();
if (res && args.find(res) != args.end()) if (res && args.find(res) != args.end())
{ {
SAPFOR::Argument* arg1 = block->getInstructions()[i]->getInstruction()->getArg1(); SAPFOR::Argument* arg1 = block->getInstructions()[i]->getInstruction()->getArg1();
SAPFOR::Argument* arg2 = block->getInstructions()[i]->getInstruction()->getArg2(); SAPFOR::Argument* arg2 = block->getInstructions()[i]->getInstruction()->getArg2();
if (arg1) if (arg1)
{ {
string name = arg1->getValue(); string name = arg1->getValue();
int idx = name.find('%'); int idx = name.find('%');
@@ -93,7 +92,7 @@ static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, Loop
return ""; return "";
} }
static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use, Region* region) { static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use) {
auto instructions = block->getInstructions(); auto instructions = block->getInstructions();
map<string, LoopGraph*> loopForIndex; map<string, LoopGraph*> loopForIndex;
BuildLoopIndex(loopForIndex, loop); BuildLoopIndex(loopForIndex, loop);
@@ -105,37 +104,15 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
auto operation = instruction->getInstruction()->getOperation(); auto operation = instruction->getInstruction()->getOperation();
auto type = instruction->getInstruction()->getArg1()->getType(); 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) if ((operation == SAPFOR::CFG_OP::STORE || operation == SAPFOR::CFG_OP::LOAD) && type == SAPFOR::CFG_ARG_TYPE::ARRAY)
{ {
vector<SAPFOR::Argument*> index_vars; vector<SAPFOR::Argument*> index_vars;
vector<int> refPos; vector<int> refPos;
string array_name = instruction->getInstruction()->getArg1()->getValue(); string array_name;
if (operation == SAPFOR::CFG_OP::STORE)
array_name = instruction->getInstruction()->getArg1()->getValue();
else
array_name = instruction->getInstruction()->getArg2()->getValue();
int j = i - 1; int j = i - 1;
while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF) while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF)
@@ -150,151 +127,75 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
vector<ArrayDimension> accessPoint(n); vector<ArrayDimension> accessPoint(n);
auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression());
if (!ref) vector<pair<int, int>> coefsForDims;
continue;
int fillCount = 0;
vector<pair<int, int>> coeffsForDims;
int subs = ref->numberOfSubscripts();
for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i) for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i)
{ {
const vector<int*>& coeffs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL }); const vector<int*>& coefs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
if (coeffs.size() == 1) if (coefs.size() == 1)
{ {
const pair<int, int> coef(coeffs[0][0], coeffs[0][1]); const pair<int, int> coef(coefs[0][0], coefs[0][1]);
coeffsForDims.push_back(coef); coefsForDims.push_back(coef);
} }
} }
coeffsForDims = { coeffsForDims.rbegin(), coeffsForDims.rend() };
while (!index_vars.empty() && !refPos.empty() && !coeffsForDims.empty()) if(coefsForDims.empty())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
while (!index_vars.empty())
{ {
auto var = index_vars.back(); auto var = index_vars.back();
int currentVarPos = refPos.back(); int currentVarPos = refPos.back();
pair<int, int> currentCoefs = coefsForDims.back();
ArrayDimension current_dim; ArrayDimension current_dim;
if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST) if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST)
current_dim = { stoul(var->getValue()), 1, 1, ref }; current_dim = { stoul(var->getValue()), 1, 1 };
else else
{ {
string name, full_name = var->getValue(); string name, full_name = var->getValue();
int pos = full_name.find('%'); int pos = full_name.find('%');
LoopGraph* currentLoop; LoopGraph* currentLoop;
if (pos != -1) if (pos != -1)
{ {
name = full_name.substr(pos + 1); name = full_name.substr(pos + 1);
if (loopForIndex.find(name) != loopForIndex.end()) if (loopForIndex.find(name) != loopForIndex.end())
currentLoop = loopForIndex[name]; currentLoop = loopForIndex[name];
else else
return -1; return -1;
} }
else else
{ {
name = FindIndexName(currentVarPos, block, loopForIndex); name = FindIndexName(currentVarPos, block, loopForIndex);
if (name == "") if (name == "")
return -1; return -1;
if (loopForIndex.find(name) != loopForIndex.end()) if (loopForIndex.find(name) != loopForIndex.end())
currentLoop = loopForIndex[name]; currentLoop = loopForIndex[name];
else else
return -1; return -1;
} }
uint64_t start = coeffsForDims.back().second * currentLoop->startVal + coeffsForDims.back().first; uint64_t start = currentLoop->startVal * currentCoefs.first + currentCoefs.second;
uint64_t step = currentLoop->stepVal; uint64_t step = currentCoefs.first;
uint64_t iters = currentLoop->calculatedCountOfIters; current_dim = { start, step, (uint64_t)currentLoop->calculatedCountOfIters };
current_dim = { start, step, iters, ref };
} }
if (current_dim.step != 0 && current_dim.tripCount != 0) accessPoint[n - index_vars.size()] = current_dim;
{
accessPoint[n - index_vars.size()] = current_dim;
fillCount++;
}
index_vars.pop_back(); index_vars.pop_back();
refPos.pop_back(); refPos.pop_back();
coeffsForDims.pop_back(); coefsForDims.pop_back();
} }
if (fillCount == accessPoint.size()) if (operation == SAPFOR::CFG_OP::STORE)
{ def[array_name].Insert(accessPoint);
RegionInstruction instruction; else
if (operation == SAPFOR::CFG_OP::STORE) use[array_name].Insert(accessPoint);
{
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; 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);
}
bool HasCycle(Region* block, const std::unordered_set<Region*>& cycleBlocks, std::unordered_set<Region*>& visitedBlocks)
{
if (visitedBlocks.find(block) != visitedBlocks.end())
return true;
visitedBlocks.insert(block);
for (Region* nextBlock : block->getNextRegions())
{
if (cycleBlocks.find(nextBlock) != cycleBlocks.end() && HasCycle(nextBlock, cycleBlocks, visitedBlocks))
return true;
}
return false;
}
bool TopologySort(std::vector<Region*>& basikBlocks, Region* header)
{
unordered_set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end());
unordered_set<Region*> visitedBlocks;
if (HasCycle(header, cycleBlocks, visitedBlocks))
return false;
vector<Region*> result;
DFS(header, result, cycleBlocks);
reverse(result.begin(), result.end());
basikBlocks = move(result);
return true;
}
static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet) static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet)
{ {
for (SAPFOR::BasicBlock* block : blockSet) for (SAPFOR::BasicBlock* block : blockSet)
@@ -302,38 +203,32 @@ static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegi
for (SAPFOR::BasicBlock* nextBlock : block->getNext()) for (SAPFOR::BasicBlock* nextBlock : block->getNext())
if (bbToRegion.find(nextBlock) != bbToRegion.end()) if (bbToRegion.find(nextBlock) != bbToRegion.end())
bbToRegion[block]->addNextRegion(bbToRegion[nextBlock]); bbToRegion[block]->addNextRegion(bbToRegion[nextBlock]);
for (SAPFOR::BasicBlock* prevBlock : block->getPrev()) for (SAPFOR::BasicBlock* prevBlock : block->getPrev())
if (bbToRegion.find(prevBlock) != bbToRegion.end()) if (bbToRegion.find(prevBlock) != bbToRegion.end())
bbToRegion[block]->addPrevRegion(bbToRegion[prevBlock]); bbToRegion[block]->addPrevRegion(bbToRegion[prevBlock]);
} }
} }
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion) static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, const unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
{ {
Region* region = new Region; Region* region = new Region;
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks);
RemoveHeaderConnection(header, blockSet, bbToRegion);
if (bbToRegion.find(header) != bbToRegion.end()) if (bbToRegion.find(header) != bbToRegion.end())
region->setHeader(bbToRegion.at(header)); region->setHeader(bbToRegion.at(header));
else else
{ {
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return NULL; return NULL;
} }
for (SAPFOR::BasicBlock* block : blockSet) for (SAPFOR::BasicBlock* block : blockSet)
if (bbToRegion.find(block) != bbToRegion.end()) if (bbToRegion.find(block) != bbToRegion.end())
region->addBasickBlocks(bbToRegion.at(block)); region->addBasickBlocks(bbToRegion.at(block));
for (LoopGraph* childLoop : loop->children) for (LoopGraph* childLoop : loop->children)
{
if (!childLoop->isFor())
continue;
region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion));
}
if (!TopologySort(region->getBasickBlocks(), region->getHeader()))
throw std::runtime_error("Unnoticed cycle");
return region; return region;
} }
@@ -344,20 +239,13 @@ Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks)
for (auto poiner : blockSet) for (auto poiner : blockSet)
{ {
bbToRegion[poiner] = new Region(*poiner); bbToRegion[poiner] = new Region(*poiner);
this->basickBlocks.push_back(bbToRegion[poiner]); this->basickBlocks.insert(bbToRegion[poiner]);
GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use, bbToRegion[poiner]); GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use);
} }
this->header = bbToRegion[header]; this->header = bbToRegion[header];
SetConnections(bbToRegion, blockSet); SetConnections(bbToRegion, blockSet);
RemoveHeaderConnection(header, blockSet, bbToRegion);
//create subRegions //create subRegions
for (LoopGraph* childLoop : loop->children) for (LoopGraph* childLoop : loop->children)
{
if (!childLoop->isFor())
continue;
subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion));
} }
if (!TopologySort(basickBlocks, this->header))
throw std::runtime_error("Unnoticed cycle");
}

View File

@@ -8,11 +8,6 @@
#include "graph_loops.h" #include "graph_loops.h"
#include "CFGraph/CFGraph.h" #include "CFGraph/CFGraph.h"
struct RegionInstruction
{
ArrayAccessingIndexes def, use, in, out;
};
class Region : public SAPFOR::BasicBlock { class Region : public SAPFOR::BasicBlock {
public: public:
Region() { header = nullptr; } Region() { header = nullptr; }
@@ -25,25 +20,13 @@ public:
void setHeader(Region* region) { header = region; } void setHeader(Region* region) { header = region; }
std::vector<Region*>& getBasickBlocks() { return basickBlocks; } std::unordered_set<Region*>& getBasickBlocks() { return basickBlocks; }
void addBasickBlocks(Region* region) { basickBlocks.push_back(region); } void addBasickBlocks(Region* region) { basickBlocks.insert(region); }
const std::unordered_set<Region*>& getPrevRegions() { return prevRegions; } 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); } void addPrevRegion(Region* region) { prevRegions.insert(region); }
@@ -65,20 +48,13 @@ public:
void addSubRegions(Region* region) { subRegions.insert(region); } void addSubRegions(Region* region) { subRegions.insert(region); }
std::vector<RegionInstruction> instructions;
ArrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv; ArrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv;
private: private:
std::vector<Region*> basickBlocks; std::unordered_set<Region*> subRegions, basickBlocks;
std::unordered_set<Region*> subRegions;
/*next Region which is BB for current BB Region*/ /*next Region which is BB for current BB Region*/
std::unordered_set<Region*> nextRegions; std::unordered_set<Region*> nextRegions;
/*prev Regions which is BBs for current BB Region*/ /*prev Regions which is BBs for current BB Region*/
std::unordered_set<Region*> prevRegions; std::unordered_set<Region*> prevRegions;
Region* header; Region* header;
}; };
bool HasCycle(Region* block, const std::unordered_set<Region*>& cycleBlocks, std::unordered_set<Region*>& visitedBlocks);
bool TopologySort(std::vector<Region*>& basikBlocks, Region* header);

View File

@@ -23,7 +23,6 @@
#include "ParallelizationRegions/ParRegions_func.h" #include "ParallelizationRegions/ParRegions_func.h"
#include "ParallelizationRegions/resolve_par_reg_conflicts.h" #include "ParallelizationRegions/resolve_par_reg_conflicts.h"
#include "ParallelizationRegions/expand_extract_reg.h" #include "ParallelizationRegions/expand_extract_reg.h"
#include "ParallelizationRegions/merge_regions.h"
#include "Distribution/Distribution.h" #include "Distribution/Distribution.h"
#include "Distribution/GraphCSR.h" #include "Distribution/GraphCSR.h"
@@ -47,7 +46,6 @@
#include "DynamicAnalysis/gCov_parser_func.h" #include "DynamicAnalysis/gCov_parser_func.h"
#include "DynamicAnalysis/createParallelRegions.h" #include "DynamicAnalysis/createParallelRegions.h"
#include "ArrayConstantPropagation/propagation.h"
#include "DirectiveProcessing/directive_analyzer.h" #include "DirectiveProcessing/directive_analyzer.h"
#include "DirectiveProcessing/directive_creator.h" #include "DirectiveProcessing/directive_creator.h"
#include "DirectiveProcessing/insert_directive.h" #include "DirectiveProcessing/insert_directive.h"
@@ -91,7 +89,7 @@
#include "Transformations/DeadCodeRemoving/dead_code.h" #include "Transformations/DeadCodeRemoving/dead_code.h"
#include "Transformations/RenameSymbols/rename_symbols.h" #include "Transformations/RenameSymbols/rename_symbols.h"
#include "Transformations/FunctionInlining/inliner.h" #include "Transformations/FunctionInlining/inliner.h"
#include "Transformations/MoveOperators/move_operators.h" #include "Transformations/SwapOperators/swap_operators.h"
#include "ProjectParameters/projectParameters.h" #include "ProjectParameters/projectParameters.h"
@@ -282,8 +280,7 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext()) for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
if (isSPF_stat(st)) // except sapfor parallel regions and if attributes dont move 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 (st->variant() != SPF_PARALLEL_REG_DIR && st->variant() != SPF_END_PARALLEL_REG_DIR)
if (insertedPrivates.find(st) == insertedPrivates.end()) toDel.push_back(st);
toDel.push_back(st);
for (auto& elem : toDel) for (auto& elem : toDel)
elem->deleteStmt(); elem->deleteStmt();
@@ -742,7 +739,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == LOOP_DATA_DEPENDENCIES) else if (curr_regime == LOOP_DATA_DEPENDENCIES)
doDependenceAnalysisOnTheFullFile(file, 1, 1, 1); doDependenceAnalysisOnTheFullFile(file, 1, 1, 1);
else if (curr_regime == REMOVE_DVM_DIRS || curr_regime == REMOVE_DVM_DIRS_TO_COMMENTS || curr_regime == REMOVE_SPF_DIRS) { else if (curr_regime == REMOVE_DVM_DIRS || curr_regime == REMOVE_DVM_DIRS_TO_COMMENTS || curr_regime == REMOVE_SPF_DIRS) {
bool removeDvm = (curr_regime == REMOVE_DVM_DIRS); bool removeDvm = (curr_regime == REMOVE_DVM_DIRS || curr_regime == REMOVE_DVM_DIRS);
bool removeSpf = (curr_regime == REMOVE_SPF_DIRS); bool removeSpf = (curr_regime == REMOVE_SPF_DIRS);
bool toComment = (curr_regime == REMOVE_DVM_DIRS_TO_COMMENTS); bool toComment = (curr_regime == REMOVE_DVM_DIRS_TO_COMMENTS);
removeDvmSpfDirectives(file, removeDvm, removeSpf, toComment); removeDvmSpfDirectives(file, removeDvm, removeSpf, toComment);
@@ -943,8 +940,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
internalExit = err; internalExit = err;
} }
} }
else if (curr_regime == MOVE_OPERATORS) else if (curr_regime == SWAP_OPERATORS)
moveOperators(file, fullIR, countOfTransform); runSwapOperators(file, loopGraph, fullIR, countOfTransform);
else if (curr_regime == PRIVATE_REMOVING_ANALYSIS) else if (curr_regime == PRIVATE_REMOVING_ANALYSIS)
{ {
auto itFound = loopGraph.find(file->filename()); auto itFound = loopGraph.find(file->filename());
@@ -1025,6 +1022,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
if(func->funcPointer->variant() != ENTRY_STAT) if(func->funcPointer->variant() != ENTRY_STAT)
countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks); countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
} }
else if (curr_regime == FIND_PRIVATE_ARRAYS)
FindPrivateArrays(loopGraph, fullIR);
else if (curr_regime == TEST_PASS) else if (curr_regime == TEST_PASS)
{ {
//test pass //test pass
@@ -1042,7 +1041,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
PRIVATE_ARRAYS_EXPANSION, PRIVATE_ARRAYS_EXPANSION,
PRIVATE_ARRAYS_SHRINKING, PRIVATE_ARRAYS_SHRINKING,
REMOVE_DEAD_CODE, REMOVE_DEAD_CODE,
MOVE_OPERATORS }; SWAP_OPERATORS };
if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end()) if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end())
{ {
@@ -1265,8 +1264,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
moveAllocatesInterproc(arrayLinksByFuncCalls); moveAllocatesInterproc(arrayLinksByFuncCalls);
propagateRegionInfo(declaredArrays, arrayLinksByFuncCalls, subs_parallelRegions);
removeDistrStateFromDeadFunctions(allFuncInfo, declaredArrays); removeDistrStateFromDeadFunctions(allFuncInfo, declaredArrays);
propagateArrayFlags(arrayLinksByFuncCalls, declaredArrays, SPF_messages); propagateArrayFlags(arrayLinksByFuncCalls, declaredArrays, SPF_messages);
} }
@@ -1684,11 +1681,30 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
findDeadFunctionsAndFillCalls(allFuncInfo_IR, SPF_messages, true); findDeadFunctionsAndFillCalls(allFuncInfo_IR, SPF_messages, true);
else if (curr_regime == GET_ALL_ARRAY_DECL) else if (curr_regime == GET_ALL_ARRAY_DECL)
{ {
if (ignoreArrayDistributeState) bool hasNonDefaultReg = false;
for (auto &elem : subs_parallelRegions)
if (elem->GetName() != "DEFAULT")
hasNonDefaultReg = true;
if (hasNonDefaultReg)
{ {
for (auto array : declaredArrays) for (auto array : declaredArrays)
array.second.first->SetDistributeFlag(DIST::NO_DISTR); {
if (array.second.first->GetRegionsName().size() == 0)
array.second.first->SetDistributeFlag(DIST::NO_DISTR);
else if (array.second.first->GetRegionsName().size() == 1)
{
string regName = *array.second.first->GetRegionsName().begin();
convertToLower(regName);
if (regName == "default")
array.second.first->SetDistributeFlag(DIST::NO_DISTR);
}
}
} }
if (ignoreArrayDistributeState)
for (auto array : declaredArrays)
array.second.first->SetDistributeFlag(DIST::NO_DISTR);
} }
else if (curr_regime == GCOV_PARSER) else if (curr_regime == GCOV_PARSER)
{ {
@@ -1877,7 +1893,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
findParameters(parametersOfProject, fullIR, declaredArrays); findParameters(parametersOfProject, fullIR, declaredArrays);
else if (curr_regime == BUILD_IR) else if (curr_regime == BUILD_IR)
{ {
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings()); auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
for (auto& byFunc : CFG_forFile) for (auto& byFunc : CFG_forFile)
fullIR[byFunc.first].insert(fullIR[byFunc.first].end(), byFunc.second.begin(), byFunc.second.end()); fullIR[byFunc.first].insert(fullIR[byFunc.first].end(), byFunc.second.begin(), byFunc.second.end());
@@ -1904,12 +1920,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
} }
else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS) else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS)
transformAssumedSizeParameters(allFuncInfo); transformAssumedSizeParameters(allFuncInfo);
else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS)
findPrivateArrays(loopGraph, fullIR, insertedPrivates);
else if (curr_regime == MERGE_REGIONS)
mergeRegions(parallelRegions, allFuncInfo);
else if (curr_regime == ARRAY_PROPAGATION)
arrayConstantPropagation(project);
const float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - timeForPass).count() / 1000.; const float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - timeForPass).count() / 1000.;
const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.; const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.;
@@ -2328,7 +2338,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case INSERT_NO_DISTR_FLAGS_FROM_GUI: case INSERT_NO_DISTR_FLAGS_FROM_GUI:
case PRIVATE_REMOVING: case PRIVATE_REMOVING:
case RENAME_INLCUDES: case RENAME_INLCUDES:
case MOVE_OPERATORS: case SWAP_OPERATORS:
runAnalysis(*project, curr_regime, true, "", folderName); runAnalysis(*project, curr_regime, true, "", folderName);
break; break;
case INLINE_PROCEDURES: case INLINE_PROCEDURES:
@@ -2364,12 +2374,10 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case FIX_COMMON_BLOCKS: case FIX_COMMON_BLOCKS:
case TEST_PASS: case TEST_PASS:
case SET_IMPLICIT_NONE: case SET_IMPLICIT_NONE:
case MERGE_REGIONS:
runAnalysis(*project, curr_regime, false); runAnalysis(*project, curr_regime, false);
case SUBST_EXPR_RD_AND_UNPARSE: case SUBST_EXPR_RD_AND_UNPARSE:
case SUBST_EXPR_AND_UNPARSE: case SUBST_EXPR_AND_UNPARSE:
case REMOVE_DEAD_CODE_AND_UNPARSE: case REMOVE_DEAD_CODE_AND_UNPARSE:
case FIND_PRIVATE_ARRAYS:
if (folderName) if (folderName)
runAnalysis(*project, UNPARSE_FILE, true, "", folderName); runAnalysis(*project, UNPARSE_FILE, true, "", folderName);
else else
@@ -2510,8 +2518,8 @@ int main(int argc, char **argv)
out_free_form = 1; out_free_form = 1;
out_line_unlimit = 1; out_line_unlimit = 1;
} }
/*else if (string(curr_arg) == "-sh") else if (string(curr_arg) == "-sh")
staticShadowAnalysis = 1;*/ staticShadowAnalysis = 1;
else if (string(curr_arg) == "-shWidth") else if (string(curr_arg) == "-shWidth")
{ {
i++; i++;
@@ -2631,7 +2639,7 @@ int main(int argc, char **argv)
} }
} }
if (curr_regime == INSERT_PARALLEL_DIRS_NODIST || curr_regime == FIND_PRIVATE_ARRAYS) if (curr_regime == INSERT_PARALLEL_DIRS_NODIST)
{ {
ignoreArrayDistributeState = true; ignoreArrayDistributeState = true;
sharedMemoryParallelization = 1; sharedMemoryParallelization = 1;

View File

@@ -88,8 +88,6 @@ enum passes {
REMOVE_DVM_INTERVALS, REMOVE_DVM_INTERVALS,
VERIFY_DVM_DIRS, VERIFY_DVM_DIRS,
MERGE_REGIONS,
REMOVE_DIST_ARRAYS_FROM_IO, REMOVE_DIST_ARRAYS_FROM_IO,
SUBST_EXPR, SUBST_EXPR,
@@ -124,7 +122,7 @@ enum passes {
CREATE_INTER_TREE, CREATE_INTER_TREE,
INSERT_INTER_TREE, INSERT_INTER_TREE,
MOVE_OPERATORS, SWAP_OPERATORS,
SHADOW_GROUPING, SHADOW_GROUPING,
INLINE_PROCEDURES, INLINE_PROCEDURES,
@@ -187,11 +185,9 @@ enum passes {
SET_IMPLICIT_NONE, SET_IMPLICIT_NONE,
RENAME_INLCUDES, RENAME_INLCUDES,
FIND_PRIVATE_ARRAYS_ANALYSIS,
FIND_PRIVATE_ARRAYS, FIND_PRIVATE_ARRAYS,
TRANSFORM_ASSUMED_SIZE_PARAMETERS, TRANSFORM_ASSUMED_SIZE_PARAMETERS,
ARRAY_PROPAGATION,
TEST_PASS, TEST_PASS,
EMPTY_PASS EMPTY_PASS
@@ -275,7 +271,6 @@ static void setPassValues()
passNames[VERIFY_DVM_DIRS] = "VERIFY_DVM_DIRS"; passNames[VERIFY_DVM_DIRS] = "VERIFY_DVM_DIRS";
passNames[REMOVE_DVM_DIRS_TO_COMMENTS] = "REMOVE_DVM_DIRS_TO_COMMENTS"; passNames[REMOVE_DVM_DIRS_TO_COMMENTS] = "REMOVE_DVM_DIRS_TO_COMMENTS";
passNames[REMOVE_SPF_DIRS] = "REMOVE_SPF_DIRS"; passNames[REMOVE_SPF_DIRS] = "REMOVE_SPF_DIRS";
passNames[MERGE_REGIONS] = "MERGE_REGIONS";
passNames[REMOVE_DIST_ARRAYS_FROM_IO] = "REMOVE_DIST_ARRAYS_FROM_IO"; passNames[REMOVE_DIST_ARRAYS_FROM_IO] = "REMOVE_DIST_ARRAYS_FROM_IO";
passNames[SUBST_EXPR] = "SUBST_EXPR"; passNames[SUBST_EXPR] = "SUBST_EXPR";
passNames[SUBST_EXPR_RD] = "SUBST_EXPR_RD"; passNames[SUBST_EXPR_RD] = "SUBST_EXPR_RD";
@@ -326,7 +321,7 @@ static void setPassValues()
passNames[CHECK_PAR_REG_DIR] = "CHECK_PAR_REG_DIR"; passNames[CHECK_PAR_REG_DIR] = "CHECK_PAR_REG_DIR";
passNames[CREATE_INTER_TREE] = "CREATE_INTER_TREE"; passNames[CREATE_INTER_TREE] = "CREATE_INTER_TREE";
passNames[INSERT_INTER_TREE] = "INSERT_INTER_TREE"; passNames[INSERT_INTER_TREE] = "INSERT_INTER_TREE";
passNames[MOVE_OPERATORS] = "MOVE_OPERATORS"; passNames[SWAP_OPERATORS] = "SWAP_OPERATORS";
passNames[CREATE_PARALLEL_REGIONS] = "CREATE_PARALLEL_REGIONS"; passNames[CREATE_PARALLEL_REGIONS] = "CREATE_PARALLEL_REGIONS";
passNames[PRIVATE_REMOVING_ANALYSIS] = "PRIVATE_REMOVING_ANALYSIS"; passNames[PRIVATE_REMOVING_ANALYSIS] = "PRIVATE_REMOVING_ANALYSIS";
passNames[PRIVATE_REMOVING] = "PRIVATE_REMOVING"; passNames[PRIVATE_REMOVING] = "PRIVATE_REMOVING";
@@ -379,11 +374,9 @@ static void setPassValues()
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE"; passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
passNames[RENAME_INLCUDES] = "RENAME_INLCUDES"; passNames[RENAME_INLCUDES] = "RENAME_INLCUDES";
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI"; passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
passNames[FIND_PRIVATE_ARRAYS_ANALYSIS] = "FIND_PRIVATE_ARRAYS_ANALYSIS";
passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS"; passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS";
passNames[TRANSFORM_ASSUMED_SIZE_PARAMETERS] = "TRANSFORM_ASSUMED_SIZE_PARAMETERS"; passNames[TRANSFORM_ASSUMED_SIZE_PARAMETERS] = "TRANSFORM_ASSUMED_SIZE_PARAMETERS";
passNames[ARRAY_PROPAGATION] = "ARRAY_PROPAGATION";
passNames[TEST_PASS] = "TEST_PASS"; passNames[TEST_PASS] = "TEST_PASS";
} }

View File

@@ -19,7 +19,7 @@
extern std::map<std::string, std::string> shortFileNames; extern std::map<std::string, std::string> shortFileNames;
static int activeState = 0; static int activeState = 0;
int staticShadowAnalysis = 1; int staticShadowAnalysis = 0;
int staticPrivateAnalysis = 0; int staticPrivateAnalysis = 0;
int keepDvmDirectives = 0; int keepDvmDirectives = 0;
int keepFiles = 0; int keepFiles = 0;
@@ -175,11 +175,6 @@ std::set<std::tuple<std::string, int, std::string>> parametersOfProject; // [fil
//for GET_MIN_MAX_BLOCK_DIST //for GET_MIN_MAX_BLOCK_DIST
std::pair<int, int> min_max_block = std::make_pair(-1, -1); 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* passNames[EMPTY_PASS + 1];
const char* optionNames[EMPTY_OPTION + 1]; const char* optionNames[EMPTY_OPTION + 1];
bool passNamesWasInit = false; bool passNamesWasInit = false;

View File

@@ -12,7 +12,6 @@ using std::map;
using std::string; using std::string;
using std::vector; using std::vector;
using std::set; using std::set;
using SAPFOR::CFG_Settings;
using std::remove_if; using std::remove_if;
@@ -425,8 +424,7 @@ int removeDeadCode(SgStatement* func,
if (intervalDelEnd->lineNumber() < prog->lineNumber() || intervalDelEnd->lineNumber() > prog->lastNodeOfStmt()->lineNumber()) if (intervalDelEnd->lineNumber() < prog->lineNumber() || intervalDelEnd->lineNumber() > prog->lastNodeOfStmt()->lineNumber())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop }); auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, false, false, false, false), commonBlocks, allFuncs);
auto cfg = buildCFGforCurrentFunc(func, settings, commonBlocks, allFuncs);
if(cfg.size() != 1) if(cfg.size() != 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);

View File

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

View File

@@ -234,65 +234,10 @@ static bool hasDvmParallel(SgStatement *func)
return false; return false;
} }
static map<FuncInfo*, bool> createDvmParallelInfo(const map<string, vector<FuncInfo*>>& allFuncInfo) {
map<FuncInfo*, bool> hasDvmParallelMap;
for (auto& funcByFile : allFuncInfo)
{
if (SgFile::switchToFile(funcByFile.first) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& func : funcByFile.second)
{
SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal());
if (prog == NULL)
continue;
hasDvmParallelMap[func] = hasDvmParallel(prog);
}
}
bool changed = true;
while (changed)
{
changed = false;
for (auto& funcByFile : allFuncInfo)
{
for (auto& func : funcByFile.second)
{
if (!hasDvmParallelMap[func])
{
bool hasParallel = false;
for (auto& callF : func->callsFromV)
{
if (hasDvmParallelMap[callF])
{
hasParallel = true;
break;
}
}
if (hasParallel)
{
changed = true;
hasDvmParallelMap[func] = true;
}
}
}
}
}
return hasDvmParallelMap;
}
void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFuncInfo) void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFuncInfo)
{ {
map<string, vector<int>> assumedSizeArraysByFunc; map<string, vector<int>> assumedSizeArraysByFunc;
const map<FuncInfo*, bool> hasDvmParallelMap = createDvmParallelInfo(allFuncInfo);
for (auto& funcByFile : allFuncInfo) for (auto& funcByFile : allFuncInfo)
{ {
if (SgFile::switchToFile(funcByFile.first) == -1) if (SgFile::switchToFile(funcByFile.first) == -1)
@@ -304,7 +249,7 @@ void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFun
if (prog == NULL) if (prog == NULL)
continue; continue;
if (!hasDvmParallelMap.at(func)) if (!hasDvmParallel(prog))
continue; continue;
vector<SgSymbol*> parNames; vector<SgSymbol*> parNames;
@@ -314,8 +259,7 @@ void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFun
bool hasRefs = false; bool hasRefs = false;
for (int z = 0; z < func->funcParams.countOfPars; ++z) for (int z = 0; z < func->funcParams.countOfPars; ++z)
{ {
if (func->funcParams.parametersT[z] == ARRAY_T || if (func->funcParams.parametersT[z] == ARRAY_T)
func->funcParams.parametersT[z] == STRING_ARRAY_T)
{ {
auto s = prog->parameter(z); auto s = prog->parameter(z);
const string name = s->identifier(); const string name = s->identifier();

View File

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

View File

@@ -16,18 +16,12 @@
struct DeclInfo // for error messages struct DeclInfo // for error messages
{ {
private:
std::string varName; std::string varName;
std::string fileName; std::string fileName;
int lineNum; int lineNum;
public:
DeclInfo() : varName(""), fileName(""), lineNum(0) {}; DeclInfo() : varName(""), fileName(""), lineNum(0) {};
DeclInfo(const std::string& vn, const std::string& fn, int ln) : varName(vn), fileName(fn), lineNum(ln) {}; 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 struct CommConstraint // TODO: add variable attributes
@@ -48,4 +42,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) for (int d = 0; d < dimensions; ++d)
{ {
//по измерениям массива отображение на цикл вложенности d //по измерениям массива отображение на цикл вложенности d
vector<set<pair<int, int>>> coeffsRead[2], coeffsWrite[2]; vector<set<pair<int, int>>> coefsRead[2], coefsWrite[2];
checkNull(currLoop[0], convertFileName(__FILE__).c_str(), __LINE__); checkNull(currLoop[0], convertFileName(__FILE__).c_str(), __LINE__);
checkNull(currLoop[1], 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); auto it = currLoop[k]->readOpsForLoop.find(array);
if (it != currLoop[k]->readOpsForLoop.end()) if (it != currLoop[k]->readOpsForLoop.end())
{ {
if (coeffsRead[k].size() == 0) if (coefsRead[k].size() == 0)
coeffsRead[k].resize(it->second.size()); coefsRead[k].resize(it->second.size());
for (int z = 0; z < it->second.size(); ++z) for (int z = 0; z < it->second.size(); ++z)
if (it->second[z].coefficients.size()) if (it->second[z].coefficients.size())
for (auto& coef : it->second[z].coefficients) for (auto& coef : it->second[z].coefficients)
coeffsRead[k][z].insert(coef.first); coefsRead[k][z].insert(coef.first);
} }
auto itW = currLoop[k]->writeOpsForLoop.find(array); auto itW = currLoop[k]->writeOpsForLoop.find(array);
if (itW != currLoop[k]->writeOpsForLoop.end()) if (itW != currLoop[k]->writeOpsForLoop.end())
{ {
if (coeffsWrite[k].size() == 0) if (coefsWrite[k].size() == 0)
coeffsWrite[k].resize(itW->second.size()); coefsWrite[k].resize(itW->second.size());
for (int z = 0; z < itW->second.size(); ++z) for (int z = 0; z < itW->second.size(); ++z)
if (itW->second[z].coefficients.size()) if (itW->second[z].coefficients.size())
for (auto& coef : itW->second[z].coefficients) for (auto& coef : itW->second[z].coefficients)
coeffsWrite[k][z].insert(coef.first); coefsWrite[k][z].insert(coef.first);
} }
} }
//нет записей, значит нет зависимости //нет записей, значит нет зависимости
bool nulWrite = true; bool nulWrite = true;
for (auto& wr : coeffsWrite) for (auto& wr : coefsWrite)
for (auto& elem : wr) for (auto& elem : wr)
if (elem.size() != 0) if (elem.size() != 0)
nulWrite = false; nulWrite = false;
@@ -1168,62 +1168,62 @@ static bool hasDependenciesBetweenArrays(LoopGraph* firstLoop, LoopGraph* loop,
// если чтение в одном цикле и запись (и наоборот) в другом идут по разным правилам, то пока что это зависимость. // если чтение в одном цикле и запись (и наоборот) в другом идут по разным правилам, то пока что это зависимость.
// здесь можно уточнить. // здесь можно уточнить.
const int len = std::max(coeffsWrite[0].size(), coeffsRead[0].size()); const int len = std::max(coefsWrite[0].size(), coefsRead[0].size());
int countW[2] = { 0, 0 }; int countW[2] = { 0, 0 };
int countR[2] = { 0, 0 }; int countR[2] = { 0, 0 };
for (int L = 0; L < 2; ++L) for (int L = 0; L < 2; ++L)
for (int z = 0; z < coeffsWrite[L].size(); ++z) for (int z = 0; z < coefsWrite[L].size(); ++z)
countW[L] += (coeffsWrite[L][z].size() ? 1 : 0); countW[L] += (coefsWrite[L][z].size() ? 1 : 0);
for (int L = 0; L < 2; ++L) for (int L = 0; L < 2; ++L)
for (int z = 0; z < coeffsRead[L].size(); ++z) for (int z = 0; z < coefsRead[L].size(); ++z)
countR[L] += (coeffsRead[L][z].size() ? 1 : 0); countR[L] += (coefsRead[L][z].size() ? 1 : 0);
for (int p = 0; p < len; ++p) for (int p = 0; p < len; ++p)
{ {
if (coeffsWrite[1].size() && coeffsWrite[0].size()) if (coefsWrite[1].size() && coefsWrite[0].size())
if (coeffsWrite[0][p].size() != 0 && coeffsWrite[1][p].size() != 0) if (coefsWrite[0][p].size() != 0 && coefsWrite[1][p].size() != 0)
if (coeffsWrite[0][p] != coeffsWrite[1][p]) if (coefsWrite[0][p] != coefsWrite[1][p])
return true; return true;
if (coeffsRead[1].size() && coeffsWrite[0].size()) if (coefsRead[1].size() && coefsWrite[0].size())
if (coeffsWrite[0][p].size() != 0 && coeffsRead[1][p].size() != 0) if (coefsWrite[0][p].size() != 0 && coefsRead[1][p].size() != 0)
if (coeffsWrite[0][p] != coeffsRead[1][p]) if (coefsWrite[0][p] != coefsRead[1][p])
return true; return true;
if (coeffsWrite[1].size() && coeffsRead[0].size()) if (coefsWrite[1].size() && coefsRead[0].size())
if (coeffsWrite[1][p].size() != 0 && coeffsRead[0][p].size() != 0) if (coefsWrite[1][p].size() != 0 && coefsRead[0][p].size() != 0)
if (coeffsWrite[1][p] != coeffsRead[0][p]) if (coefsWrite[1][p] != coefsRead[0][p])
return true; return true;
//отображение на разные измерения //отображение на разные измерения
if (coeffsWrite[1].size() && coeffsWrite[0].size()) if (coefsWrite[1].size() && coefsWrite[0].size())
{ {
if (coeffsWrite[0][p].size() != 0 && coeffsWrite[1][p].size() == 0 && countW[1] || if (coefsWrite[0][p].size() != 0 && coefsWrite[1][p].size() == 0 && countW[1] ||
coeffsWrite[0][p].size() == 0 && coeffsWrite[1][p].size() != 0 && countW[0]) coefsWrite[0][p].size() == 0 && coefsWrite[1][p].size() != 0 && countW[0])
return true; return true;
} }
if (coeffsRead[1].size() && coeffsWrite[0].size()) if (coefsRead[1].size() && coefsWrite[0].size())
{ {
if (coeffsWrite[0][p].size() != 0 && coeffsRead[1][p].size() == 0 && countR[1] || if (coefsWrite[0][p].size() != 0 && coefsRead[1][p].size() == 0 && countR[1] ||
coeffsWrite[0][p].size() == 0 && coeffsRead[1][p].size() != 0 && countW[0]) coefsWrite[0][p].size() == 0 && coefsRead[1][p].size() != 0 && countW[0])
return true; return true;
} }
if (coeffsWrite[1].size() && coeffsRead[1].size()) if (coefsWrite[1].size() && coefsRead[1].size())
{ {
if (coeffsWrite[1][p].size() != 0 && coeffsRead[0][p].size() == 0 && countR[0] || if (coefsWrite[1][p].size() != 0 && coefsRead[0][p].size() == 0 && countR[0] ||
coeffsWrite[1][p].size() == 0 && coeffsRead[0][p].size() != 0 && countW[1]) coefsWrite[1][p].size() == 0 && coefsRead[0][p].size() != 0 && countW[1])
return true; return true;
} }
//где то нет правил отображения вообще, но есть факт его наличия. //где то нет правил отображения вообще, но есть факт его наличия.
if ( ((coeffsWrite[0].size() == 0 && coeffsRead[0].size() == 0) && (countW[0] == 0 && countR[0] == 0)) if ( ((coefsWrite[0].size() == 0 && coefsRead[0].size() == 0) && (countW[0] == 0 && countR[0] == 0))
|| ||
((coeffsWrite[1].size() == 0 && coeffsRead[1].size() == 0) && (countW[1] == 0 && countR[1] == 0)) ) ((coefsWrite[1].size() == 0 && coefsRead[1].size() == 0) && (countW[1] == 0 && countR[1] == 0)) )
return true; return true;
} }

View File

@@ -19,7 +19,6 @@ using std::pair;
using std::make_pair; using std::make_pair;
using std::wstring; using std::wstring;
using std::stack; using std::stack;
using SAPFOR::CFG_Settings;
#define PRINT_SPLITTED_FRAGMENTS 0 #define PRINT_SPLITTED_FRAGMENTS 0
@@ -316,7 +315,7 @@ static map<SgStatement*, pair<set<SgStatement*>, set<SgStatement*>>>
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
map<SAPFOR::Argument*, set<int>> outForCurr; map<SAPFOR::Argument*, set<int>> outForCurr;
buildGenKillForCFG(itCFG->second, funcByName, outForFunc, gen, kill, &genForIR, &killForIR, notInitedGlobals, SAPFOR::CFG_Settings()); buildGenKillForCFG(itCFG->second, funcByName, outForFunc, gen, kill, &genForIR, &killForIR, notInitedGlobals, SAPFOR::CFG_Settings(0));
if (outForFunc.count(byFunc)) if (outForFunc.count(byFunc))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1052,8 +1051,7 @@ int splitLoops(SgFile *file, vector<LoopGraph*> &loopGraphs, vector<Messages> &m
checkNull(listExp, convertFileName(__FILE__).c_str(), __LINE__); checkNull(listExp, convertFileName(__FILE__).c_str(), __LINE__);
int deep = listExp->length(); int deep = listExp->length();
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, SAPFOR::CFG_Settings(true, true), commonBlocks, allFuncInfo);
currIR = buildCFGforCurrentFunc(loop->loop, settings, commonBlocks, allFuncInfo);
totalErr = splitLoop(loop, messages, deep, depInfoForLoopGraph); totalErr = splitLoop(loop, messages, deep, depInfoForLoopGraph);
if (totalErr > 0) if (totalErr > 0)

View File

@@ -1,602 +0,0 @@
#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;
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;
};
for (SgStatement* s : ops)
{
auto itDeps = depsMap.find(s);
if (itDeps == depsMap.end() || itDeps->second.empty())
continue;
int posS = indexIn(order, s);
if (posS < 0)
continue;
int lastDepIdx = -1;
for (SgStatement* dep : itDeps->second)
{
const int j = indexIn(order, dep);
if (j >= 0)
lastDepIdx = max(lastDepIdx, j);
}
if (lastDepIdx < 0)
continue;
if (posS == lastDepIdx + 1)
continue;
order.erase(order.begin() + posS);
int lp = lastDepIdx;
if (posS < lastDepIdx)
lp = lastDepIdx - 1;
const int insertAt = lp + 1;
order.insert(order.begin() + insertAt, 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

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

View File

@@ -504,7 +504,7 @@ static void replaceArrayInFragment(SgSymbol* replace_symb,
} }
} }
static bool ioRegionBorder(SgStatement* stat, SgStatement* last_io_bound) static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound)
{ {
auto var = stat->variant(); auto var = stat->variant();
@@ -535,24 +535,14 @@ static bool ioRegionBorder(SgStatement* stat, SgStatement* last_io_bound)
if (last_io_bound && last_io_bound->lastNodeOfStmt() && last_io_bound->lastNodeOfStmt() == stat) if (last_io_bound && last_io_bound->lastNodeOfStmt() && last_io_bound->lastNodeOfStmt() == stat)
return true; return true;
int parent_var;
if (var == CONTROL_END && border_stats.find(stat->controlParent()->variant()) != border_stats.end()) if (var == CONTROL_END && border_stats.find(stat->controlParent()->variant()) != border_stats.end())
return true; return true;
return false; return false;
} }
FuncInfo* getCurrentFuncInfo(const vector<FuncInfo*>& fileFuncInfo, int line)
{
for (auto* func : fileFuncInfo)
{
if (func->linesNum.first <= line && line <= func->linesNum.second)
return func;
}
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return NULL;
}
void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions, void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
const map<string, vector<FuncInfo*>>& allFuncInfo, const map<string, vector<FuncInfo*>>& allFuncInfo,
map<string, vector<Messages>>& SPF_messages, map<string, vector<Messages>>& SPF_messages,
@@ -572,8 +562,6 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
if (SgFile::switchToFile(current_file_name) == -1) if (SgFile::switchToFile(current_file_name) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
FuncInfo *current_func_info = NULL;
auto func_info_it = allFuncInfo.find(current_file_name); auto func_info_it = allFuncInfo.find(current_file_name);
if (func_info_it == allFuncInfo.end()) if (func_info_it == allFuncInfo.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -600,12 +588,13 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
{ {
curr_stmt = lines.stats.first->GetOriginal(); curr_stmt = lines.stats.first->GetOriginal();
end = lines.stats.second->GetOriginal()->lexNext(); end = lines.stats.second->GetOriginal()->lexNext();
current_func_info = getCurrentFuncInfo(func_info_it->second, curr_stmt->lineNumber());
} }
map<SgSymbol*, set<SgStatement*>> need_replace; map<SgSymbol*, set<SgStatement*>> need_replace;
SgStatement* last_io_bound = NULL; SgStatement* last_io_bound = NULL;
FuncInfo *current_func_info = NULL;
while (curr_stmt != end) while (curr_stmt != end)
{ {
if (!curr_stmt) if (!curr_stmt)
@@ -615,7 +604,18 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
if (var == PROC_HEDR || var == PROG_HEDR || var == FUNC_HEDR) if (var == PROC_HEDR || var == PROG_HEDR || var == FUNC_HEDR)
{ {
current_func_info = getCurrentFuncInfo(func_info_it->second, curr_stmt->lineNumber()); current_func_info = NULL;
for (auto *func_info : func_info_it->second)
{
if (func_info->funcName == curr_stmt->symbol()->identifier())
{
current_func_info = func_info;
break;
}
}
if (!current_func_info)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
curr_stmt = curr_stmt->lexNext(); curr_stmt = curr_stmt->lexNext();
while (curr_stmt && !isSgExecutableStatement(curr_stmt)) while (curr_stmt && !isSgExecutableStatement(curr_stmt))
@@ -628,7 +628,7 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
break; break;
} }
if (ioRegionBorder(curr_stmt, last_io_bound)) if (ioReginBorder(curr_stmt, last_io_bound))
{ {
for (const auto& by_array_to_copy : need_replace) for (const auto& by_array_to_copy : need_replace)
{ {

View File

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

@@ -0,0 +1,6 @@
#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); Pass(DEF_USE_STAGE1) <= Pass(DEF_USE_STAGE2);
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 }); 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 });
Pass(VERIFY_COMMON) <= Pass(FILL_COMMON_BLOCKS);
Pass(BUILD_IR) <= Pass(SUBST_EXPR) <= Pass(SUBST_EXPR_AND_UNPARSE); Pass(BUILD_IR) <= Pass(SUBST_EXPR) <= Pass(SUBST_EXPR_AND_UNPARSE);
Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE); Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE);
list({BUILD_IR, CALL_GRAPH2}) <= Pass(SWAP_OPERATORS);
list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS); list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS);
list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING); list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING);
Pass(RESTORE_LOOP_FROM_ASSIGN) <= list({ SUBST_EXPR_AND_UNPARSE, SUBST_EXPR_RD_AND_UNPARSE }); Pass(RESTORE_LOOP_FROM_ASSIGN) <= list({ SUBST_EXPR_AND_UNPARSE, SUBST_EXPR_RD_AND_UNPARSE });
Pass(FILL_COMMON_BLOCKS) <= Pass(GET_ALL_ARRAY_DECL) <= list({ CALL_GRAPH_IR, INSERT_NO_DISTR_FLAGS_FROM_GUI }); 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 }); 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_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({ FILL_COMMON_BLOCKS, GET_ALL_ARRAY_DECL, PARSE_OMP_DIRS }) <= Pass(PREPROC_SPF); 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);
Pass(CHECK_PAR_REG_DIR) <= Pass(FILL_PARALLEL_REG_IR); Pass(CHECK_PAR_REG_DIR) <= Pass(FILL_PARALLEL_REG_IR);
@@ -318,11 +318,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE); list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE);
list({ ARRAY_PROPAGATION, CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS); list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS);
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);
Pass(CREATE_TEMPLATE_LINKS) <= Pass(MERGE_REGIONS);
passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS, passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS,
EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW, EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,

View File

@@ -577,20 +577,10 @@ string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const ch
for (auto& incl : inclByPos.second) for (auto& incl : inclByPos.second)
inlcude += (renameIncludes ? renameInclude(incl) : incl); inlcude += (renameIncludes ? renameInclude(incl) : incl);
//check inserted operators if (st->comments())
SgStatement* toInsert = st; st->setComments((inlcude + st->comments()).c_str());
do {
auto lexPrev = toInsert->lexPrev();
if (lexPrev && lexPrev->variant() > 0 && lexPrev->lineNumber() < 0)
toInsert = lexPrev;
else
break;
} while (true);
if (toInsert->comments())
toInsert->setComments((inlcude + toInsert->comments()).c_str());
else else
toInsert->addComment(inlcude.c_str()); st->addComment(inlcude.c_str());
} }
} }
@@ -658,7 +648,7 @@ string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const ch
if (wasDeleted) if (wasDeleted)
{ {
if (str.size() && str.back() != '\n') if (str.size() || str.back() != '\n')
str += '\n'; str += '\n';
st->setComments(str.c_str()); st->setComments(str.c_str());
} }
@@ -944,14 +934,8 @@ void fillNonDistrArraysAsPrivate(SgStatement *st,
{ {
auto itD = declaredArrays.find(*itSet); auto itD = declaredArrays.find(*itSet);
if (itD != declaredArrays.end()) if (itD != declaredArrays.end())
{ if (itD->second.first->IsNotDistribute())
const auto array = itD->second.first; privatesVars.insert(itD->second.first->GetShortName());
if (array->IsNotDistribute())
{
auto symb = array->GetDeclSymbol(make_pair(st->fileName(), st->lineNumber()));
privatesVars.insert(symb->identifier());
}
}
} }
} }
} }
@@ -969,21 +953,9 @@ DIST::Array* getArrayFromDeclarated(SgStatement *st, const string &arrayName)
for (auto itSet = it->second.begin(); itSet != it->second.end() && !found; ++itSet) for (auto itSet = it->second.begin(); itSet != it->second.end() && !found; ++itSet)
{ {
auto itD = declaredArrays.find(*itSet); auto itD = declaredArrays.find(*itSet);
if (itD != declaredArrays.end()) if (itD != declaredArrays.end())
{ if (itD->second.first->GetShortName() == arrayName)
DIST::Array* array = itD->second.first; found = 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; return found;
@@ -1292,32 +1264,6 @@ static SgExpression* isInCommon(const vector<SgExpression*> &commonBlocks, const
return NULL; 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; 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) tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>> &commonBlocks, SgStatement *decl, SgSymbol *symb)
{ {
@@ -1326,7 +1272,6 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
int commonPos = 0; int commonPos = 0;
SgExpression *foundCommon = NULL; SgExpression *foundCommon = NULL;
string symbCommn = "";
SgStatement *declCP = decl->controlParent(); SgStatement *declCP = decl->controlParent();
// find symbol in parameter list of functions // find symbol in parameter list of functions
@@ -1362,7 +1307,6 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
if (foundCommon) if (foundCommon)
{ {
inCommon = true; inCommon = true;
symbCommn = getCommonNameOnPos(common.first, commonPos);
break; break;
} }
} }
@@ -1370,7 +1314,7 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
tuple<int, string, string> retVal; tuple<int, string, string> retVal;
if (inCommon) if (inCommon)
retVal = make_tuple(commonPos, string("common_") + getCommonName(foundCommon), symbCommn); retVal = make_tuple(commonPos, string("common_") + getCommonName(foundCommon), string(symb->identifier()));
else else
retVal = make_tuple(decl->lineNumber(), string(decl->fileName()), string(symb->identifier())); retVal = make_tuple(decl->lineNumber(), string(decl->fileName()), string(symb->identifier()));

View File

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

View File

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

View File

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