|
|
|
@@ -4,6 +4,7 @@
|
|
|
|
#include "../Utils/SgUtils.h"
|
|
|
|
#include "../Utils/SgUtils.h"
|
|
|
|
#include "../Utils/utils.h"
|
|
|
|
#include "../Utils/utils.h"
|
|
|
|
#include "../ExpressionTransform/expr_transform.h"
|
|
|
|
#include "../ExpressionTransform/expr_transform.h"
|
|
|
|
|
|
|
|
#include "dead_code.h"
|
|
|
|
|
|
|
|
|
|
|
|
using std::make_pair;
|
|
|
|
using std::make_pair;
|
|
|
|
using std::map;
|
|
|
|
using std::map;
|
|
|
|
@@ -16,17 +17,48 @@ using std::wstring;
|
|
|
|
using CFG_Type = map<FuncInfo*, vector<SAPFOR::BasicBlock*>>;
|
|
|
|
using CFG_Type = map<FuncInfo*, vector<SAPFOR::BasicBlock*>>;
|
|
|
|
using UsersDirectives = map<pair<string, int>, set<SgStatement*>>;
|
|
|
|
using UsersDirectives = map<pair<string, int>, set<SgStatement*>>;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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 = 0;
|
|
|
|
|
|
|
|
int coefB;
|
|
|
|
|
|
|
|
string var;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RegularExpr(): coefA(0), coefB(0), var("") {}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool operator==(const RegularExpr& left, const RegularExpr& right)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return left.var == right.var && left.coefA == right.coefA && left.coefB == right.coefB;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool operator<(const RegularExpr& left, const RegularExpr& right)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (left.var == right.var && left.coefA < right.coefA && left.coefB <= right.coefB)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (left.var == right.var && left.coefA == right.coefA && left.coefB < right.coefB)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FixedSubscript represents subscript of array. Subscript is fixed if it is INT_VAL value
|
|
|
|
// FixedSubscript represents subscript of array. Subscript is fixed if it is INT_VAL value
|
|
|
|
struct FixedSubscript {
|
|
|
|
struct FixedSubscript {
|
|
|
|
bool isFixed;
|
|
|
|
bool isFixed;
|
|
|
|
int value;
|
|
|
|
int value;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// RegularExpr represents expressions like ( coefA * I + coefB ),
|
|
|
|
bool isRegIndex;
|
|
|
|
// where I is a variable and coefA or coefB can be equal to zero
|
|
|
|
RegularExpr regExprStart;
|
|
|
|
struct RegularExpr {
|
|
|
|
RegularExpr regExprEnd;
|
|
|
|
int coefA;
|
|
|
|
|
|
|
|
int coefB;
|
|
|
|
FixedSubscript() {
|
|
|
|
|
|
|
|
isFixed = false;
|
|
|
|
|
|
|
|
value = 0;
|
|
|
|
|
|
|
|
isRegIndex = false;
|
|
|
|
|
|
|
|
regExprStart = RegularExpr{};
|
|
|
|
|
|
|
|
regExprEnd = RegularExpr{};
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// DefUseStmtsPair represents pair of DEF and USE statements for private variable
|
|
|
|
// DefUseStmtsPair represents pair of DEF and USE statements for private variable
|
|
|
|
@@ -106,15 +138,50 @@ static bool isArrayRefInVector(SgArrayRefExp* ref, const vector<SgArrayRefExp*>&
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// findAnyVar returns first found VAR_REF in expr
|
|
|
|
|
|
|
|
static SgSymbol* findAnyVar(SgExpression* expr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (expr == nullptr)
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (expr->variant() == VAR_REF)
|
|
|
|
|
|
|
|
return expr->symbol();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SgSymbol* res = findAnyVar(expr->lhs());
|
|
|
|
|
|
|
|
if (res != nullptr)
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return findAnyVar(expr->rhs());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// checkAndFillRegularExpr checks if expr is regular and fills regularExpr struct
|
|
|
|
// checkAndFillRegularExpr checks if expr is regular and fills regularExpr struct
|
|
|
|
// with info about expr
|
|
|
|
// with info about expr
|
|
|
|
static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr, SgSymbol* iterationVar)
|
|
|
|
static bool checkAndFillRegularExpr(SgExpression* expr, RegularExpr& regularExpr, SgSymbol* iterationVar)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
if (expr == nullptr)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// hack for cases when iterationVar doesn't matter:
|
|
|
|
|
|
|
|
if (iterationVar == nullptr)
|
|
|
|
|
|
|
|
iterationVar = findAnyVar(expr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool deleteTmpVar = false;
|
|
|
|
|
|
|
|
if (iterationVar == nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
iterationVar = new SgSymbol(VARIABLE_NAME, "tmp");
|
|
|
|
|
|
|
|
deleteTmpVar = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pair<int, int> retCoefs;
|
|
|
|
pair<int, int> retCoefs;
|
|
|
|
getCoefsOfSubscript(retCoefs, expr, iterationVar);
|
|
|
|
getCoefsOfSubscript(retCoefs, expr, iterationVar);
|
|
|
|
|
|
|
|
|
|
|
|
regularExpr.coefA = retCoefs.first;
|
|
|
|
regularExpr.coefA = retCoefs.first;
|
|
|
|
regularExpr.coefB = retCoefs.second;
|
|
|
|
regularExpr.coefB = retCoefs.second;
|
|
|
|
|
|
|
|
if (!deleteTmpVar)
|
|
|
|
|
|
|
|
regularExpr.var = iterationVar->identifier();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (deleteTmpVar)
|
|
|
|
|
|
|
|
delete iterationVar;
|
|
|
|
|
|
|
|
|
|
|
|
if (retCoefs.first != 0 || retCoefs.second != 0)
|
|
|
|
if (retCoefs.first != 0 || retCoefs.second != 0)
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
@@ -218,6 +285,33 @@ static bool isSymbolInExpression(SgSymbol* symbol, SgExpression* exp)
|
|
|
|
isSymbolInExpression(symbol, exp->rhs());
|
|
|
|
isSymbolInExpression(symbol, exp->rhs());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static FuncInfo* findFunc(string fileName, string funcName, const map<string, vector<FuncInfo*>>& allFuncInfo)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto fileInfo = allFuncInfo.find(fileName);
|
|
|
|
|
|
|
|
if (fileInfo == allFuncInfo.end())
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto funcInfo : fileInfo->second)
|
|
|
|
|
|
|
|
if (funcInfo->funcName == funcName)
|
|
|
|
|
|
|
|
return funcInfo;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static FuncInfo* getCurrectFunc(SgStatement* stmt, const map<string, vector<FuncInfo*>>& allFuncInfo)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto fileInfo = allFuncInfo.find(stmt->fileName());
|
|
|
|
|
|
|
|
if (fileInfo == allFuncInfo.end())
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int stmtLine = stmt->lineNumber();
|
|
|
|
|
|
|
|
for (auto funcInfo : fileInfo->second)
|
|
|
|
|
|
|
|
if (funcInfo->linesNum.first <= stmtLine && stmtLine <= funcInfo->linesNum.second)
|
|
|
|
|
|
|
|
return funcInfo;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************** *
|
|
|
|
/* ************************************** *
|
|
|
|
* End of block of common used functions: *
|
|
|
|
* End of block of common used functions: *
|
|
|
|
* ************************************** */
|
|
|
|
* ************************************** */
|
|
|
|
@@ -227,16 +321,17 @@ static bool isSymbolInExpression(SgSymbol* symbol, SgExpression* exp)
|
|
|
|
* Block of creating messages functions: *
|
|
|
|
* Block of creating messages functions: *
|
|
|
|
* ************************************* */
|
|
|
|
* ************************************* */
|
|
|
|
|
|
|
|
|
|
|
|
static void addMessageRemoveLoop(vector<Messages>& messages, int loopLineNum)
|
|
|
|
// unused:
|
|
|
|
{
|
|
|
|
//static void addMessageRemoveLoop(vector<Messages>& messages, int loopLineNum)
|
|
|
|
__spf_print(1, "NOTE: loop on line %d was removed\n", loopLineNum);
|
|
|
|
//{
|
|
|
|
|
|
|
|
// __spf_print(1, "NOTE: loop on line %d was removed\n", loopLineNum);
|
|
|
|
wstring messageE, messageR;
|
|
|
|
//
|
|
|
|
__spf_printToLongBuf(messageE, L"Loop on line %d was removed", loopLineNum);
|
|
|
|
// wstring messageE, messageR;
|
|
|
|
__spf_printToLongBuf(messageR, R198, loopLineNum);
|
|
|
|
// __spf_printToLongBuf(messageE, L"Loop on line %d was removed", loopLineNum);
|
|
|
|
|
|
|
|
// __spf_printToLongBuf(messageR, R198, loopLineNum);
|
|
|
|
messages.push_back(Messages(typeMessage::NOTE, loopLineNum, messageR, messageE, 2024));
|
|
|
|
//
|
|
|
|
}
|
|
|
|
// messages.push_back(Messages(typeMessage::NOTE, loopLineNum, messageR, messageE, 2024));
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
static void addMessageRemovePrivateVar(vector<Messages>& messages, string varName, int loopLineNum)
|
|
|
|
static void addMessageRemovePrivateVar(vector<Messages>& messages, string varName, int loopLineNum)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@@ -603,30 +698,31 @@ static void removeExcessiveDefs(const PrivateToRemove& var)
|
|
|
|
st->deleteStmt();
|
|
|
|
st->deleteStmt();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: unused - can be removed?
|
|
|
|
// removeEmptyLoops removes loops with empty body and create messages
|
|
|
|
// removeEmptyLoops removes loops with empty body and create messages
|
|
|
|
static void removeEmptyLoops(LoopGraph* loop, vector<Messages>& messages)
|
|
|
|
//static void removeEmptyLoops(LoopGraph* loop, vector<Messages>& messages)
|
|
|
|
{
|
|
|
|
//{
|
|
|
|
vector<LoopGraph*> loopsToDelete;
|
|
|
|
// vector<LoopGraph*> loopsToDelete;
|
|
|
|
vector<LoopGraph*> newChildrenVector;
|
|
|
|
// vector<LoopGraph*> newChildrenVector;
|
|
|
|
for (auto childLoop : loop->children)
|
|
|
|
// for (auto childLoop : loop->children)
|
|
|
|
{
|
|
|
|
// {
|
|
|
|
SgStatement* loopStmt = childLoop->loop->GetOriginal();
|
|
|
|
// SgStatement* loopStmt = childLoop->loop->GetOriginal();
|
|
|
|
if (loopStmt->lastNodeOfStmt() == loopStmt->lexNext())
|
|
|
|
// if (loopStmt->lastNodeOfStmt() == loopStmt->lexNext())
|
|
|
|
loopsToDelete.push_back(childLoop);
|
|
|
|
// loopsToDelete.push_back(childLoop);
|
|
|
|
else
|
|
|
|
// else
|
|
|
|
newChildrenVector.push_back(childLoop);
|
|
|
|
// newChildrenVector.push_back(childLoop);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
for (auto loopToDelete : loopsToDelete)
|
|
|
|
// for (auto loopToDelete : loopsToDelete)
|
|
|
|
{
|
|
|
|
// {
|
|
|
|
addMessageRemoveLoop(messages, loopToDelete->lineNum);
|
|
|
|
// addMessageRemoveLoop(messages, loopToDelete->lineNum);
|
|
|
|
loopToDelete->loop->extractStmt();
|
|
|
|
// loopToDelete->loop->extractStmt();
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
loop->children.swap(newChildrenVector);
|
|
|
|
// loop->children.swap(newChildrenVector);
|
|
|
|
for (auto childLoop : loop->children)
|
|
|
|
// for (auto childLoop : loop->children)
|
|
|
|
removeEmptyLoops(childLoop, messages);
|
|
|
|
// removeEmptyLoops(childLoop, messages);
|
|
|
|
}
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
// removeVarFromPrivateAttributes removes var from SPF ANALYSIS PRIVATE attributes of loop
|
|
|
|
// removeVarFromPrivateAttributes removes var from SPF ANALYSIS PRIVATE attributes of loop
|
|
|
|
static void removeVarFromPrivateAttributes(SgSymbol* var, LoopGraph* loop)
|
|
|
|
static void removeVarFromPrivateAttributes(SgSymbol* var, LoopGraph* loop)
|
|
|
|
@@ -735,7 +831,10 @@ static set<vector<int>> removeArray(string filename, const PrivateToRemove& arra
|
|
|
|
return removedFixedSubscripts;
|
|
|
|
return removedFixedSubscripts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransform)
|
|
|
|
void removePrivates(SgFile* file, vector<Messages>& messages,
|
|
|
|
|
|
|
|
const map<string, CommonBlock*>& commonBlocks,
|
|
|
|
|
|
|
|
const map<string, vector<FuncInfo*>>& allFuncInfo,
|
|
|
|
|
|
|
|
int& countOfTransform)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (auto& varToRemove : privatesToRemoveGlobal)
|
|
|
|
for (auto& varToRemove : privatesToRemoveGlobal)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@@ -747,9 +846,15 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
|
|
|
|
|
|
|
|
|
|
|
|
//removeDeadCodeFromLoop(varToRemove.loop); // TODO: problem with reverting substitution
|
|
|
|
//removeDeadCodeFromLoop(varToRemove.loop); // TODO: problem with reverting substitution
|
|
|
|
removeExcessiveDefs(varToRemove);
|
|
|
|
removeExcessiveDefs(varToRemove);
|
|
|
|
removeEmptyLoops(varToRemove.loop, messages);
|
|
|
|
//removeEmptyLoops(varToRemove.loop, messages); // removing is made by REMOVE_DEAD_CODE pass
|
|
|
|
|
|
|
|
|
|
|
|
SgForStmt* loopStmt = (SgForStmt*)varToRemove.loop->loop->GetOriginal();
|
|
|
|
SgForStmt* loopStmt = (SgForStmt*)varToRemove.loop->loop->GetOriginal();
|
|
|
|
|
|
|
|
FuncInfo* currFunc = getCurrectFunc(loopStmt, allFuncInfo);
|
|
|
|
|
|
|
|
if (currFunc == nullptr)
|
|
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
removeDeadCode(currFunc->funcPointer, allFuncInfo, commonBlocks);
|
|
|
|
|
|
|
|
|
|
|
|
vector<SgArrayRefExp*> varRefs = getDirectArrayRefs(loopStmt, varToRemove.varSymbol);
|
|
|
|
vector<SgArrayRefExp*> varRefs = getDirectArrayRefs(loopStmt, varToRemove.varSymbol);
|
|
|
|
int loopLineNum = varToRemove.loop->lineNum;
|
|
|
|
int loopLineNum = varToRemove.loop->lineNum;
|
|
|
|
string varName = varToRemove.varSymbol->identifier();
|
|
|
|
string varName = varToRemove.varSymbol->identifier();
|
|
|
|
@@ -780,7 +885,7 @@ void removePrivates(SgFile* file, vector<Messages>& messages, int& countOfTransf
|
|
|
|
{
|
|
|
|
{
|
|
|
|
varName = getDimensionVarName(varToRemove.varSymbol, removedDimension,
|
|
|
|
varName = getDimensionVarName(varToRemove.varSymbol, removedDimension,
|
|
|
|
fixedDimensions, varToRemove.regime);
|
|
|
|
fixedDimensions, varToRemove.regime);
|
|
|
|
addMessageRemovePrivateVarPart(messages, varName, loopLineNum);
|
|
|
|
addMessageRemovePrivateVar(messages, varName, loopLineNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -1042,9 +1147,35 @@ static vector<bool> getFixedDimensionsMask(Context* ctx)
|
|
|
|
return resultMask;
|
|
|
|
return resultMask;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// getScopeLoopStmt returns least outer scope loop statement
|
|
|
|
|
|
|
|
static SgForStmt* getScopeLoopStmt(SgStatement* stmt)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
while (stmt != nullptr && stmt->variant() != FOR_NODE)
|
|
|
|
|
|
|
|
stmt = stmt->controlParent();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (SgForStmt*)stmt;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// getLoopStmtForVar searches for loop with iteration var equal loopVar starting from from stmt
|
|
|
|
|
|
|
|
static SgForStmt* getLoopStmtForVar(SgStatement* stmt, string loopVar)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
while (stmt != nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SgForStmt* loopStmt = getScopeLoopStmt(stmt);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loopStmt->doName()->identifier() == loopVar)
|
|
|
|
|
|
|
|
return loopStmt;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stmt = stmt->controlParent();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// getFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef
|
|
|
|
// getFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef
|
|
|
|
// true - subscript is fixed, false - it isn't
|
|
|
|
// true - subscript is fixed, false - it isn't
|
|
|
|
static vector<FixedSubscript> getFixedSubscriptsVector(SgArrayRefExp* arrayRef, int dimensionsNum = 0)
|
|
|
|
static vector<FixedSubscript> getFixedSubscriptsVector(SgArrayRefExp* arrayRef, int dimensionsNum = 0,
|
|
|
|
|
|
|
|
SgStatement* stmt = nullptr)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (arrayRef->numberOfSubscripts() == 0)
|
|
|
|
if (arrayRef->numberOfSubscripts() == 0)
|
|
|
|
return vector<FixedSubscript>(dimensionsNum);
|
|
|
|
return vector<FixedSubscript>(dimensionsNum);
|
|
|
|
@@ -1052,42 +1183,50 @@ static vector<FixedSubscript> getFixedSubscriptsVector(SgArrayRefExp* arrayRef,
|
|
|
|
vector<FixedSubscript> subscriptsVector;
|
|
|
|
vector<FixedSubscript> subscriptsVector;
|
|
|
|
for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i)
|
|
|
|
for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (arrayRef->subscript(i)->variant() == INT_VAL)
|
|
|
|
SgExpression* subscriptExpr = arrayRef->subscript(i);
|
|
|
|
subscriptsVector.push_back(FixedSubscript{ true, arrayRef->subscript(i)->valueInteger() });
|
|
|
|
FixedSubscript sub;
|
|
|
|
else
|
|
|
|
|
|
|
|
subscriptsVector.push_back(FixedSubscript{ false, 0 });
|
|
|
|
if (subscriptExpr->variant() == INT_VAL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sub.isFixed = true;
|
|
|
|
|
|
|
|
sub.value = subscriptExpr->valueInteger();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (stmt != nullptr && subscriptExpr->variant() == VAR_REF)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SgForStmt* loopStmt = getLoopStmtForVar(stmt, subscriptExpr->symbol()->identifier());
|
|
|
|
|
|
|
|
if (loopStmt != nullptr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
RegularExpr regExprStep;
|
|
|
|
|
|
|
|
SgExpression* step = loopStmt->step();
|
|
|
|
|
|
|
|
if (step == nullptr || checkAndFillRegularExpr(step, regExprStep, nullptr) && regExprStep.coefA == 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SgExpression* start = loopStmt->start();
|
|
|
|
|
|
|
|
SgExpression* end = loopStmt->end();
|
|
|
|
|
|
|
|
if (regExprStep.coefB < 0)
|
|
|
|
|
|
|
|
std::swap(start, end);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isRegular = true;
|
|
|
|
|
|
|
|
isRegular = isRegular && checkAndFillRegularExpr(start, sub.regExprStart, nullptr);
|
|
|
|
|
|
|
|
isRegular = isRegular && checkAndFillRegularExpr(end, sub.regExprEnd, nullptr);
|
|
|
|
|
|
|
|
sub.isRegIndex = isRegular;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
RegularExpr regExpr;
|
|
|
|
|
|
|
|
if (checkAndFillRegularExpr(subscriptExpr, regExpr, nullptr)) {
|
|
|
|
|
|
|
|
sub.isRegIndex = true;
|
|
|
|
|
|
|
|
sub.regExprStart = regExpr;
|
|
|
|
|
|
|
|
sub.regExprEnd = regExpr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
subscriptsVector.push_back(sub);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return subscriptsVector;
|
|
|
|
return subscriptsVector;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static FuncInfo* findFunc(string fileName, string funcName, const map<string, vector<FuncInfo*>>& allFuncInfo)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto fileInfo = allFuncInfo.find(fileName);
|
|
|
|
|
|
|
|
if (fileInfo == allFuncInfo.end())
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto funcInfo : fileInfo->second)
|
|
|
|
|
|
|
|
if (funcInfo->funcName == funcName)
|
|
|
|
|
|
|
|
return funcInfo;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static FuncInfo* getCurrectFunc(SgStatement* stmt, const map<string, vector<FuncInfo*>>& allFuncInfo)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto fileInfo = allFuncInfo.find(stmt->fileName());
|
|
|
|
|
|
|
|
if (fileInfo == allFuncInfo.end())
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int stmtLine = stmt->lineNumber();
|
|
|
|
|
|
|
|
for (auto funcInfo : fileInfo->second)
|
|
|
|
|
|
|
|
if (funcInfo->linesNum.first <= stmtLine && stmtLine <= funcInfo->linesNum.second)
|
|
|
|
|
|
|
|
return funcInfo;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// checkImplicitDirectUsage returns masks of array implicit usage (as out argument)
|
|
|
|
// checkImplicitDirectUsage returns masks of array implicit usage (as out argument)
|
|
|
|
// in any function call in exp and writes message about each usage
|
|
|
|
// in any function call in exp and writes message about each usage
|
|
|
|
static void checkImplicitDirectUsage(Context* ctx, SgExpression* exp, int stmtLineNum,
|
|
|
|
static void checkImplicitDirectUsage(Context* ctx, SgExpression* exp, int stmtLineNum,
|
|
|
|
@@ -1580,14 +1719,14 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
|
|
|
|
return defUsePairs;
|
|
|
|
return defUsePairs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// getScopeLoopStmt returns least outer scope loop statement
|
|
|
|
//// getScopeLoopStmt returns least outer scope loop statement
|
|
|
|
static SgForStmt* getScopeLoopStmt(SgStatement* stmt)
|
|
|
|
//static SgForStmt* getScopeLoopStmt(SgStatement* stmt)
|
|
|
|
{
|
|
|
|
//{
|
|
|
|
while (stmt != nullptr && stmt->variant() != FOR_NODE)
|
|
|
|
// while (stmt != nullptr && stmt->variant() != FOR_NODE)
|
|
|
|
stmt = stmt->controlParent();
|
|
|
|
// stmt = stmt->controlParent();
|
|
|
|
|
|
|
|
//
|
|
|
|
return (SgForStmt*)stmt;
|
|
|
|
// return (SgForStmt*)stmt;
|
|
|
|
}
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
@@ -1653,7 +1792,8 @@ static LoopGraph* leastCommonAncestor(LoopGraph* a, LoopGraph* b, LoopGraph* par
|
|
|
|
// fillFullFixedSubscriptsVectorsOfAllVars return vector of pairs (name of var, its fixed subscripts vector)
|
|
|
|
// fillFullFixedSubscriptsVectorsOfAllVars return vector of pairs (name of var, its fixed subscripts vector)
|
|
|
|
// of all VAR_REF and ARRAY_REF vars in exp
|
|
|
|
// of all VAR_REF and ARRAY_REF vars in exp
|
|
|
|
static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp,
|
|
|
|
static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp,
|
|
|
|
vector<pair<string, vector<FixedSubscript>>>& vec)
|
|
|
|
vector<pair<string, vector<FixedSubscript>>>& vec,
|
|
|
|
|
|
|
|
SgStatement* stmt = nullptr)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (exp == nullptr)
|
|
|
|
if (exp == nullptr)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
@@ -1671,22 +1811,54 @@ static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp,
|
|
|
|
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, 0, stmt)));
|
|
|
|
|
|
|
|
|
|
|
|
SgExprListExp* exprList = (SgExprListExp*)exp->lhs();
|
|
|
|
SgExprListExp* exprList = (SgExprListExp*)exp->lhs();
|
|
|
|
for (int i = 0; i < exprList->length(); ++i)
|
|
|
|
for (int i = 0; i < exprList->length(); ++i)
|
|
|
|
fillFixedSubscriptsVectorsOfAllVars(exprList->elem(i), vec);
|
|
|
|
fillFixedSubscriptsVectorsOfAllVars(exprList->elem(i), vec, stmt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fillFixedSubscriptsVectorsOfAllVars(exp->lhs(), vec);
|
|
|
|
fillFixedSubscriptsVectorsOfAllVars(exp->lhs(), vec, stmt);
|
|
|
|
fillFixedSubscriptsVectorsOfAllVars(exp->rhs(), vec);
|
|
|
|
fillFixedSubscriptsVectorsOfAllVars(exp->rhs(), vec, stmt);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// fixedSubscriptLess checks if left FixedSubscript is less than right
|
|
|
|
|
|
|
|
static bool fixedSubscriptLess(const FixedSubscript& left, const FixedSubscript& right)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (left.isFixed && right.isFixed && left.value < right.value)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (left.isFixed && right.isRegIndex
|
|
|
|
|
|
|
|
&& right.regExprStart.coefA == 0 && left.value < right.regExprStart.coefB)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (left.isRegIndex && right.isFixed
|
|
|
|
|
|
|
|
&& left.regExprEnd.coefA == 0 && left.regExprEnd.coefB < right.value)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (left.isRegIndex && right.isRegIndex)
|
|
|
|
|
|
|
|
return left.regExprEnd < right.regExprStart;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// fixedSubscriptLess checks if left and right FixedSubscripts are different,
|
|
|
|
|
|
|
|
// using empirical methods
|
|
|
|
|
|
|
|
static bool possibleDifferent(FixedSubscript left, FixedSubscript right)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// TODO: add warning?
|
|
|
|
|
|
|
|
if (left.isFixed && right.isRegIndex && right.regExprStart == right.regExprEnd) {
|
|
|
|
|
|
|
|
return true; // in general, this is not true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// isDifferentRefs checks if exp (var reference) is different from var. Refs are different
|
|
|
|
// isDifferentRefs checks if exp (var reference) is different from var. Refs are different
|
|
|
|
// if they has at least one different fixed subscript: arr(i, 1) is different from arr(j, 2)
|
|
|
|
// if they has at least one different fixed subscript: arr(i, 1) is different from arr(j, 2)
|
|
|
|
static bool isDifferentRefs(SgExpression* exp, const pair<string, vector<FixedSubscript>>& var)
|
|
|
|
static bool isDifferentRefs(SgExpression* exp, const pair<string, vector<FixedSubscript>>& var, SgStatement* stmt)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (exp->symbol()->identifier() != var.first)
|
|
|
|
if (exp->symbol()->identifier() != var.first)
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
@@ -1694,16 +1866,25 @@ static bool isDifferentRefs(SgExpression* exp, const pair<string, vector<FixedSu
|
|
|
|
if (exp->variant() == VAR_REF)
|
|
|
|
if (exp->variant() == VAR_REF)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
vector<FixedSubscript> leftVec = getFixedSubscriptsVector((SgArrayRefExp*)exp);
|
|
|
|
vector<FixedSubscript> leftVec = getFixedSubscriptsVector((SgArrayRefExp*)exp, 0, stmt);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (leftVec.size() != var.second.size())
|
|
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < leftVec.size(); i++)
|
|
|
|
for (int i = 0; i < leftVec.size(); i++)
|
|
|
|
if (leftVec[i].isFixed && var.second[i].isFixed && leftVec[i].value != var.second[i].value)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (fixedSubscriptLess(leftVec[i], var.second[i])
|
|
|
|
|
|
|
|
|| fixedSubscriptLess(var.second[i], leftVec[i])
|
|
|
|
|
|
|
|
|| possibleDifferent(leftVec[i], var.second[i]))
|
|
|
|
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pair<SAPFOR::Argument*, set<int>> findVarInRDSet(map<SAPFOR::Argument*, set<int>> RD_In, string var)
|
|
|
|
static pair<SAPFOR::Argument*, set<int>> findVarInRDSet(const map<SAPFOR::Argument*, set<int>> RD_In, string var)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (auto& RD_InElem : RD_In)
|
|
|
|
for (auto& RD_InElem : RD_In)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@@ -1721,7 +1902,7 @@ pair<SAPFOR::Argument*, set<int>> findVarInRDSet(map<SAPFOR::Argument*, set<int>
|
|
|
|
|
|
|
|
|
|
|
|
// 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, const DefUseStmtsPair& defUse, const CFG_Type& CFGraph)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (defUse.first->lineNumber() > defUse.second->lineNumber())
|
|
|
|
if (defUse.first->lineNumber() > defUse.second->lineNumber())
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
@@ -1737,7 +1918,7 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
|
|
|
|
SgExpression* expToSubst = defUse.first->rhs()->copyPtr();
|
|
|
|
SgExpression* expToSubst = defUse.first->rhs()->copyPtr();
|
|
|
|
expToSubst = replaceVarsWithExps(expToSubst, varToExpMap);
|
|
|
|
expToSubst = replaceVarsWithExps(expToSubst, varToExpMap);
|
|
|
|
|
|
|
|
|
|
|
|
fillFixedSubscriptsVectorsOfAllVars(expToSubst, dependOnVars);
|
|
|
|
fillFixedSubscriptsVectorsOfAllVars(expToSubst, dependOnVars, defUse.second);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<SgSymbol*> iterationVars{};
|
|
|
|
vector<SgSymbol*> iterationVars{};
|
|
|
|
@@ -1784,29 +1965,16 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// TODO: ^^^^^
|
|
|
|
|
|
|
|
// ïðîâåðêà ìàññèâîâ îòêëþ÷åíà, ïîñêîëüêó ÿâëÿåòñÿ ñëèøêîì êîíñåðâàòèâíîé è íå ïîçâîëÿåò
|
|
|
|
|
|
|
|
// âûïîëíèòü óäàëåíèå ìàññèâà RTMP â ôóíêöèè RHS òåñòà LU.
|
|
|
|
|
|
|
|
// òðåáóåòñÿ âûïîëíÿòü áîëåå ñëîæíûé àíàëèç, ñ îïðåäåëåíèåì ãðàíèö öèêëîâ,
|
|
|
|
|
|
|
|
// ÷òîáû îòëè÷àòü, ÷òî âñå ïðèñâàèâàíèÿ â ïåðåìåííóþ rsd â ýòîì ïðèìåðå
|
|
|
|
|
|
|
|
// ÿâëÿþòñÿ ïðèñâàèâàíèÿìè â ðàçíûå ýëåìåíòû ìàññèâà:
|
|
|
|
|
|
|
|
// rsd(1,i,j,2) = ...
|
|
|
|
|
|
|
|
// do k = 4, nz - 3
|
|
|
|
|
|
|
|
// rsd(1, i, j, k) = ...
|
|
|
|
|
|
|
|
// enddo
|
|
|
|
|
|
|
|
// rsd(1, i, j, nz - 2) = ...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// checking arrays:
|
|
|
|
// checking arrays:
|
|
|
|
auto defLoopStmt = getScopeLoopStmt(defUse.first);
|
|
|
|
auto defLoopStmt = getScopeLoopStmt(defUse.first);
|
|
|
|
auto useLoopStmt = getScopeLoopStmt(defUse.second);
|
|
|
|
auto useLoopStmt = getScopeLoopStmt(defUse.second);
|
|
|
|
|
|
|
|
|
|
|
|
LoopGraph* loop = ctx->loop;
|
|
|
|
LoopGraph* loop = ctx->loop;
|
|
|
|
while (loop->perfectLoop != 1) // (what is it? - ìîæåò áûòü ýòî íå íóæíî)
|
|
|
|
while (loop->perfectLoop != 1) // (what is it? - TODO: may be remove it)
|
|
|
|
loop = loop->children[0];
|
|
|
|
loop = loop->children[0];
|
|
|
|
|
|
|
|
|
|
|
|
auto defLoop = findLoop(loop, defLoopStmt);
|
|
|
|
LoopGraph* defLoop = findLoop(loop, defLoopStmt);
|
|
|
|
auto useLoop = findLoop(loop, useLoopStmt);
|
|
|
|
LoopGraph* useLoop = findLoop(loop, useLoopStmt);
|
|
|
|
|
|
|
|
|
|
|
|
if (!defLoopStmt || !useLoopStmt || !defLoop || !useLoop)
|
|
|
|
if (!defLoopStmt || !useLoopStmt || !defLoop || !useLoop)
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
@@ -1850,7 +2018,9 @@ static bool checkDefUsePair(Context* ctx, DefUseStmtsPair defUse, const CFG_Type
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (SgStatement* st = startStmt; st != endStmt; st = st->lexNext())
|
|
|
|
for (SgStatement* st = startStmt; st != endStmt; st = st->lexNext())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (st->variant() == ASSIGN_STAT && !isDifferentRefs(st->expr(0), var))
|
|
|
|
if (st == defUse.second)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (st->variant() == ASSIGN_STAT && !isDifferentRefs(st->expr(0), var, st))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
addMessageDependOnNonInvariant(ctx->messages, arrayName,
|
|
|
|
addMessageDependOnNonInvariant(ctx->messages, arrayName,
|
|
|
|
var.first, defUse.first->lineNumber());
|
|
|
|
var.first, defUse.first->lineNumber());
|
|
|
|
|