add checking for iteration vars in index expressions

This commit is contained in:
2023-12-10 14:39:06 +03:00
parent b35886bf0e
commit f42ed16096
2 changed files with 161 additions and 117 deletions

View File

@@ -3,6 +3,7 @@
#include "../Utils/errors.h"
#include "../Utils/SgUtils.h"
#include "../Utils/utils.h"
#include "../ExpressionTransform/expr_transform.h"
using std::make_pair;
using std::map;
@@ -26,7 +27,6 @@ struct FixedSubscript {
struct RegularExpr {
int coefA;
int coefB;
SgSymbol* varSymbol;
};
// DefUseStmtsPair represents pair of DEF and USE statements for private variable
@@ -57,7 +57,7 @@ static void fillDirectArrayRefs(SgExpression* exp, SgSymbol* arraySym, vector<Sg
fillDirectArrayRefs(exp->rhs(), arraySym, refs);
}
// getDirectArrayRefs returns all direct arraySym references in stmt,
// getDirectArrayRefs returns all direct arraySym references in compound stmt,
// except VAR_DECL statements
static vector<SgArrayRefExp*> getDirectArrayRefs(SgStatement* stmt, SgSymbol* arraySym)
{
@@ -81,6 +81,22 @@ static vector<SgArrayRefExp*> getDirectArrayRefs(SgStatement* stmt, SgSymbol* ar
return arrayRefs;
}
// getDirectArrayRefs returns all direct arraySym references in single stmt,
// except VAR_DECL statements
static vector<SgArrayRefExp*> getDirectArrayRefsFromSingleStmt(SgStatement* stmt, SgSymbol* arraySym)
{
vector<SgArrayRefExp*> arrayRefs;
if (stmt == nullptr)
return arrayRefs;
if (stmt->variant() != VAR_DECL && stmt->variant() != VAR_DECL_90) // skip var declaration stmt
for (int i = 0; i < 3; ++i)
fillDirectArrayRefs(stmt->expr(i), arraySym, arrayRefs);
return arrayRefs;
}
static bool isArrayRefInVector(SgArrayRefExp* ref, const vector<SgArrayRefExp*>& arrayRefs)
{
for (SgArrayRefExp* arrayRef : arrayRefs)
@@ -92,62 +108,20 @@ static bool isArrayRefInVector(SgArrayRefExp* ref, const vector<SgArrayRefExp*>&
// checkAndFillRegularExpr checks if expr is regular and fills regularExpr struct
// with info about expr
static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr)
static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr, SgSymbol* iterationVar)
{
regularExpr.coefA = 0;
regularExpr.coefB = 0;
regularExpr.varSymbol = nullptr;
pair<int, int> retCoefs;
getCoefsOfSubscript(retCoefs, expr, iterationVar);
if (expr->variant() == INT_VAL) // expr is like ( coefB )
{
regularExpr.coefB = expr->valueInteger();
return true;
}
regularExpr.coefA = retCoefs.first;
regularExpr.coefB = retCoefs.second;
if (expr->variant() == VAR_REF) // expr is like ( I )
{
regularExpr.coefA = 1;
regularExpr.varSymbol = expr->symbol();
if (retCoefs.first != 0 || retCoefs.second != 0)
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();
// check if expr is like ( 0 ), because we cannot separate zero const int expr from incorrect expr:
if (expr->variant() == INT_VAL)
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;
}
@@ -155,7 +129,7 @@ static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr
// getShortFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef
static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef,
const vector<bool>& fixedDimensionsMask,
Regime regime)
Regime regime, vector<SgSymbol*> iterationVars)
{
if (regime == Regime::DEFLT)
{
@@ -170,11 +144,14 @@ static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef,
{
vector<int> subscriptsVector;
SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs();
if (iterationVars.size() < indexExprList->length())
return vector<int>{};
for (int i = 0; i < indexExprList->length(); ++i)
{
SgExpression* indexExpr = indexExprList->elem(i);
RegularExpr regularExpr;
if (!checkAndFillRegularExpr(indexExpr, regularExpr))
if (!checkAndFillRegularExpr(indexExpr, regularExpr, iterationVars[i]))
return vector<int>{};
subscriptsVector.push_back(regularExpr.coefA);
@@ -187,17 +164,39 @@ static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef,
return vector<int>{};
}
static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, const PrivateToRemove& varToRemove)
{
vector<SgSymbol*> iterationVars;
if (varToRemove.regime == Regime::REGULAR_INDEXES)
{
auto vars = varToRemove.arrayRefToIterationVarsMap.find(arrayRef);
if (vars != varToRemove.arrayRefToIterationVarsMap.end())
iterationVars = vars->second;
}
return getShortFixedSubscriptsVector(arrayRef, varToRemove.fixedDimensions,
varToRemove.regime, iterationVars);
}
// removeDuplicateArrayRefs returns unique array refereces in fixed dimensions
static vector<SgArrayRefExp*> removeDuplicateArrayRefs(const vector<SgArrayRefExp*>& arrayRefs,
const vector<bool>& fixedDimensionsMask,
Regime regime)
Regime regime,
const map<SgArrayRefExp*, vector<SgSymbol*>>& arrayRefToIterVarsMap)
{
map<vector<int>, SgArrayRefExp*> uniqueRefs;
for (SgArrayRefExp* ref : arrayRefs)
for (SgArrayRefExp* arrayRef : arrayRefs)
{
vector<int> subscripts = getShortFixedSubscriptsVector(ref, fixedDimensionsMask, regime);
vector<SgSymbol*> iterationVars;
if (regime == Regime::REGULAR_INDEXES)
{
auto vars = arrayRefToIterVarsMap.find(arrayRef);
if (vars != arrayRefToIterVarsMap.end())
iterationVars = vars->second;
}
vector<int> subscripts = getShortFixedSubscriptsVector(arrayRef, fixedDimensionsMask, regime, iterationVars);
if (uniqueRefs.find(subscripts) == uniqueRefs.end())
uniqueRefs.insert(make_pair(subscripts, ref));
uniqueRefs.insert(make_pair(subscripts, arrayRef));
}
vector<SgArrayRefExp*> result;
@@ -553,7 +552,7 @@ static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemov
{
if (isEqSymbols(exp->symbol(), var.varSymbol))
{
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var.fixedDimensions, var.regime);
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var);
fixedSubscripts.insert(subscripts);
return;
}
@@ -597,8 +596,7 @@ static void removeExcessiveDefs(const PrivateToRemove& var)
if (st->expr(0)->symbol() == nullptr || !isEqSymbols(st->expr(0)->symbol(), var.varSymbol))
continue;
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var.fixedDimensions,
var.regime);
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*) st->expr(0), var);
if (usedFixedSubscripts.find(subscripts) == usedFixedSubscripts.end())
stmtsToRemove.push_back(st);
}
@@ -699,8 +697,7 @@ static set<vector<int>> removeArray(string filename, const PrivateToRemove& arra
SgStatement* useStmt = defUsePair.second;
SgArrayRefExp* defRef = (SgArrayRefExp*)defStmt->lhs();
vector<int> defFixedSubscripts = getShortFixedSubscriptsVector(defRef, fixedDimensions,
arrayToRemove.regime);
vector<int> defFixedSubscripts = getShortFixedSubscriptsVector(defRef, arrayToRemove);
int startIndex = 0;
if (useStmt->variant() == ASSIGN_STAT)
@@ -715,8 +712,7 @@ static set<vector<int>> removeArray(string filename, const PrivateToRemove& arra
for (SgArrayRefExp* useRef : arrayUseRefs)
{
vector<int> useFixedSubscripts = getShortFixedSubscriptsVector(useRef, fixedDimensions,
arrayToRemove.regime);
vector<int> useFixedSubscripts = getShortFixedSubscriptsVector(useRef, arrayToRemove);
if (defFixedSubscripts != useFixedSubscripts)
continue; // because useRef and defRef can be different in subscripts of fixed dimensions
@@ -767,10 +763,11 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
}
else
{
varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime);
varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime,
varToRemove.arrayRefToIterationVarsMap);
for (auto& varRef : varRefs)
{
vector<int> subscripts = getShortFixedSubscriptsVector(varRef, fixedDimensions, varToRemove.regime);
vector<int> subscripts = getShortFixedSubscriptsVector(varRef, varToRemove);
if (removedDimensions.find(subscripts) != removedDimensions.end())
{
varName = getDimensionVarName(varToRemove.varSymbol, subscripts,
@@ -811,10 +808,9 @@ struct Context {
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;
map<SgArrayRefExp*, vector<SgSymbol*>> arrayRefToIterationVarsMap;
};
// ReducedArrayVars represents mapping of array reference to reduced scalar var:
@@ -879,6 +875,33 @@ static vector<InsertedStatement>::const_iterator findInsertedStmt(const vector<I
return insertedStmts.end();
}
static vector<int> getShortFixedSubscriptsVector(Context* ctx, SgArrayRefExp* arrayRef)
{
vector<SgSymbol*> iterationVars;
if (ctx->regime == Regime::REGULAR_INDEXES)
{
auto vars = ctx->arrayRefToIterationVarsMap.find(arrayRef);
if (vars != ctx->arrayRefToIterationVarsMap.end())
iterationVars = vars->second;
}
return getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime, iterationVars);
}
// fillIterationVariables fill vars set with iteration variables of all loops
// from stmt to outerLoopStmt
static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, vector<SgSymbol*>& vars)
{
if (stmt == nullptr)
return;
if (stmt->variant() == FOR_NODE)
vars.push_back(((SgForStmt*)stmt)->doName());
if (stmt->id() != outerLoopStmt->id())
fillIterationVars(stmt->controlParent(), outerLoopStmt, vars);
}
// matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension
static bool checkFixedDimensionsMaskMatching(Context* ctx)
{
@@ -894,13 +917,14 @@ static bool checkFixedDimensionsMaskMatching(Context* ctx)
// and VAR_REF in non-fixed dimensions
static bool checkDefStmtRefsMatchesMask(Context* ctx)
{
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD> VAR_REF - <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> a * i + b, <20><> i <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext())
{
if (st->variant() != ASSIGN_STAT)
continue;
vector<SgSymbol*> iterationVars;
fillIterationVars(st, ctx->loopStmt, iterationVars);
if (isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol)) // DEF statement
{
SgArrayRefExp* ref = (SgArrayRefExp*)st->expr(0);
@@ -908,8 +932,19 @@ static bool checkDefStmtRefsMatchesMask(Context* ctx)
{
if (ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == INT_VAL)
continue;
if (!ctx->fixedDimensionsMask[i] && ref->subscript(i)->variant() == VAR_REF)
{
bool isIterationVar = false;
for (auto iterationvVar : iterationVars)
if (isEqSymbols(ref->subscript(i)->symbol(), iterationvVar))
isIterationVar = true;
if (!isIterationVar)
return false;
continue;
}
return false;
}
@@ -951,44 +986,40 @@ static string sunparseFixedDimensionsVector(const vector<bool>& fixedDimensions)
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))
vector<SgSymbol*> iterationVars;
fillIterationVars(st, ctx->loopStmt, iterationVars);
vector<SgArrayRefExp*> arrayRefs = getDirectArrayRefsFromSingleStmt(st, ctx->arraySymbol);
for (auto arrayRef : arrayRefs)
{
if (!isArrayRefInVector(arrayRef, ctx->explicitArrayRefs))
continue;
if (isSymbolInExpression(ctx->arraySymbol, st->expr(1)))
SgExprListExp* indexExprList = (SgExprListExp*)arrayRef->lhs();
if (iterationVars.size() < indexExprList->length())
return false;
for (int i = 0; i < indexExprList->length(); ++i)
{
SgExpression* indexExpr = indexExprList->elem(i);
RegularExpr regularExpr;
if (!checkAndFillRegularExpr(indexExpr, regularExpr, iterationVars[i]))
return false;
}
if (st->variant() == ASSIGN_STAT && isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol))
for (auto iterationVar : iterationVars)
if (isSymbolInExpression(iterationVar, st->expr(1)))
return false;
iterationVars.resize(indexExprList->length());
ctx->arrayRefToIterationVarsMap.insert(make_pair(arrayRef, iterationVars));
}
}
return true;
@@ -1287,12 +1318,12 @@ static ReducedArrayVarsMap getReducedArrayVars(Context* ctx)
SgType* type = ctx->explicitArrayRefs[0]->type();
SgStatement* scope = ctx->loopStmt->getScopeForDeclare();
for (SgArrayRefExp* ref : ctx->explicitArrayRefs)
for (SgArrayRefExp* arrayRef : ctx->explicitArrayRefs)
{
vector<int> subscripts = getShortFixedSubscriptsVector(ref, ctx->fixedDimensionsMask, ctx->regime);
vector<int> subscripts = getShortFixedSubscriptsVector(ctx, arrayRef);
if (reducedArrayVars.find(subscripts) == nullptr)
{
string name = getReducedArrayVarName(ref->symbol(), subscripts);
string name = getReducedArrayVarName(arrayRef->symbol(), subscripts);
int nameNumber = checkSymbNameAndCorrect(name + "__", 0);
if (nameNumber != 0)
@@ -1321,7 +1352,7 @@ static set<string> getVarsToDependOn(SgForStmt* loopStmt, SgSymbol* var)
static InsertedStatement getDefStmtForReducedArray(Context* ctx, SgArrayRefExp* arrayRef,
const ReducedArrayVarsMap& reducedArrayVars)
{
vector<int> subscriptVector = getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime);
vector<int> subscriptVector = getShortFixedSubscriptsVector(ctx, arrayRef);
SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector);
if (reducedVar == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1339,7 +1370,7 @@ static InsertedStatement getUseStmtForReducedArray(Context* ctx, SgArrayRefExp*
const ReducedArrayVarsMap& reducedArrayVars,
SgSymbol* receiverVar)
{
vector<int> subscriptVector = getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime);
vector<int> subscriptVector = getShortFixedSubscriptsVector(ctx, arrayRef);
SgSymbol* reducedVar = reducedArrayVars.find(subscriptVector);
if (reducedVar == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1371,7 +1402,8 @@ static vector<InsertedStatement> insertReducedArrayVarStmts(Context* ctx,
{
vector<SgArrayRefExp*> arrayRefs;
fillDirectArrayRefs(st->expr(i), ctx->arraySymbol, arrayRefs);
arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask, ctx->regime);
arrayRefs = removeDuplicateArrayRefs(arrayRefs, ctx->fixedDimensionsMask, ctx->regime,
ctx->arrayRefToIterationVarsMap);
if (!arrayRefs.empty())
isUseStmt = true;
@@ -1696,7 +1728,7 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
vector<pair<string, vector<FixedSubscript>>> dependOnVars;
SgArrayRefExp* defRef = (SgArrayRefExp*)defUse.first->expr(0);
vector<SgArrayRefExp*> arrayUseRefs = getDirectArrayRefs(defUse.second, ctx->arraySymbol);
vector<SgArrayRefExp*> arrayUseRefs = getDirectArrayRefsFromSingleStmt(defUse.second, ctx->arraySymbol);
for (auto useRef : arrayUseRefs)
{
map<SgSymbol*, SgExpression*> varToExpMap = getVarToExpMap(defRef, useRef, ctx->fixedDimensionsMask);
@@ -1706,7 +1738,7 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
fillFixedSubscriptsVectorsOfAllVars(expToSubst, dependOnVars);
}
set<string> iterationVars{};
vector<SgSymbol*> iterationVars{};
fillIterationVars(defUse.second, ctx->loopStmt, iterationVars);
auto defInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.first);
@@ -1718,7 +1750,17 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
if (var.second.size() == 0) // check scalar vars
{
// iteration var doesn't obstruct the removing:
if (iterationVars.find(var.first) != iterationVars.end())
bool isIterationVar = false;
for (auto iterationVar : iterationVars)
{
if (iterationVar->identifier() == var.first)
{
isIterationVar = true;
break;
}
}
if (isIterationVar)
continue;
auto defArg = findVarInRDSet(defRD_In, var.first);
@@ -1879,6 +1921,7 @@ void removePrivateAnalyze(Context *ctx)
newPrivateToRemove.regime = ctx->regime;
newPrivateToRemove.defUseStmtsPairs.swap(resultDefUsePairs);
newPrivateToRemove.fixedDimensions.swap(ctx->fixedDimensionsMask);
newPrivateToRemove.arrayRefToIterationVarsMap = ctx->arrayRefToIterationVarsMap;
privatesToRemoveGlobal.push_back(newPrivateToRemove);
}

View File

@@ -17,6 +17,7 @@ struct PrivateToRemove {
Regime regime;
std::vector<std::pair<SgAssignStmt*, SgStatement*>> defUseStmtsPairs;
std::vector<bool> fixedDimensions;
std::map<SgArrayRefExp*, std::vector<SgSymbol*>> arrayRefToIterationVarsMap;
};
// removePrivates removes all privates from vector privatesToRemoveGloval