Обновление прохода удаления приватных переменных #18
@@ -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();
|
||||
regularExpr.coefA = retCoefs.first;
|
||||
regularExpr.coefB = retCoefs.second;
|
||||
|
||||
if (retCoefs.first != 0 || retCoefs.second != 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expr->variant() == VAR_REF) // expr is like ( I )
|
||||
{
|
||||
regularExpr.coefA = 1;
|
||||
regularExpr.varSymbol = expr->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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -543,7 +542,7 @@ static void removeDeadCodeFromLoop(LoopGraph* loop)
|
||||
|
||||
// fillReadShortFixedSumscripts fills all short fixed subscripts vectors of array var,
|
||||
// which are used for reading from array var in exp
|
||||
static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemove& var,
|
||||
static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemove& var,
|
||||
set<vector<int>>& fixedSubscripts)
|
||||
{
|
||||
if (exp == nullptr)
|
||||
@@ -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))
|
||||
continue;
|
||||
|
||||
if (isSymbolInExpression(ctx->arraySymbol, st->expr(1)))
|
||||
return false;
|
||||
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;
|
||||
|
||||
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;
|
||||
@@ -1128,7 +1159,7 @@ static vector<vector<FixedSubscript>> checkImplicitDirectUsage(Context* ctx)
|
||||
auto mask = getFixedSubscriptsVector((SgArrayRefExp*)callArg, ctx->dimensionsNum);
|
||||
fixedSubscripts.push_back(mask);
|
||||
addMessageUsageInFunctionCall(ctx->messages, getDimensionVarName(ctx->arraySymbol, mask),
|
||||
procName, ctx->loop->lineNum, st->lineNumber());
|
||||
procName, ctx->loop->lineNum, st->lineNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1975,4 +2018,4 @@ void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
|
||||
|
||||
for (LoopGraph* loop : loopGraphs)
|
||||
removePrivatesAnalysis(loop->children, messages, usersDirectives, commonBlocks, allFuncInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user
мне кажется, что эта функция уже есть в проекте:
getCoefsOfSubscript из expr_transform.h.
Она также выполняет предвычисления констант, посмотри пожалуйста, может быть лучше использовать ее?
Можно заменить на неё, но эта функция требует, чтобы ей передали имя переменной, относительно которой вычисляются коэффициенты выражения:
void getCoefsOfSubscript(pair<int, int> &retCoefs, SgExpression *exp, SgSymbol *doName)
я на имена переменных не опираюсь в преобразовании, поэтому их нужно откуда-то получать.
Можно просто перед вызовом функции получать из exp и подсовывать в вызов getCoefsOfSubscript.
Если так ок, то могу заменить на вызов getCoefsOfSubscript
а как не привязываться к циклу? у нас же замена связана с переменными цикла или с любыми переменными?. А что будет в случае a(i*i), a(i+k), a(i+k+2), где i,k - переменные цикла? по идее нужно проверять, что выражение точно соответствует тому, что нам нужно. Можно попробовать объединить и взять вычисление констант из той функции и оставить частичный обход у себя, если он проверят больше. Либо сделать проверку, что переменная цикла один раз встречается и что она та самая переменная, что нужна, и уже потом вызывать эту функцию для получения выражения. Также не ясно, что будет для многомерных циклов/массивов - будет ли там все корректно?
В случае a(i*i), a(i+k), a(i+k+2) моя функция вернёт false и подстановка не будет осуществляться, getCoefsOfSubscript вернёт <0, 0>. Замена связана с итерационными переменными, но я не думал учитывать их порядок в индексных выражениях (тут ещё обнаружил, что вообще проверку на них не добавил, это ошибка, исправлю).
Можно в качестве дополнительной проверки строить вектор итерационных переменных и, предполагая, что они должны быть в нужном порядке в индексных выражениях, получать коэффициенты через getCoefsOfSubscript. Но тогда обращение к массиву вида А(i + 1, 1) будет считаться некорректным - нет итерационной переменной во втором индексном выражении. Надо будет проверять, есть что если переменной нет и индексное выражение - это просто константа, то это ок ситуация. Наверно сделаю так
хорошо
Обновил PR