7 Commits

Author SHA1 Message Date
30b2248e39 private_removing: add support for indexes like 2*i + 1
private_removing: fix bug bugreport_1701358632 - add check for build-in functions

private_removing: fix bug bugreport_1699352305 - update logic for finding definitions
2023-12-03 19:34:54 +03:00
ALEXks
d48a73043a addede new pass, improved IR 2023-12-02 10:20:13 +03:00
ALEXks
f5bc37c845 updated version 2023-12-01 10:28:51 +03:00
845e171247 Merge pull request 'wrong privatization of threadprivate arrays' (#17) from fix_omp_threadprivate into master 2023-12-01 07:26:39 +00:00
mkoch
2c62e57503 wrong privatization of threadprivate arrays 2023-12-01 10:17:06 +03:00
ALEXks
abd0c0caac fixed IR 2023-11-29 14:08:12 +03:00
43e5a9e8ba Merge pull request 'private_removing: исправление багов' (#16) from private_removing into master 2023-11-29 11:04:32 +00:00
12 changed files with 418 additions and 190 deletions

View File

@@ -2218,12 +2218,12 @@ SgStatement* SgStatement::nextInChildList()
return x; return x;
} }
std::string SgStatement::sunparse() std::string SgStatement::sunparse(int lang)
{ {
#ifdef __SPF #ifdef __SPF
checkConsistence(); checkConsistence();
#endif #endif
return std::string(unparse()); return std::string(unparse(lang));
} }

View File

@@ -243,9 +243,9 @@ public:
inline void replaceSymbBySymb(SgSymbol &symb, SgSymbol &newsymb); inline void replaceSymbBySymb(SgSymbol &symb, SgSymbol &newsymb);
inline void replaceSymbBySymbSameName(SgSymbol &symb, SgSymbol &newsymb); inline void replaceSymbBySymbSameName(SgSymbol &symb, SgSymbol &newsymb);
inline void replaceTypeInStmt(SgType &old, SgType &newtype); inline void replaceTypeInStmt(SgType &old, SgType &newtype);
char* unparse(); char* unparse(int lang = 2); // FORTRAN_LANG
inline void unparsestdout(); inline void unparsestdout();
std::string sunparse(); //unparsing functions. std::string sunparse(int lang = 2); // FORTRAN_LANG
inline char *comments(); //preceding comment lines. inline char *comments(); //preceding comment lines.
void addComment(const char *com); void addComment(const char *com);
void addComment(char *com); void addComment(char *com);
@@ -3679,12 +3679,12 @@ inline SgStatement *SgStatement::getScopeForDeclare()
} }
//Kataev 07.03.2013 //Kataev 07.03.2013
inline char* SgStatement::unparse() inline char* SgStatement::unparse(int lang)
{ {
#ifdef __SPF #ifdef __SPF
checkConsistence(); checkConsistence();
#endif #endif
return UnparseBif_Char(thebif, 2); //2 - fortran language return UnparseBif_Char(thebif, lang); //2 - fortran language
} }
inline void SgStatement::unparsestdout() inline void SgStatement::unparsestdout()

View File

@@ -187,6 +187,9 @@ set(TR_FUNC_PURE _src/Transformations/function_purifying.cpp
_src/Transformations/function_purifying.h) _src/Transformations/function_purifying.h)
set(TR_GV _src/Transformations/fix_common_blocks.cpp set(TR_GV _src/Transformations/fix_common_blocks.cpp
_src/Transformations/fix_common_blocks.h) _src/Transformations/fix_common_blocks.h)
set(TR_CONV _src/Transformations/convert_to_c.cpp
_src/Transformations/convert_to_c.h)
set(TRANSFORMS set(TRANSFORMS
${TR_CP} ${TR_CP}
${TR_VECTOR} ${TR_VECTOR}
@@ -200,7 +203,8 @@ set(TRANSFORMS
${TR_FUNC_PURE} ${TR_FUNC_PURE}
${TR_LOOP_UNROLL} ${TR_LOOP_UNROLL}
${TR_GV} ${TR_GV}
${TR_PRIV_DEL}) ${TR_PRIV_DEL}
${TR_CONV})
set(CFG _src/CFGraph/IR.cpp set(CFG _src/CFGraph/IR.cpp
_src/CFGraph/IR.h _src/CFGraph/IR.h
@@ -419,6 +423,7 @@ source_group (Transformations\\PrivateArrayRemoving FILES ${TR_PRIV_DEL})
source_group (Transformations\\VectorAssignToLoop FILES ${TR_VECTOR}) source_group (Transformations\\VectorAssignToLoop FILES ${TR_VECTOR})
source_group (Transformations\\RenameSymbols FILES ${RENAME_SYMBOLS}) source_group (Transformations\\RenameSymbols FILES ${RENAME_SYMBOLS})
source_group (Transformations\\GlobalVariables FILES ${TR_GV}) source_group (Transformations\\GlobalVariables FILES ${TR_GV})
source_group (Transformations\\ConvertToC FILES ${TR_CONV})
source_group (CreateIntervals FILES ${CREATE_INTER_T}) source_group (CreateIntervals FILES ${CREATE_INTER_T})

View File

@@ -728,8 +728,8 @@ static SgStatement* processStatement(SgStatement* st, vector<IR_Block*>& blocks,
const int var = st->variant(); const int var = st->variant();
//printf("%d %d\n", st->lineNumber(), st->variant()); //printf("%d %d\n", st->lineNumber(), st->variant());
static const set<int> skip = { FORMAT_STAT, static const set<int> skip = { FORMAT_STAT, OPEN_STAT, CLOSE_STAT, INQUIRE_STAT, REWIND_STAT, BACKSPACE_STAT,
OPEN_STAT, CLOSE_STAT, INQUIRE_STAT, REWIND_STAT, BACKSPACE_STAT, ENDFILE_STAT// <--- TODO ENDFILE_STAT, PAUSE_NODE // <--- TODO
}; };
const int blockShift = blocks.size() != 0 ? blocks[0]->getNumber() : Instruction::getNextInstrNum(); const int blockShift = blocks.size() != 0 ? blocks[0]->getNumber() : Instruction::getNextInstrNum();
@@ -824,7 +824,7 @@ static SgStatement* processStatement(SgStatement* st, vector<IR_Block*>& blocks,
} }
} }
blocks.push_back(new IR_Block(new Instruction(CFG_OP::EMPTY, st))); blocks.push_back(new IR_Block(new Instruction(CFG_OP::EMPTY, (ifSt->falseBody()) ? ifSt->falseBody() : st->lastNodeOfStmt())));
blocks[jump_if]->getInstruction()->setArg2(new SAPFOR::Argument(CFG_ARG_TYPE::INSTR, to_string(blocks.back()->getNumber()))); blocks[jump_if]->getInstruction()->setArg2(new SAPFOR::Argument(CFG_ARG_TYPE::INSTR, to_string(blocks.back()->getNumber())));
processLabel(st, firstBlock, blocks, labels); processLabel(st, firstBlock, blocks, labels);

View File

@@ -629,16 +629,6 @@ void findArrayRef(const vector<SgForStmt*> &parentLoops, SgExpression *currExp,
fillReductionsFromComment(new Statement(data), loopsReductions); fillReductionsFromComment(new Statement(data), loopsReductions);
fillReductionsFromComment(new Statement(data), loopsReductionsLoc); fillReductionsFromComment(new Statement(data), loopsReductionsLoc);
} }
set<string> dummy;
auto res = parseOmpDirs(loop, dummy);
for (auto& dir : res)
if (dir.keys.find("do") != dir.keys.end())
if (itFound->second.first->IsOmpThreadPrivate())
{
loopsPrivates.insert(itFound->second.first->GetShortName());
privatesVarsForLoop[z].insert(itFound->second.first->GetShortName());
}
} }
for (auto &elem : loopsReductions) for (auto &elem : loopsReductions)

