private_removing: bugreport_1672139586
add message about var usage in function calls add correct support for iteration vars
This commit is contained in:
@@ -201,17 +201,30 @@ static void addMessageDependOnNonInvariant(vector<Messages>& messages, string va
|
|||||||
messages.push_back(Messages(typeMessage::WARR, lineNum, messageR, messageE, 2017));
|
messages.push_back(Messages(typeMessage::WARR, lineNum, messageR, messageE, 2017));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addMessageDoesNotMachMask(vector<Messages>& messages, string varName, int loopLneNum)
|
static void addMessageDoesNotMachMask(vector<Messages>& messages, string varName, int loopLineNum)
|
||||||
{
|
{
|
||||||
__spf_print(1, "WARR: cannot remove private var '%s' in loop %d - it doesn't match any fixed dimensions mask\n",
|
__spf_print(1, "WARR: cannot remove private var '%s' in loop %d - it doesn't match any fixed dimensions mask\n",
|
||||||
varName.c_str(), loopLneNum);
|
varName.c_str(), loopLineNum);
|
||||||
|
|
||||||
wstring messageE, messageR;
|
wstring messageE, messageR;
|
||||||
__spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - it doesn't match any fixed dimensions mask",
|
__spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - it doesn't match any fixed dimensions mask",
|
||||||
to_wstring(varName).c_str());
|
to_wstring(varName).c_str());
|
||||||
__spf_printToLongBuf(messageR, R188, to_wstring(varName).c_str());
|
__spf_printToLongBuf(messageR, R188, to_wstring(varName).c_str());
|
||||||
|
|
||||||
messages.push_back(Messages(typeMessage::WARR, loopLneNum, messageR, messageE, 2016));
|
messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2016));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addMessageUsageInFunctionCall(vector<Messages>& messages, string varName, int loopLineNum, int lineNum)
|
||||||
|
{
|
||||||
|
__spf_print(1, "WARR: cannot remove private var '%s' in loop %d - it is used in function call in line %d\n",
|
||||||
|
varName.c_str(), loopLineNum, lineNum);
|
||||||
|
|
||||||
|
wstring messageE, messageR;
|
||||||
|
__spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - it is used in function call in line %d",
|
||||||
|
to_wstring(varName).c_str(), lineNum);
|
||||||
|
__spf_printToLongBuf(messageR, R203, to_wstring(varName).c_str(), lineNum);
|
||||||
|
|
||||||
|
messages.push_back(Messages(typeMessage::WARR, lineNum, messageR, messageE, 2025));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ****************************************** *
|
/* ****************************************** *
|
||||||
@@ -657,6 +670,46 @@ static vector<InsertedStatement>::const_iterator findInsertedStmt(const vector<I
|
|||||||
return insertedStmts.end();
|
return insertedStmts.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isVarUsedInFunctionCall checks if var is used in any function call in exp (as argument)
|
||||||
|
static bool isVarUsedInFunctionCall(SgSymbol* var, SgExpression* exp)
|
||||||
|
{
|
||||||
|
if (exp == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (exp->symbol() != nullptr && (exp->variant() == FUNC_CALL || exp->variant() == PROC_CALL))
|
||||||
|
return isSymbolInExpression(var, exp);
|
||||||
|
|
||||||
|
return isVarUsedInFunctionCall(var, exp->lhs()) || isVarUsedInFunctionCall(var, exp->rhs());
|
||||||
|
}
|
||||||
|
|
||||||
|
// isArrayUsedInFunctionCall checks if arraySym is used in any function call in stmt (as argument)
|
||||||
|
// and writes message if true
|
||||||
|
static bool isArrayUsedInFunctionCall(SgSymbol* arraySym, SgStatement* stmt, vector<Messages>& messages)
|
||||||
|
{
|
||||||
|
for (SgStatement* st = stmt; st != stmt->lastNodeOfStmt(); st = st->lexNext())
|
||||||
|
{
|
||||||
|
bool isUsed = false;
|
||||||
|
if (st->variant() == PROC_STAT)
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
if (isSymbolInExpression(arraySym, st->expr(i)))
|
||||||
|
isUsed = true;
|
||||||
|
|
||||||
|
if (!isUsed)
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
if (isVarUsedInFunctionCall(arraySym, st->expr(i)))
|
||||||
|
isUsed = true;
|
||||||
|
|
||||||
|
if (isUsed)
|
||||||
|
{
|
||||||
|
addMessageUsageInFunctionCall(messages, arraySym->identifier(),
|
||||||
|
stmt->lineNumber(), st->lineNumber());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension
|
// matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension
|
||||||
// and writes found mismatches to messages
|
// and writes found mismatches to messages
|
||||||
static bool matchesFixedDimensionsMask(const vector<SgArrayRefExp*>& arrayRefs,
|
static bool matchesFixedDimensionsMask(const vector<SgArrayRefExp*>& arrayRefs,
|
||||||
@@ -675,6 +728,8 @@ static bool matchesFixedDimensionsMask(const vector<SgArrayRefExp*>& arrayRefs,
|
|||||||
static bool defStmtRefsMatchesMask(SgStatement* loopStmt, const vector<bool>& fixedDimensions,
|
static bool defStmtRefsMatchesMask(SgStatement* loopStmt, const vector<bool>& fixedDimensions,
|
||||||
SgSymbol* arraySym)
|
SgSymbol* arraySym)
|
||||||
{
|
{
|
||||||
|
// 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 = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
for (SgStatement* st = loopStmt; st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
|
||||||
{
|
{
|
||||||
if (st->variant() != ASSIGN_STAT)
|
if (st->variant() != ASSIGN_STAT)
|
||||||
@@ -715,7 +770,8 @@ static string sunparseFixedDimensionsVector(const vector<bool>& fixedDimensions)
|
|||||||
{
|
{
|
||||||
string result = "<";
|
string result = "<";
|
||||||
result.reserve(result.size() + 7 * fixedDimensions.size());
|
result.reserve(result.size() + 7 * fixedDimensions.size());
|
||||||
for (int i = 0; i < fixedDimensions.size(); ++i) {
|
for (int i = 0; i < fixedDimensions.size(); ++i)
|
||||||
|
{
|
||||||
if (fixedDimensions[i] == true)
|
if (fixedDimensions[i] == true)
|
||||||
result += "true";
|
result += "true";
|
||||||
else
|
else
|
||||||
@@ -734,11 +790,19 @@ static string sunparseFixedDimensionsVector(const vector<bool>& fixedDimensions)
|
|||||||
static vector<bool> getFixedDimensionsMask(const vector<SgArrayRefExp*>& arrayRefs,
|
static vector<bool> getFixedDimensionsMask(const vector<SgArrayRefExp*>& arrayRefs,
|
||||||
vector<Messages>& messages, int loopLineNum)
|
vector<Messages>& messages, int loopLineNum)
|
||||||
{
|
{
|
||||||
int fixedDimensionsNumber = arrayRefs[0]->numberOfSubscripts();
|
int numberOfDimensions = arrayRefs[0]->numberOfSubscripts();
|
||||||
vector<bool> resultMask(fixedDimensionsNumber, true);
|
if (numberOfDimensions == 0) // invalid array reference
|
||||||
for (const auto arrayRef : arrayRefs) {
|
return vector<bool>{};
|
||||||
|
|
||||||
|
for (const auto arrayRef : arrayRefs)
|
||||||
|
if (arrayRef->numberOfSubscripts() != numberOfDimensions) // invalid array reference
|
||||||
|
return vector<bool>{};
|
||||||
|
|
||||||
|
vector<bool> resultMask(numberOfDimensions, true);
|
||||||
|
for (const auto arrayRef : arrayRefs)
|
||||||
|
{
|
||||||
vector<bool> fixedDimensions = getFixedDimensionsVector(arrayRef);
|
vector<bool> fixedDimensions = getFixedDimensionsVector(arrayRef);
|
||||||
for (int i = 0; i < fixedDimensionsNumber; ++i)
|
for (int i = 0; i < numberOfDimensions; ++i)
|
||||||
resultMask[i] = resultMask[i] && fixedDimensions[i];
|
resultMask[i] = resultMask[i] && fixedDimensions[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1073,10 +1137,22 @@ static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp,
|
|||||||
if (exp->symbol() != nullptr)
|
if (exp->symbol() != nullptr)
|
||||||
{
|
{
|
||||||
if (exp->variant() == VAR_REF)
|
if (exp->variant() == VAR_REF)
|
||||||
|
{
|
||||||
|
for (const auto& elem : vec)
|
||||||
|
if (elem.first == exp->symbol()->identifier())
|
||||||
|
return;
|
||||||
|
|
||||||
vec.push_back(make_pair(exp->symbol()->identifier(), vector<FixedSubscript>{}));
|
vec.push_back(make_pair(exp->symbol()->identifier(), vector<FixedSubscript>{}));
|
||||||
|
}
|
||||||
else if (exp->variant() == ARRAY_REF)
|
else if (exp->variant() == ARRAY_REF)
|
||||||
|
{
|
||||||
vec.push_back(make_pair(exp->symbol()->identifier(),
|
vec.push_back(make_pair(exp->symbol()->identifier(),
|
||||||
getFixedSubscriptsVector((SgArrayRefExp*)exp)));
|
getFixedSubscriptsVector((SgArrayRefExp*)exp)));
|
||||||
|
|
||||||
|
SgExprListExp* exprList = (SgExprListExp*)exp->lhs();
|
||||||
|
for (int i = 0; i < exprList->length(); ++i)
|
||||||
|
fillFixedSubscriptsVectorsOfAllVars(exprList->elem(i), vec);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1119,6 +1195,20 @@ 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(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_Type& CFGraph,
|
static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_Type& CFGraph,
|
||||||
@@ -1127,9 +1217,6 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T
|
|||||||
if (defUse.first->lineNumber() > defUse.second->lineNumber())
|
if (defUse.first->lineNumber() > defUse.second->lineNumber())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (loop->perfectLoop != 1)
|
|
||||||
loop = loop->children[0];
|
|
||||||
|
|
||||||
vector<pair<string, vector<FixedSubscript>>> dependOnVars;
|
vector<pair<string, vector<FixedSubscript>>> dependOnVars;
|
||||||
|
|
||||||
SgArrayRefExp* defRef = (SgArrayRefExp*)defUse.first->expr(0);
|
SgArrayRefExp* defRef = (SgArrayRefExp*)defUse.first->expr(0);
|
||||||
@@ -1145,14 +1232,21 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T
|
|||||||
fillFixedSubscriptsVectorsOfAllVars(expToSubst, dependOnVars);
|
fillFixedSubscriptsVectorsOfAllVars(expToSubst, dependOnVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set<string> iterationVars{};
|
||||||
|
fillIterationVars(defUse.second, loop->loop->GetOriginal(), iterationVars);
|
||||||
|
|
||||||
auto defInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.first);
|
auto defInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.first);
|
||||||
const auto& defRD_In = defInsAndBlock.second->getRD_In();
|
const auto& defRD_In = defInsAndBlock.second->getRD_In();
|
||||||
auto useInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.second);
|
auto useInsAndBlock = getInstructionAndBlockByStatement(CFGraph, defUse.second);
|
||||||
const auto& useRD_In = useInsAndBlock.second->getRD_In();
|
const auto& useRD_In = useInsAndBlock.second->getRD_In();
|
||||||
for (const auto& var : dependOnVars) // checking scalar vars
|
for (const auto& var : dependOnVars)
|
||||||
{
|
{
|
||||||
if (var.second.size() == 0)
|
if (var.second.size() == 0) // check scalar vars
|
||||||
{
|
{
|
||||||
|
// iteration var doesn't obstruct the removing:
|
||||||
|
if (iterationVars.find(var.first) != iterationVars.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
auto defArg = findVarInRDSet(defRD_In, var.first);
|
auto defArg = findVarInRDSet(defRD_In, var.first);
|
||||||
if (defArg.first == nullptr) // there is no any RD for common vars or parameters
|
if (defArg.first == nullptr) // there is no any RD for common vars or parameters
|
||||||
continue;
|
continue;
|
||||||
@@ -1185,6 +1279,9 @@ static bool checkDefUsePair(DefUseStmtsPair defUse, LoopGraph* loop, const CFG_T
|
|||||||
auto defLoopStmt = getScopeLoopStmt(defUse.first);
|
auto defLoopStmt = getScopeLoopStmt(defUse.first);
|
||||||
auto useLoopStmt = getScopeLoopStmt(defUse.second);
|
auto useLoopStmt = getScopeLoopStmt(defUse.second);
|
||||||
|
|
||||||
|
while (loop->perfectLoop != 1) // (what is it? - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>)
|
||||||
|
loop = loop->children[0];
|
||||||
|
|
||||||
auto defLoop = findLoop(loop, defLoopStmt);
|
auto defLoop = findLoop(loop, defLoopStmt);
|
||||||
auto useLoop = findLoop(loop, useLoopStmt);
|
auto useLoop = findLoop(loop, useLoopStmt);
|
||||||
|
|
||||||
@@ -1317,10 +1414,13 @@ void removePrivatesAnalysis(vector<LoopGraph*>& loopGraphs,
|
|||||||
if (arrayToRemove == nullptr) // no array to remove
|
if (arrayToRemove == nullptr) // no array to remove
|
||||||
break;
|
break;
|
||||||
|
|
||||||
vector<bool> fixedDimensionsMask = getFixedDimensionsMask(arrayRefs, messages, loop->lineNum);
|
if (isArrayUsedInFunctionCall(arrayToRemove, loopStmt, messages))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!matchesFixedDimensionsMask(arrayRefs, fixedDimensionsMask)
|
vector<bool> fixedDimensionsMask = getFixedDimensionsMask(arrayRefs, messages, loop->lineNum);
|
||||||
|| !defStmtRefsMatchesMask(loopStmt, fixedDimensionsMask, arrayToRemove))
|
if (fixedDimensionsMask.empty() ||
|
||||||
|
!matchesFixedDimensionsMask(arrayRefs, fixedDimensionsMask) ||
|
||||||
|
!defStmtRefsMatchesMask(loopStmt, fixedDimensionsMask, arrayToRemove))
|
||||||
{
|
{
|
||||||
addMessageDoesNotMachMask(messages, arrayToRemove->identifier(), loop->lineNum);
|
addMessageDoesNotMachMask(messages, arrayToRemove->identifier(), loop->lineNum);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ static void printStackTrace() { };
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
// Свободный - R203
|
// Свободный - R204
|
||||||
// Гайд по русификации сообщений: При добавлении нового сообщения, меняется последний сводобный идентификатор.
|
// Гайд по русификации сообщений: При добавлении нового сообщения, меняется последний сводобный идентификатор.
|
||||||
// В этом файле остаются только спецификаторы, для которых будет заполнен текст. Полный текст пишется в файле
|
// В этом файле остаются только спецификаторы, для которых будет заполнен текст. Полный текст пишется в файле
|
||||||
// russian_errors_text.txt. Спецификаторы там тоже сохраняются, по ним в визуализаторе будет восстановлен
|
// russian_errors_text.txt. Спецификаторы там тоже сохраняются, по ним в визуализаторе будет восстановлен
|
||||||
@@ -530,6 +530,8 @@ static const wchar_t* R196 = L"R196:";
|
|||||||
static const wchar_t *R197 = L"R197:";
|
static const wchar_t *R197 = L"R197:";
|
||||||
//2024
|
//2024
|
||||||
static const wchar_t *R198 = L"R198:%d";
|
static const wchar_t *R198 = L"R198:%d";
|
||||||
|
//2025
|
||||||
|
static const wchar_t *R203 = L"R203:%s%d";
|
||||||
|
|
||||||
//3001
|
//3001
|
||||||
static const wchar_t *R108 = L"R108:%s";
|
static const wchar_t *R108 = L"R108:%s";
|
||||||
|
|||||||
@@ -242,6 +242,8 @@ R196 = "Невозможно выполнить преобразование ц
|
|||||||
R197 = "Преобразование не может быть выполнено - не произошло никаких изменений в коде"
|
R197 = "Преобразование не может быть выполнено - не произошло никаких изменений в коде"
|
||||||
//2024
|
//2024
|
||||||
R198 = "Цикл на строке %d был удалён"
|
R198 = "Цикл на строке %d был удалён"
|
||||||
|
//2025
|
||||||
|
R203 = "Нельзя удалить приватную переменную '%s' - она используется в вызове функции на строке %d"
|
||||||
|
|
||||||
//3001
|
//3001
|
||||||
R108 = "Добавлена across-зависимость к массиву '%s' в цикле"
|
R108 = "Добавлена across-зависимость к массиву '%s' в цикле"
|
||||||
|
|||||||
Reference in New Issue
Block a user