View File

@@ -78,6 +78,7 @@
#include "Transformations/function_purifying.h" #include "Transformations/function_purifying.h"
#include "Transformations/private_removing.h" #include "Transformations/private_removing.h"
#include "Transformations/fix_common_blocks.h" #include "Transformations/fix_common_blocks.h"
#include "Transformations/convert_to_c.h"
#include "RenameSymbols/rename_symbols.h" #include "RenameSymbols/rename_symbols.h"
#include "ProjectParameters/projectParameters.h" #include "ProjectParameters/projectParameters.h"
@@ -1158,6 +1159,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
} }
else if (curr_regime == GET_MIN_MAX_BLOCK_DIST) else if (curr_regime == GET_MIN_MAX_BLOCK_DIST)
getMaxMinBlockDistribution(file, min_max_block); getMaxMinBlockDistribution(file, min_max_block);
else if (curr_regime == CONVERT_TO_C)
covertToC(file);
else if (curr_regime == TEST_PASS) else if (curr_regime == TEST_PASS)
{ {
//test pass //test pass

View File

@@ -171,6 +171,7 @@ enum passes {
REMOVE_OMP_DIRS_TRANSFORM, REMOVE_OMP_DIRS_TRANSFORM,
REMOVE_COMMENTS, REMOVE_COMMENTS,
GET_MIN_MAX_BLOCK_DIST, GET_MIN_MAX_BLOCK_DIST,
CONVERT_TO_C,
TEST_PASS, TEST_PASS,
EMPTY_PASS EMPTY_PASS
@@ -347,6 +348,7 @@ static void setPassValues()
passNames[REMOVE_OMP_DIRS_TRANSFORM] = "REMOVE_OMP_DIRS_TRANSFORM"; passNames[REMOVE_OMP_DIRS_TRANSFORM] = "REMOVE_OMP_DIRS_TRANSFORM";
passNames[REMOVE_COMMENTS] = "REMOVE_COMMENTS"; passNames[REMOVE_COMMENTS] = "REMOVE_COMMENTS";
passNames[GET_MIN_MAX_BLOCK_DIST] = "GET_MIN_MAX_BLOCK_DIST"; passNames[GET_MIN_MAX_BLOCK_DIST] = "GET_MIN_MAX_BLOCK_DIST";
passNames[CONVERT_TO_C] = "CONVERT_TO_C";
passNames[TEST_PASS] = "TEST_PASS"; passNames[TEST_PASS] = "TEST_PASS";
} }

View File

@@ -0,0 +1,20 @@
#include "../Utils/leak_detector.h"
#include <cstdio>
#include <cstring>
#include <cstring>
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <set>
#include <vector>
#include <algorithm>
#include <tuple>
#include "dvm.h"
#include "convert_to_c.h"
void covertToC(SgFile* file)
{
printf("%s\n", file->firstStatement()->unparse(C_LANG));
}

View File

@@ -0,0 +1,3 @@
#pragma once
void covertToC(SgFile* file);

View File

@@ -21,6 +21,14 @@ struct FixedSubscript {
int value; int value;
}; };
// RegularExpr represents expressions like ( coefA * I + coefB ),
// where I is a variable and coefA or coefB can be equal to zero
struct RegularExpr {
int coefA;
int coefB;
SgSymbol* varSymbol;
};
// DefUseStmtsPair represents pair of DEF and USE statements for private variable // DefUseStmtsPair represents pair of DEF and USE statements for private variable
using DefUseStmtsPair = pair<SgAssignStmt*, SgStatement*>; using DefUseStmtsPair = pair<SgAssignStmt*, SgStatement*>;
@@ -28,21 +36,6 @@ using DefUseStmtsPair = pair<SgAssignStmt*, SgStatement*>;
// used in PRIVATE_REMOVING pass - private vars that can be removed // used in PRIVATE_REMOVING pass - private vars that can be removed
static vector<PrivateToRemove> privatesToRemoveGlobal; static vector<PrivateToRemove> privatesToRemoveGlobal;
// Context stores general info about current loop and array to remove
struct Context {
const map<string, vector<FuncInfo*>>& allFuncInfo;
const map<string, CommonBlock*>& commonBlocks;
vector<Messages>& messages;
LoopGraph* loop;
SgForStmt* loopStmt;
SgSymbol* arraySymbol;
int dimensionsNum;
// string arrayName; // TODO: <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> arraySym <20><> arrayName
vector<SgArrayRefExp*> explicitArrayRefs;
vector<bool> fixedDimensionsMask;
};
/* ******************************* * /* ******************************* *
* Block of common used functions: * * Block of common used functions: *
@@ -97,26 +90,112 @@ static bool isArrayRefInVector(SgArrayRefExp* ref, const vector<SgArrayRefExp*>&
return false; return false;
} }
// checkAndFillRegularExpr checks if expr is regular and fills regularExpr struct
// with info about expr
static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr)
{
regularExpr.coefA = 0;
regularExpr.coefB = 0;
regularExpr.varSymbol = nullptr;
if (expr->variant() == INT_VAL) // expr is like ( coefB )
{
regularExpr.coefB = expr->valueInteger();
return true;
}
if (expr->variant() == VAR_REF) // expr is like ( I )
{
regularExpr.coefA = 1;
regularExpr.varSymbol = expr->symbol();
return true;
}
// is expr like ( coefA * I ):
if (expr->variant() == MULT_OP)
{
if (expr->lhs()->variant() == INT_VAL && expr->rhs()->variant() == VAR_REF)
{
regularExpr.coefA = expr->lhs()->valueInteger();
regularExpr.varSymbol = expr->rhs()->symbol();
return true;
}
}
if ((expr->variant() == ADD_OP || expr->variant() == SUBT_OP) && expr->rhs()->variant() == INT_VAL)
{
if (expr->variant() == ADD_OP)
regularExpr.coefB = expr->rhs()->valueInteger();
else // expr->variant() == SUBT_OP
regularExpr.coefB = (-1) * expr->rhs()->valueInteger();
if (expr->lhs()->variant() == MULT_OP) // is expr like ( coefA * I + coefB )
{
if (expr->lhs()->lhs()->variant() == INT_VAL && expr->lhs()->rhs()->variant() == VAR_REF)
{
regularExpr.coefA = expr->lhs()->lhs()->valueInteger();
regularExpr.varSymbol = expr->lhs()->rhs()->symbol();
return true;
}
}
else // is expr like ( I + coefB ):
{
if (expr->lhs()->variant() == VAR_REF)
{
regularExpr.coefA = 1;
regularExpr.varSymbol = expr->lhs()->symbol();
return true;
}
}
}
return false;
}
// getShortFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef // getShortFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef
static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef,
const vector<bool>& fixedDimensions) const vector<bool>& fixedDimensionsMask,
Regime regime)
{
if (regime == Regime::DEFLT)
{ {
vector<int> subscriptsVector; vector<int> subscriptsVector;
for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) for (int i = 0; i < fixedDimensionsMask.size(); ++i)
if (fixedDimensions[i]) if (fixedDimensionsMask[i])
subscriptsVector.push_back(arrayRef->subscript(i)->valueInteger()); subscriptsVector.push_back(arrayRef->subscript(i)->valueInteger());
return subscriptsVector; return subscriptsVector;
} }
else if (regime == Regime::REGULAR_INDEXES)
{
vector<int> subscriptsVector;
SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs();
for (int i = 0; i < indexExprList->length(); ++i)
{
SgExpression* indexExpr = indexExprList->elem(i);
RegularExpr regularExpr;
if (!checkAndFillRegularExpr(indexExpr, regularExpr))
return vector<int>{};
subscriptsVector.push_back(regularExpr.coefA);
subscriptsVector.push_back(regularExpr.coefB);
}
return subscriptsVector;
}
return vector<int>{};
}
// removeDuplicateArrayRefs returns unique array refereces in fixed dimensions // removeDuplicateArrayRefs returns unique array refereces in fixed dimensions
static vector<SgArrayRefExp*> removeDuplicateArrayRefs(const vector<SgArrayRefExp*>& arrayRefs, static vector<SgArrayRefExp*> removeDuplicateArrayRefs(const vector<SgArrayRefExp*>& arrayRefs,
const vector<bool>& fixedDimensions) const vector<bool>& fixedDimensionsMask,
Regime regime)
{ {
map<vector<int>, SgArrayRefExp*> uniqueRefs; map<vector<int>, SgArrayRefExp*> uniqueRefs;
for (SgArrayRefExp* ref : arrayRefs) for (SgArrayRefExp* ref : arrayRefs)
{ {
vector<int> subscripts = getShortFixedSubscriptsVector(ref, fixedDimensions); vector<int> subscripts = getShortFixedSubscriptsVector(ref, fixedDimensionsMask, regime);
if (uniqueRefs.find(subscripts) == uniqueRefs.end()) if (uniqueRefs.find(subscripts) == uniqueRefs.end())
uniqueRefs.insert(make_pair(subscripts, ref)); uniqueRefs.insert(make_pair(subscripts, ref));
} }
@@ -274,11 +353,13 @@ static void addMessageUsageInFunctionCall(vector<Messages>& messages, string var
// getDimensionVarName returns var name in style A(1, 2, *) // getDimensionVarName returns var name in style A(1, 2, *)
static string getDimensionVarName(SgSymbol* var, const vector<int>& subscripts, static string getDimensionVarName(SgSymbol* var, const vector<int>& subscripts,
const vector<bool>& fixedDimensions) const vector<bool>& fixedDimensions, Regime regime)
{ {
string result = var->identifier(); string result = var->identifier();
result += "("; result += "(";
if (regime == Regime::DEFLT)
{
for (int i = 0; i < fixedDimensions.size(); ++i) for (int i = 0; i < fixedDimensions.size(); ++i)
{ {
if (fixedDimensions[i]) if (fixedDimensions[i])
@@ -289,6 +370,36 @@ static string getDimensionVarName(SgSymbol* var, const vector<int>& subscripts,
if (i != fixedDimensions.size() - 1) if (i != fixedDimensions.size() - 1)
result += ", "; result += ", ";
} }
}
else if (regime == Regime::REGULAR_INDEXES)
{
for (int i = 0; i < subscripts.size(); i += 2) {
if (subscripts[i] == 0 && subscripts[(size_t)i + 1] == 0)
result += "0";
else
{
if (subscripts[i] != 0)
{
if (subscripts[i] != 1)
result += "I_" + std::to_string(i / 2 + 1);
else
result += std::to_string(subscripts[i]) + " * I_" + std::to_string(i / 2 + 1);
if (subscripts[(size_t)i + 1] > 0)
result += " + ";
else if (subscripts[(size_t)i + 1] < 0)
result += " - ";
}
if (subscripts[(size_t)i + 1] != 0)
result += std::to_string(std::abs(subscripts[(size_t)i + 1]));
}
if (i != subscripts.size() - 2)
result += ", ";
}
}
result += ")"; result += ")";
return result; return result;
@@ -386,6 +497,17 @@ static bool isVarReadInLoop(SgSymbol* var, SgForStmt* loopStmt)
return false; return false;
} }
// isVarChangedBetween checks if the var is changed between first and second statement
// by assignment to var (it doesn't check if the var is indirectly or implicitly by function call)
static bool isVarChangedBetween(string var, SgStatement* first, SgStatement* second)
{
for (SgStatement* st = first->lexNext(); st != second; st = st->lexNext())
if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol()->identifier() == var)
return true;
return false;
}
// removeDeadCodeFromLoop removes assign statements to private scalar vars which are not read in loop // removeDeadCodeFromLoop removes assign statements to private scalar vars which are not read in loop
static void removeDeadCodeFromLoop(LoopGraph* loop) static void removeDeadCodeFromLoop(LoopGraph* loop)
{ {
@@ -421,7 +543,7 @@ static void removeDeadCodeFromLoop(LoopGraph* loop)
// fillReadShortFixedSumscripts fills all short fixed subscripts vectors of array var, // fillReadShortFixedSumscripts fills all short fixed subscripts vectors of array var,
// which are used for reading from array var in exp // which are used for reading from array var in exp
static void fillReadShortFixedSumscripts(SgExpression* exp, const PrivateToRemove& var, static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemove& var,
set<vector<int>>& fixedSubscripts) set<vector<int>>& fixedSubscripts)
{ {
if (exp == nullptr) if (exp == nullptr)
@@ -431,19 +553,19 @@ static void fillReadShortFixedSumscripts(SgExpression* exp, const PrivateToRemov
{ {
if (isEqSymbols(exp->symbol(), var.varSymbol)) if (isEqSymbols(exp->symbol(), var.varSymbol))
{ {
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var.fixedDimensions); auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var.fixedDimensions, var.regime);
fixedSubscripts.insert(subscripts); fixedSubscripts.insert(subscripts);
return; return;
} }
} }
fillReadShortFixedSumscripts(exp->lhs(), var, fixedSubscripts); fillReadShortFixedSubscripts(exp->lhs(), var, fixedSubscripts);
fillReadShortFixedSumscripts(exp->rhs(), var, fixedSubscripts); fillReadShortFixedSubscripts(exp->rhs(), var, fixedSubscripts);
} }
// getReadShortFixedSumscripts return set of all short fixed subscripts vectors of array var from loop, // getReadShortFixedSubscripts return set of all short fixed subscripts vectors of array var from loop,
// which are used for reading from array var // which are used for reading from array var
static set<vector<int>> getReadShortFixedSumscripts(const PrivateToRemove& var, SgForStmt* loopStmt) static set<vector<int>> getReadShortFixedSubscripts(const PrivateToRemove& var, SgForStmt* loopStmt)
{ {
set<vector<int>> fixedSubscripts; set<vector<int>> fixedSubscripts;
for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
@@ -453,7 +575,7 @@ static set<vector<int>> getReadShortFixedSumscripts(const PrivateToRemove& var,
i = 1; i = 1;
for (; i < 3; ++i) for (; i < 3; ++i)
fillReadShortFixedSumscripts(st->expr(i), var, fixedSubscripts); fillReadShortFixedSubscripts(st->expr(i), var, fixedSubscripts);
} }
return fixedSubscripts; return fixedSubscripts;
@@ -464,7 +586,7 @@ static set<vector<int>> getReadShortFixedSumscripts(const PrivateToRemove& var,
static void removeExcessiveDefs(const PrivateToRemove& var) static void removeExcessiveDefs(const PrivateToRemove& var)
{ {
SgForStmt* loopStmt = (SgForStmt*)var.loop->loop->GetOriginal(); SgForStmt* loopStmt = (SgForStmt*)var.loop->loop->GetOriginal();
set<vector<int>> usedFixedSubscripts = getReadShortFixedSumscripts(var, loopStmt); set<vector<int>> usedFixedSubscripts = getReadShortFixedSubscripts(var, loopStmt);
vector<SgStatement*> stmtsToRemove; vector<SgStatement*> stmtsToRemove;
for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext()) for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
@@ -475,7 +597,8 @@ static void removeExcessiveDefs(const PrivateToRemove& var)
if (st->expr(0)->symbol() == nullptr || !isEqSymbols(st->expr(0)->symbol(), var.varSymbol)) if (st->expr(0)->symbol() == nullptr || !isEqSymbols(st->expr(0)->symbol(), var.varSymbol))
continue; continue;
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var.fixedDimensions); auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var.fixedDimensions,
var.regime);
if (usedFixedSubscripts.find(subscripts) == usedFixedSubscripts.end()) if (usedFixedSubscripts.find(subscripts) == usedFixedSubscripts.end())
stmtsToRemove.push_back(st); stmtsToRemove.push_back(st);
} }
@@ -576,7 +699,8 @@ static set<vector<int>> removeArray(string filename, const PrivateToRemove& arra
SgStatement* useStmt = defUsePair.second; SgStatement* useStmt = defUsePair.second;
SgArrayRefExp* defRef = (SgArrayRefExp*)defStmt->lhs(); SgArrayRefExp* defRef = (SgArrayRefExp*)defStmt->lhs();
vector<int> defFixedSubscripts = getShortFixedSubscriptsVector(defRef, fixedDimensions); vector<int> defFixedSubscripts = getShortFixedSubscriptsVector(defRef, fixedDimensions,
arrayToRemove.regime);
int startIndex = 0; int startIndex = 0;
if (useStmt->variant() == ASSIGN_STAT) if (useStmt->variant() == ASSIGN_STAT)
@@ -591,7 +715,8 @@ static set<vector<int>> removeArray(string filename, const PrivateToRemove& arra
for (SgArrayRefExp* useRef : arrayUseRefs) for (SgArrayRefExp* useRef : arrayUseRefs)
{ {
vector<int> useFixedSubscripts = getShortFixedSubscriptsVector(useRef, fixedDimensions); vector<int> useFixedSubscripts = getShortFixedSubscriptsVector(useRef, fixedDimensions,
arrayToRemove.regime);
if (defFixedSubscripts != useFixedSubscripts) if (defFixedSubscripts != useFixedSubscripts)
continue; // because useRef and defRef can be different in subscripts of fixed dimensions continue; // because useRef and defRef can be different in subscripts of fixed dimensions
@@ -626,7 +751,7 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
auto removedDimensions = removeArray(file->filename(), varToRemove); auto removedDimensions = removeArray(file->filename(), varToRemove);
countOfTransform++; countOfTransform++;
removeDeadCodeFromLoop(varToRemove.loop); //removeDeadCodeFromLoop(varToRemove.loop); // TODO: problem with reverting substitution
removeExcessiveDefs(varToRemove); removeExcessiveDefs(varToRemove);
removeEmptyLoops(varToRemove.loop, messages); removeEmptyLoops(varToRemove.loop, messages);
@@ -642,13 +767,14 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
} }
else else
{ {
varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions); varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime);
for (auto& varRef : varRefs) for (auto& varRef : varRefs)
{ {
vector<int> subscripts = getShortFixedSubscriptsVector(varRef, fixedDimensions); vector<int> subscripts = getShortFixedSubscriptsVector(varRef, fixedDimensions, varToRemove.regime);
if (removedDimensions.find(subscripts) != removedDimensions.end()) if (removedDimensions.find(subscripts) != removedDimensions.end())
{ {
varName = getDimensionVarName(varToRemove.varSymbol, subscripts, fixedDimensions); varName = getDimensionVarName(varToRemove.varSymbol, subscripts,
fixedDimensions, varToRemove.regime);
addMessageRemovePrivateVarPart(messages, varName, loopLineNum); addMessageRemovePrivateVarPart(messages, varName, loopLineNum);
} }
@@ -657,8 +783,9 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
for (auto& removedDimension : removedDimensions) for (auto& removedDimension : removedDimensions)
{ {
varName = getDimensionVarName(varToRemove.varSymbol, removedDimension, fixedDimensions); varName = getDimensionVarName(varToRemove.varSymbol, removedDimension,
addMessageRemovePrivateVar(messages, varName, loopLineNum); fixedDimensions, varToRemove.regime);
addMessageRemovePrivateVarPart(messages, varName, loopLineNum);
} }
} }
} }
@@ -673,9 +800,26 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
* PRIVATE_REMOVING_ANALYSIS block of functions: * * PRIVATE_REMOVING_ANALYSIS block of functions: *
* ********************************************* */ * ********************************************* */
// Context stores general info about current loop and array to remove
struct Context {
const map<string, vector<FuncInfo*>>& allFuncInfo;
const map<string, CommonBlock*>& commonBlocks;
vector<Messages>& messages;
Regime regime;
LoopGraph* loop;
SgForStmt* loopStmt;
SgSymbol* arraySymbol;
int dimensionsNum;
// string arrayName; // TODO: <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> arraySym <20><> arrayName
vector<SgArrayRefExp*> explicitArrayRefs;
//vector<pair<SgArrayRefExp*, RegularExpr>> regularIndexRefs;
vector<bool> fixedDimensionsMask;
};
// ReducedArrayVars represents mapping of array reference to reduced scalar var: // ReducedArrayVars represents mapping of array reference to reduced scalar var:
// arr(1, i) -> pair<vector<int>, SgSymbol*>: [1], arr_1 // arr(1, i) -> pair<vector<int>, SgSymbol*>: [1], arr_1
class ReducedArrayVars { class ReducedArrayVarsMap {
map<vector<int>, SgSymbol*> arrayMap; map<vector<int>, SgSymbol*> arrayMap;
public: public:
@@ -807,6 +951,49 @@ static string sunparseFixedDimensionsVector(const vector<bool>& fixedDimensions)
return result; return result;
} }
// fillIterationVariables fill vars set with iteration variables of all loops
// from stmt to outerLoopStmt
static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, set<string>& vars)
{
if (stmt == nullptr)
return;
if (stmt->variant() == FOR_NODE)
vars.insert(((SgForStmt*)stmt)->doName()->identifier());
if (stmt->id() != outerLoopStmt->id())
fillIterationVars(stmt->controlParent(), outerLoopStmt, vars);
}
static bool checkRegularIndexRefs(Context* ctx)
{
for (auto arrayRef : ctx->explicitArrayRefs)
{
SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs();
for (int i = 0; i < ctx->dimensionsNum; ++i)
{
SgExpression* indexExpr = indexExprList->elem(i);
RegularExpr regularExpr;
if (!checkAndFillRegularExpr(indexExpr, regularExpr))
return false;
//ctx->regularIndexRefs.push_back(make_pair(arrayRef, regularExpr));
}
}
vector<SgArrayRefExp*> newArrayRefsVector;
for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext())
{
if (st->variant() != ASSIGN_STAT || !isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol))
continue;
if (isSymbolInExpression(ctx->arraySymbol, st->expr(1)))
return false;
}
return true;
}
// getFixedDimensionsMask finds fixed dimensions vector with minimum number of fixed dimensions // getFixedDimensionsMask finds fixed dimensions vector with minimum number of fixed dimensions
// and writes messages if array doesn't have fixed dimensions // and writes messages if array doesn't have fixed dimensions
static vector<bool> getFixedDimensionsMask(Context* ctx) static vector<bool> getFixedDimensionsMask(Context* ctx)
@@ -927,8 +1114,6 @@ static vector<vector<FixedSubscript>> checkImplicitDirectUsage(Context* ctx)
SgCallStmt* callStmt = (SgCallStmt*)st; SgCallStmt* callStmt = (SgCallStmt*)st;
string procName = callStmt->name()->identifier(); string procName = callStmt->name()->identifier();
FuncInfo* funcInfo = findFunc(callStmt->fileName(), procName, ctx->allFuncInfo); FuncInfo* funcInfo = findFunc(callStmt->fileName(), procName, ctx->allFuncInfo);
if (funcInfo == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (int i = 0; i < callStmt->numberOfArgs(); ++i) for (int i = 0; i < callStmt->numberOfArgs(); ++i)
{ {
@@ -936,7 +1121,8 @@ static vector<vector<FixedSubscript>> checkImplicitDirectUsage(Context* ctx)
if (callArg->symbol() == nullptr || !isEqSymbols(callArg->symbol(), ctx->arraySymbol)) if (callArg->symbol() == nullptr || !isEqSymbols(callArg->symbol(), ctx->arraySymbol))
continue; continue;
if (funcInfo->funcParams.isArgOut(i) || // implicit direct usage if (funcInfo == nullptr || // no info about function
funcInfo->funcParams.isArgOut(i) || // implicit direct usage
callArg->lhs() == nullptr) // reference to whole array callArg->lhs() == nullptr) // reference to whole array
{ {
auto mask = getFixedSubscriptsVector((SgArrayRefExp*)callArg, ctx->dimensionsNum); auto mask = getFixedSubscriptsVector((SgArrayRefExp*)callArg, ctx->dimensionsNum);
@@ -1084,21 +1270,26 @@ static string getReducedArrayVarName(SgSymbol* symbol, const vector<int>& subscr
name.reserve(name.size() + subscripts.size() * 3); name.reserve(name.size() + subscripts.size() * 3);
for (int i : subscripts) for (int i : subscripts)
{
if (i < 0)
name += "_M" + std::to_string((-1) * i);
else
name += "_" + std::to_string(i); name += "_" + std::to_string(i);
}
return name; return name;
} }
// getReducedArrayVars makes reduced array vars for arrayRefs // getReducedArrayVars makes reduced array vars for arrayRefs
static ReducedArrayVars getReducedArrayVars(Context* ctx) static ReducedArrayVarsMap getReducedArrayVars(Context* ctx)
{ {
ReducedArrayVars reducedArrayVars; ReducedArrayVarsMap reducedArrayVars;
SgType* type = ctx->explicitArrayRefs[0]->type(); SgType* type = ctx->explicitArrayRefs[0]->type();
SgStatement* scope = ctx->loopStmt->getScopeForDeclare(); SgStatement* scope = ctx->loopStmt->getScopeForDeclare();
for (SgArrayRefExp* ref : ctx->explicitArrayRefs) for (SgArrayRefExp* ref : ctx->explicitArrayRefs)
{ {
vector<int> subscripts = getShortFixedSubscriptsVector(ref, ctx->fixedDimensionsMask); vector<int> subscripts = getShortFixedSubscriptsVector(ref, ctx->fixedDimensionsMask, ctx->regime);
if (reducedArrayVars.find(subscripts) == nullptr) if (reducedArrayVars.find(subscripts) == nullptr)
{ {
string name = getReducedArrayVarName(ref->symbol(), subscripts); string name = getReducedArrayVarName(ref->symbol(), subscripts);
@@ -1127,11 +1318,10 @@ static set<string> getVarsToDependOn(SgForStmt* loopStmt, SgSymbol* var)
} }
// getDefStmtForReducedArray returns DFE statement for reduced array variable // getDefStmtForReducedArray returns DFE statement for reduced array variable
static InsertedStatement getDefStmtForReducedArray(SgArrayRefExp* arrayRef, static InsertedStatement getDefStmtForReducedArray(Context* ctx, SgArrayRefExp* arrayRef,
const vector<bool>& fixedDimensions, const ReducedArrayVarsMap& reducedArrayVars)
const ReducedArrayVars& reducedArrayVars)
{ {
vector<int> subscriptVector = getShortFixedSubscriptsVector(arrayRef, fixedDimensions); vector<int> subscriptVector = getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime);
SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector); SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector);
if (reducedVar == nullptr) if (reducedVar == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1145,12 +1335,11 @@ static InsertedStatement getDefStmtForReducedArray(SgArrayRefExp* arrayRef,
// getUseStmtForReducedArray returns USE statement for reduced array variable // getUseStmtForReducedArray returns USE statement for reduced array variable
// (assignment to receiverVar) // (assignment to receiverVar)
static InsertedStatement getUseStmtForReducedArray(SgArrayRefExp* arrayRef, static InsertedStatement getUseStmtForReducedArray(Context* ctx, SgArrayRefExp* arrayRef,
const vector<bool>& fixedDimensions, const ReducedArrayVarsMap& reducedArrayVars,
const ReducedArrayVars& reducedArrayVars,
SgSymbol* receiverVar) SgSymbol* receiverVar)
{ {
vector<int> subscriptVector = getShortFixedSubscriptsVector(arrayRef, fixedDimensions); vector<int> subscriptVector = getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime);
SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector); SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector);
if (reducedVar == nullptr) if (reducedVar == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1165,7 +1354,7 @@ static InsertedStatement getUseStmtForReducedArray(SgArrayRefExp* arrayRef,
// insertReducedArrayVarStmts inserts in loop assignment statements with reduced vars, // insertReducedArrayVarStmts inserts in loop assignment statements with reduced vars,
// returns vector of inserted statements // returns vector of inserted statements
static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx, static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
const ReducedArrayVars& reducedArrayVars, const ReducedArrayVarsMap& reducedArrayVars,
SgSymbol* receiverVar) SgSymbol* receiverVar)
{ {
vector<InsertedStatement> insertedStmts; vector<InsertedStatement> insertedStmts;
@@ -1182,7 +1371,7 @@ static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
{ {
vector<SgArrayRefExp*> arrayRefs; vector<SgArrayRefExp*> arrayRefs;
fillDirectArrayRefs(st->expr(i), ctx->arraySymbol, arrayRefs); fillDirectArrayRefs(st->expr(i), ctx->arraySymbol, arrayRefs);
arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask); arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask, ctx->regime);
if (!arrayRefs.empty()) if (!arrayRefs.empty())
isUseStmt = true; isUseStmt = true;
@@ -1191,7 +1380,7 @@ static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs)) if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs))
continue; continue;
InsertedStatement useStmt = getUseStmtForReducedArray(arrayRef, ctx->fixedDimensionsMask, InsertedStatement useStmt = getUseStmtForReducedArray(ctx, arrayRef,
reducedArrayVars, receiverVar); reducedArrayVars, receiverVar);
useStmt.relatedToStmt = st; useStmt.relatedToStmt = st;
st->insertStmtBefore(*useStmt.insertedStmt, *st->controlParent()); st->insertStmtBefore(*useStmt.insertedStmt, *st->controlParent());
@@ -1204,8 +1393,8 @@ static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol) && // assignment to array - DEF stmt isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol) && // assignment to array - DEF stmt
isArrayRefInVector((SgArrayRefExp*)st->expr(0), ctx->explicitArrayRefs)) isArrayRefInVector((SgArrayRefExp*)st->expr(0), ctx->explicitArrayRefs))
{ {
InsertedStatement defStmt = getDefStmtForReducedArray((SgArrayRefExp*)st->expr(0), InsertedStatement defStmt = getDefStmtForReducedArray(ctx, (SgArrayRefExp*)st->expr(0),
ctx->fixedDimensionsMask, reducedArrayVars); reducedArrayVars);
defStmt.relatedToStmt = st; defStmt.relatedToStmt = st;
defStmt.isRecursive = isUseStmt; defStmt.isRecursive = isUseStmt;
st->insertStmtBefore(*defStmt.insertedStmt, *st->controlParent()); st->insertStmtBefore(*defStmt.insertedStmt, *st->controlParent());
@@ -1233,6 +1422,7 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
{ {
vector<DefUseStmtsPair> defUsePairs; vector<DefUseStmtsPair> defUsePairs;
string arrayName = ctx->arraySymbol->identifier();
for (const InsertedStatement& useInsertedStmt : insertedStmts) for (const InsertedStatement& useInsertedStmt : insertedStmts)
{ {
if (useInsertedStmt.type != TypeOfInsertedStmt::USE) // analysis for USE stmt if (useInsertedStmt.type != TypeOfInsertedStmt::USE) // analysis for USE stmt
@@ -1248,7 +1438,7 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
const auto& RD_forUseArg = RD_In.find(useArg); const auto& RD_forUseArg = RD_In.find(useArg);
if (RD_forUseArg == RD_In.end()) // cannot find reaching definitions for argument if (RD_forUseArg == RD_In.end()) // cannot find reaching definitions for argument
{ {
addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
continue; continue;
} }
@@ -1275,19 +1465,21 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
if (RD_defArgs.size() == 0) // argument is not initialized if (RD_defArgs.size() == 0) // argument is not initialized
{ {
addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
continue; continue;
} }
if (RD_defArgs.find(SAPFOR::CFG_VAL::UNINIT) != RD_defArgs.end()) // argument is not initialized SgStatement* defStmt = nullptr;
{
bool uninitArgIsOk = false;
if (RD_defArgs.size() == 2)
{
RD_defArgs.erase(SAPFOR::CFG_VAL::UNINIT);
int defArgNum = *RD_defArgs.begin();
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArgNum); if (RD_defArgs.size() > 1)
{
bool defIsFound = false;
for (int defArg : RD_defArgs) // try to find the real definition from RD_defArgs
{
if (defArg == SAPFOR::CFG_VAL::UNINIT)
continue;
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArg);
if (defInsAndBlock.first == nullptr) if (defInsAndBlock.first == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1295,38 +1487,54 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
if (defInsertedStmt->relatedToStmt->lineNumber() < useLineNum && if (defInsertedStmt->relatedToStmt->lineNumber() < useLineNum &&
useInsAndBlock.second->getNumber() == defInsAndBlock.second->getNumber()) useInsAndBlock.second->getNumber() == defInsAndBlock.second->getNumber())
{ {
uninitArgIsOk = true; // argument isn't really uninitialized defIsFound = true;
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArg);
defStmt = defInsAndBlock.first->getOperator();
break;
} }
} }
if (!uninitArgIsOk) if (!defIsFound)
{ {
addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); // try to find definition not from RD_defArgs:
string defVarName = useInsertedStmt.insertedStmt->expr(1)->symbol()->identifier();
SgStatement* blockStart = useInsAndBlock.second->getInstructions().front()->getInstruction()->getOperator();
SgStatement* blockEnd = useInsAndBlock.second->getInstructions().back()->getInstruction()->getOperator();
for (SgStatement* st = blockStart; st != blockEnd; st = st->lexNext())
{
if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol()->identifier() == defVarName &&
!isVarChangedBetween(defVarName, st, useInsertedStmt.insertedStmt))
{
defIsFound = true;
defStmt = st;
break;
}
}
}
if (!defIsFound)
{
addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
continue; continue;
} }
} }
else
if (RD_defArgs.size() > 1) // more than one reaching definition
{ {
addMessageMoreThanOneRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, *RD_defArgs.begin());
continue; defStmt = defInsAndBlock.first->getOperator();
} }
int defArgNum = *RD_defArgs.begin();
auto defInsAndBlock = getInstructionAndBlockByNumber(CFGraph, defArgNum);
SgStatement* defStmt = defInsAndBlock.first->getOperator();
auto defInsertedStmt = findInsertedStmt(insertedStmts, defStmt); auto defInsertedStmt = findInsertedStmt(insertedStmts, defStmt);
if (defInsertedStmt == insertedStmts.end()) if (defInsertedStmt == insertedStmts.end())
{ {
addMessageCannotFindRD(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); addMessageCannotFindRD(ctx->messages, arrayName, useLineNum);
continue; continue;
} }
//don't substitute def stmt into use, if def is recursive //don't substitute def stmt into use, if def is recursive
if (defInsertedStmt->isRecursive) if (defInsertedStmt->isRecursive)
{ {
addMessageRecursiveDependency(ctx->messages, ctx->arraySymbol->identifier(), useLineNum); addMessageRecursiveDependency(ctx->messages, arrayName, useLineNum);
continue; continue;
} }
@@ -1347,18 +1555,6 @@ static SgForStmt* getScopeLoopStmt(SgStatement* stmt)
return (SgForStmt*)stmt; return (SgForStmt*)stmt;
} }
static int getDimension(SgSymbol* arraySym)
{
SgExpression* declExpr = arraySym->makeDeclExpr();
if (declExpr == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
int dimensionNum = ((SgExprListExp*)declExpr->lhs())->length();
delete declExpr;
return dimensionNum;
}
// findChildLoop returns LoopGraph for provided loop statement // findChildLoop returns LoopGraph for provided loop statement
static LoopGraph* findLoop(LoopGraph* outerLoop, SgForStmt* loopStmt) static LoopGraph* findLoop(LoopGraph* outerLoop, SgForStmt* loopStmt)
{ {
@@ -1489,20 +1685,6 @@ pair<SAPFOR::Argument*, set<int>> findVarInRDSet(map<SAPFOR::Argument*, set<int>
return make_pair(nullptr, set<int>{}); return make_pair(nullptr, set<int>{});
} }
// fillIterationVariables fill vars set with iteration variables of all loops
// from stmt to outerLoopStmt
static void fillIterationVars(SgStatement *stmt, SgStatement* outerLoopStmt, set<string>& vars)
{
if (stmt == nullptr)
return;
if (stmt->variant() == FOR_NODE)
vars.insert(((SgForStmt*)stmt)->doName()->identifier());
if (stmt->id() != outerLoopStmt->id())
fillIterationVars(stmt->controlParent(), outerLoopStmt, vars);
}
// checkDefUsePair checks if def statement from pair can be substituted into use statement // checkDefUsePair checks if def statement from pair can be substituted into use statement
// and creates messages // and creates messages
static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type& CFGraph) static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type& CFGraph)
@@ -1547,6 +1729,10 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
if (defArg.second.size() != 1 || useArg.second.size() != 1 if (defArg.second.size() != 1 || useArg.second.size() != 1
|| *defArg.second.begin() != *useArg.second.begin()) || *defArg.second.begin() != *useArg.second.begin())
{ {
if (defInsAndBlock.second->getNumber() == useInsAndBlock.second->getNumber())
if (!isVarChangedBetween(var.first, defUse.first, defUse.second))
continue;
addMessageDependOnNonInvariant(ctx->messages, arrayName, addMessageDependOnNonInvariant(ctx->messages, arrayName,
var.first, defUse.first->lineNumber()); var.first, defUse.first->lineNumber());
return false; return false;
@@ -1656,6 +1842,54 @@ static set<SgSymbol*> getPrivateArraysForLoop(LoopGraph* loop, const UsersDirect
return privateArrays; return privateArrays;
} }
void removePrivateAnalyze(Context *ctx)
{
// inserting assignment to reduced array variables for getting reaching definitions analysis:
auto reducedArrayVars = getReducedArrayVars(ctx);
SgSymbol* receiverVar = makeTmpVar(ctx);
auto insertedStmts = insertReducedArrayVarStmts(ctx, reducedArrayVars, receiverVar);
// declare reduced array variables and receiver:
insertedStmts.push_back(InsertedStatement(
TypeOfInsertedStmt::DECLARATION,
makeDeclaration(ctx->loopStmt, reducedArrayVars.getAllVars(), nullptr)
));
insertedStmts.push_back(InsertedStatement(
TypeOfInsertedStmt::DECLARATION,
makeDeclaration(ctx->loopStmt, vector<SgSymbol*> {receiverVar}, nullptr)
));
CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(ctx->loopStmt,
SAPFOR::CFG_Settings(true, true),
ctx->commonBlocks, ctx->allFuncInfo);
if (CFG_ForFunc.empty())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto defUseStmtsPairs = buildDefUsePairs(ctx, CFG_ForFunc, insertedStmts);
if (!defUseStmtsPairs.empty()) // DEF-USE pairs were build successfully
{
vector<DefUseStmtsPair> resultDefUsePairs;
for (auto& pair : defUseStmtsPairs)
if (checkDefUsePair(ctx, pair, CFG_ForFunc))
resultDefUsePairs.push_back(pair);
PrivateToRemove newPrivateToRemove;
newPrivateToRemove.loop = ctx->loop;
newPrivateToRemove.varSymbol = ctx->arraySymbol;
newPrivateToRemove.regime = ctx->regime;
newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs);
newPrivateToRemove.fixedDimensions.swap(ctx->fixedDimensionsMask);
privatesToRemoveGlobal.push_back(newPrivateToRemove);
}
// delete inserted statements:
for (auto& stmt : insertedStmts)
stmt.insertedStmt->deleteStmt();
deleteCFG(CFG_ForFunc);
}
void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs, void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
vector<Messages>& messages, vector<Messages>& messages,
const UsersDirectives& usersDirectives, const UsersDirectives& usersDirectives,
@@ -1704,9 +1938,10 @@ void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
break; break;
Context context = Context{allFuncInfo, commonBlocks, messages}; Context context = Context{allFuncInfo, commonBlocks, messages};
context.regime = Regime::DEFLT;
context.loop = loop; context.loop = loop;
context.loopStmt = loopStmt; context.loopStmt = loopStmt;
context.dimensionsNum = getDimension(arrayToRemove); context.dimensionsNum = ((SgArrayType*)arrayToRemove->type())->dimension();
context.arraySymbol = arrayToRemove; context.arraySymbol = arrayToRemove;
auto filterMasks = checkImplicitAndIndirectUsage(&context); auto filterMasks = checkImplicitAndIndirectUsage(&context);
@@ -1718,57 +1953,23 @@ void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
context.fixedDimensionsMask = getFixedDimensionsMask(&context); context.fixedDimensionsMask = getFixedDimensionsMask(&context);
if (context.fixedDimensionsMask.empty() || if (!context.fixedDimensionsMask.empty() &&
!checkFixedDimensionsMaskMatching(&context) || checkFixedDimensionsMaskMatching(&context) &&
!checkDefStmtRefsMatchesMask(&context)) checkDefStmtRefsMatchesMask(&context))
{ {
removePrivateAnalyze(&context);
}
else
{
if (checkRegularIndexRefs(&context))
{
context.regime = Regime::REGULAR_INDEXES;
context.fixedDimensionsMask = vector<bool>{};
removePrivateAnalyze(&context);
}
else
addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(), context.loop->lineNum); addMessageDoesNotMatchMask(messages, context.arraySymbol->identifier(), context.loop->lineNum);
continue;
} }
// inserting assignment to reduced array variables for getting reaching definitions analysis:
auto reducedArrayVars = getReducedArrayVars(&context);
SgSymbol* receiverVar = makeTmpVar(&context);
auto insertedStmts = insertReducedArrayVarStmts(&context, reducedArrayVars, receiverVar);
// declare reduced array variables and receiver:
insertedStmts.push_back(InsertedStatement(
TypeOfInsertedStmt::DECLARATION,
makeDeclaration(context.loopStmt, reducedArrayVars.getAllVars(), nullptr)
));
insertedStmts.push_back(InsertedStatement(
TypeOfInsertedStmt::DECLARATION,
makeDeclaration(context.loopStmt, vector<SgSymbol*> {receiverVar}, nullptr)
));
CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(context.loopStmt,
SAPFOR::CFG_Settings(true, true),
commonBlocks, context.allFuncInfo);
if (CFG_ForFunc.empty())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto defUseStmtsPairs = buildDefUsePairs(&context, CFG_ForFunc, insertedStmts);
if (!defUseStmtsPairs.empty()) // DEF-USE pairs were build successfully
{
vector<DefUseStmtsPair> resultDefUsePairs;
for (auto& pair : defUseStmtsPairs)
if (checkDefUsePair(&context, pair, CFG_ForFunc))
resultDefUsePairs.push_back(pair);
PrivateToRemove newPrivateToRemove;
newPrivateToRemove.loop = context.loop;
newPrivateToRemove.varSymbol = context.arraySymbol;
newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs);
newPrivateToRemove.fixedDimensions.swap(context.fixedDimensionsMask);
privatesToRemoveGlobal.push_back(newPrivateToRemove);
}
// delete inserted statements:
for (auto& stmt : insertedStmts)
stmt.insertedStmt->deleteStmt();
deleteCFG(CFG_ForFunc);
} }
} }

View File

@@ -5,12 +5,16 @@
#include "../CFGraph/CFGraph.h" #include "../CFGraph/CFGraph.h"
#include "../CFGraph/RD_subst.h" #include "../CFGraph/RD_subst.h"
// Regime defines the regime of private removing
enum class Regime { DEFLT = 1, REGULAR_INDEXES };
// PrivateToRemove represents private variable of loop, that can be removed // PrivateToRemove represents private variable of loop, that can be removed
// by substitution of its definition statements (DEF) into usage statements (USE). // by substitution of its definition statements (DEF) into usage statements (USE).
// fixedDimensions is used for comparison of DEF and USE statements // fixedDimensions is used for comparison of DEF and USE statements
struct PrivateToRemove { struct PrivateToRemove {
LoopGraph* loop; LoopGraph* loop;
SgSymbol* varSymbol; SgSymbol* varSymbol;
Regime regime;
std::vector<std::pair<SgAssignStmt*, SgStatement*>> defUseStmtsPairs; std::vector<std::pair<SgAssignStmt*, SgStatement*>> defUseStmtsPairs;
std::vector<bool> fixedDimensions; std::vector<bool> fixedDimensions;
}; };

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_SPF "2250" #define VERSION_SPF "2254"