added new directives

This commit is contained in:
ALEXks
2024-04-09 16:41:48 +03:00
parent 1b4eb0c5c4
commit 2b48813783
23 changed files with 4084 additions and 3828 deletions

View File

@@ -84,7 +84,7 @@ static inline Symbol* getData(SgExpression *symb, Symbol**, bool moduleNameAdd =
}
template<typename fillType>
void fillPrivatesFromComment(Statement *stIn, set<fillType> &privates)
void fillPrivatesFromComment(Statement *stIn, set<fillType> &privates, int type)
{
if (stIn)
{
@@ -94,7 +94,10 @@ void fillPrivatesFromComment(Statement *stIn, set<fillType> &privates)
SgExpression *exprList = st->expr(0);
while (exprList)
{
if (exprList->lhs()->variant() == ACC_PRIVATE_OP)
const int var = exprList->lhs()->variant();
if ( ((var == ACC_PRIVATE_OP || var == SPF_PROCESS_PRIVATE_OP) && type == -1) ||
(var == ACC_PRIVATE_OP && var == type) ||
(var == SPF_PROCESS_PRIVATE_OP && var == type) )
{
SgExpression *list = exprList->lhs()->lhs();
while (list)
@@ -111,8 +114,8 @@ void fillPrivatesFromComment(Statement *stIn, set<fillType> &privates)
}
}
template void fillPrivatesFromComment(Statement *st, set<string> &privates);
template void fillPrivatesFromComment(Statement *st, set<Symbol*> &privates);
template void fillPrivatesFromComment(Statement *st, set<string> &privates, int type);
template void fillPrivatesFromComment(Statement *st, set<Symbol*> &privates, int type);
//XXX: need to remove message and to add implementation
extern map<string, vector<Messages>> SPF_messages;
@@ -594,3 +597,28 @@ void fillInfoFromDirectives(const LoopGraph *loopInfo, ParallelDirective *direct
}
}
}
int getCoverPropertyFromComment(Statement* stIn)
{
if (stIn)
{
SgStatement* st = stIn->GetOriginal();
if (st->variant() == SPF_ANALYSIS_DIR)
{
SgExpression* exprList = st->expr(0);
while (exprList)
{
if (exprList->lhs() && exprList->lhs()->variant() == SPF_COVER_OP)
{
auto value = exprList->lhs()->lhs();
if (value->isInteger())
return value->valueInteger();
else
return -1;
}
exprList = exprList->rhs();
}
}
}
return 0;
}

View File

@@ -11,7 +11,7 @@
bool isSPF_NoInline(Statement *stPrev);
template<typename fillType>
void fillPrivatesFromComment(Statement *st, std::set<fillType> &privates);
void fillPrivatesFromComment(Statement *st, std::set<fillType> &privates, int type = -1);
template<typename fillType>
void fillReductionsFromComment(Statement *st, std::map<std::string, std::set<fillType>> &reduction, bool moduleNameAdd = false);
@@ -40,3 +40,5 @@ void fillShrinkFromComment(Statement *stIn, std::vector<std::pair<fillType, std:
template<typename fillType>
void fillCheckpointFromComment(Statement *stIn, std::map<int, Expression*> &clauses, std::set<fillType> &vars, std::set<fillType> &expt);
int getCoverPropertyFromComment(Statement* stIn);

View File

@@ -156,6 +156,76 @@ static void fillVarsSets(SgStatement *iterator, SgStatement *end, set<string> &v
}
}
static bool checkCover(SgStatement* st,
SgStatement* attributeStatement,
const int coverLoops,
vector<Messages>& messagesForFile)
{
// COVER(VALUE)
const int var = st->variant();
bool retVal = true;
SgForStmt* forSt = (SgForStmt*)st;
const int nestedCount = countPerfectLoopNest(forSt);
if (coverLoops > nestedCount || coverLoops == 0)
{
__spf_print(1, "bad directive expression: expected %d nested loops on line %d but got %d on line %d\n",
coverLoops, attributeStatement->lineNumber(), nestedCount, st->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"bad directive expression: expected %d nested loops on line %d but got %d",
coverLoops, attributeStatement->lineNumber(), nestedCount);
__spf_printToLongBuf(messageR, R77, coverLoops, attributeStatement->lineNumber(), nestedCount);
messagesForFile.push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1043));
retVal = false;
}
return retVal;
}
static bool checkProcessPrivate(SgStatement* st,
SgStatement* attributeStatement,
const set<Symbol*>& privates,
vector<Messages>& messagesForFile)
{
// PROCESS_PRIVATE(VAR)
const int var = st->variant();
bool retVal = true;
if (!isSgExecutableStatement(st))
{
st = skipDvmDirs(st);
SgStatement* iterator = st;
SgStatement* end = st->lexNext();
set<string> varDef, varUse;
fillVarsSets(iterator, end, varDef, varUse);
for (auto& privElemS : privates)
{
const string privElem = privElemS->GetOriginal()->identifier();
bool defCond = true;
if (varDef.find(privElem) == varDef.end())
defCond = false;
if (!defCond)
{
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "variable declaration", RR1_2, "", L"", attributeStatement->lineNumber());
retVal = false;
}
}
}
else
{
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "variable declaration", RR1_2, "", L"", attributeStatement->lineNumber());
retVal = false;
}
return retVal;
}
static bool checkPrivate(SgStatement *st,
SgStatement *attributeStatement,
const set<Symbol*> &privates,
@@ -165,19 +235,16 @@ static bool checkPrivate(SgStatement *st,
const int var = st->variant();
bool retVal = true;
if (!isSgExecutableStatement(st) || var == FOR_NODE)
if (var == FOR_NODE)
{
st = skipDvmDirs(st);
SgStatement *iterator = st;
SgStatement *end = (var == FOR_NODE) ? st->lastNodeOfStmt() : st->lexNext();
set<string> varDef;
set<string> varUse;
fillVarsSets(iterator, end, varDef, varUse);
SgStatement *end = st->lastNodeOfStmt();
set<string> varDef, varUse;
set<string> wrongPrivFromOmpParallel;
for (auto &privElemS : privates)
fillVarsSets(iterator, end, varDef, varUse);
for (auto& privElemS : privates)
{
const string privElem = privElemS->GetOriginal()->identifier();
bool defCond = true;
@@ -188,51 +255,40 @@ static bool checkPrivate(SgStatement *st,
if (varUse.find(privElem) == varUse.end())
useCond = false;
if (var == FOR_NODE)
if (!defCond && !useCond)
{
if (!defCond && !useCond)
if (attributeStatement->localLineNumber() != 888)
{
if (attributeStatement->localLineNumber() != 888)
{
__spf_print(1, "variable '%s' is not used in loop on line %d\n", privElem.c_str(), attributeStatement->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"variable '%s' is not used in loop", to_wstring(privElem.c_str()).c_str());
__spf_print(1, "variable '%s' is not used in loop on line %d\n", privElem.c_str(), attributeStatement->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"variable '%s' is not used in loop", to_wstring(privElem.c_str()).c_str());
__spf_printToLongBuf(messageR, R21, to_wstring(privElem.c_str()).c_str());
__spf_printToLongBuf(messageR, R21, to_wstring(privElem.c_str()).c_str());
messagesForFile.push_back(Messages(WARR, attributeStatement->lineNumber(), messageR, messageE, 1002));
}
else
wrongPrivFromOmpParallel.insert(privElem);
}
else if (!defCond && useCond)
{
if (attributeStatement->localLineNumber() != 888)
{
__spf_print(1, "variable '%s' is not changed in loop on line %d\n", privElem.c_str(), attributeStatement->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"variable '%s' is not changed in loop", to_wstring(privElem.c_str()).c_str());
__spf_printToLongBuf(messageR, R23, to_wstring(privElem.c_str()).c_str());
messagesForFile.push_back(Messages(ERROR, attributeStatement->lineNumber(), messageR, messageE, 1003));
retVal = false;
}
else
wrongPrivFromOmpParallel.insert(privElem);
messagesForFile.push_back(Messages(WARR, attributeStatement->lineNumber(), messageR, messageE, 1002));
}
else
wrongPrivFromOmpParallel.insert(privElem);
}
else
else if (!defCond && useCond)
{
if (!defCond)
if (attributeStatement->localLineNumber() != 888)
{
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "variable declaration or", RR1_2, "DO statement", RR1_3, attributeStatement->lineNumber());
__spf_print(1, "variable '%s' is not changed in loop on line %d\n", privElem.c_str(), attributeStatement->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"variable '%s' is not changed in loop", to_wstring(privElem.c_str()).c_str());
__spf_printToLongBuf(messageR, R23, to_wstring(privElem.c_str()).c_str());
messagesForFile.push_back(Messages(ERROR, attributeStatement->lineNumber(), messageR, messageE, 1003));
retVal = false;
}
else
wrongPrivFromOmpParallel.insert(privElem);
}
}
if (var == FOR_NODE && wrongPrivFromOmpParallel.size()) // remove unnecessary
if (wrongPrivFromOmpParallel.size()) // remove unnecessary
{
if (wrongPrivFromOmpParallel.size() == privates.size()) // remove all
attributeStatement->expr(0)->lhs()->setLhs(NULL);
@@ -252,7 +308,7 @@ static bool checkPrivate(SgStatement *st,
}
else
{
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "variable declaration or", RR1_2, "DO statement", RR1_3, attributeStatement->lineNumber());
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "", L"", "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
@@ -1246,17 +1302,17 @@ static bool checkFissionPrivatesExpansion(SgStatement *st,
addSPFtoAttr(s, currFile, usersDirectives);
SgForStmt *forSt = (SgForStmt*)st;
if (vars.size() > countPerfectLoopNest(forSt))
const int nestedCount = countPerfectLoopNest(forSt);
if (vars.size() > nestedCount)
{
__spf_print(1, "bad directive expression: expected %d nested loops on line %d but got %d on line %d\n",
(int)vars.size(), attributeStatement->lineNumber(), countPerfectLoopNest(forSt), st->lineNumber());
(int)vars.size(), attributeStatement->lineNumber(), nestedCount, st->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"bad directive expression: expected %d nested loops on line %d but got %d",
(int)vars.size(), attributeStatement->lineNumber(), countPerfectLoopNest(forSt));
(int)vars.size(), attributeStatement->lineNumber(), nestedCount);
__spf_printToLongBuf(messageR, R77,
(int)vars.size(), attributeStatement->lineNumber(), countPerfectLoopNest(forSt));
__spf_printToLongBuf(messageR, R77, (int)vars.size(), attributeStatement->lineNumber(), nestedCount);
messagesForFile.push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1043));
@@ -1708,18 +1764,29 @@ static inline bool processStat(SgStatement *st, const string &currFile,
SgAttribute *attr = st->getAttribute(i);
SgStatement *attributeStatement = (SgStatement *)(attr->getAttributeData());
int type = st->attributeType(i);
int count;
if (type == SPF_ANALYSIS_DIR)
{
// !$SPF ANALYSIS
// PRIVATE(VAR)
set<Symbol*> privates;
fillPrivatesFromComment(new Statement(attributeStatement), privates);
fillPrivatesFromComment(new Statement(attributeStatement), privates, ACC_PRIVATE_OP);
if (privates.size())
{
bool result = checkPrivate(st, attributeStatement, privates, messagesForFile);
retVal = retVal && result;
}
// PROCESS_PRIVATE(VAR)
privates.clear();
fillPrivatesFromComment(new Statement(attributeStatement), privates, SPF_PROCESS_PRIVATE_OP);
if (privates.size())
{
bool result = checkProcessPrivate(st, attributeStatement, privates, messagesForFile);
retVal = retVal && result;
}
// REDUCTION(OP(VAR), MIN/MAXLOC(VAR, ARRAY, CONST))
map<string, set<Symbol*>> reduction;
map<string, set<tuple<Symbol*, Symbol*, int>>> reductionLoc;
@@ -1740,10 +1807,27 @@ static inline bool processStat(SgStatement *st, const string &currFile,
bool result = checkParameter(st, attributeStatement, assigns, messagesForFile);
retVal = retVal && result;
}
// COVER
if (isSPF_OP(attributeStatement, SPF_COVER_OP) && (count = countSPF_OP(st, SPF_ANALYSIS_DIR, SPF_COVER_OP)))
{
attributeStatement->setLocalLineNumber(-1);
if (count > 1 || st->variant() != FOR_NODE)
{
BAD_POSITION_FULL(1, ERROR, "once", RR1_7, "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
else
{
bool result = checkCover(st, attributeStatement, getCoverPropertyFromComment(new Statement(attributeStatement)), messagesForFile);
retVal = retVal && result;
}
}
}
else if (type == SPF_PARALLEL_DIR)
{
// !$SPF PARALLEL
// SHADOW (VAR(list of shadows)) / ACROSS (VAR(list of shadows))
vector<pair<pair<Symbol*, string>, vector<pair<int, int>>>> data;
fillShadowAcrossFromComment(SHADOW_OP, new Statement(attributeStatement), data);
@@ -1766,7 +1850,6 @@ static inline bool processStat(SgStatement *st, const string &currFile,
else if (type == SPF_TRANSFORM_DIR)
{
// !$SPF TRANSFORM
int count;
// NOINLINE
if (isSPF_NoInline(new Statement(st)))
@@ -1815,7 +1898,7 @@ static inline bool processStat(SgStatement *st, const string &currFile,
// SHRINK
if (isSPF_OP(attributeStatement, SPF_SHRINK_OP))
{
attributeStatement->setLocalLineNumber(-1); // is it needed?
attributeStatement->setLocalLineNumber(-1);
if (st->variant() != FOR_NODE)
{
BAD_POSITION_FULL(1, ERROR, "", "", "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
@@ -1838,6 +1921,17 @@ static inline bool processStat(SgStatement *st, const string &currFile,
retVal = false;
}
}
// MERGE
if (isSPF_OP(attributeStatement, SPF_MERGE_OP))
{
attributeStatement->setLocalLineNumber(-1);
if (st->variant() != FOR_NODE)
{
BAD_POSITION_FULL(1, ERROR, "", "", "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
}
}
else if (type == SPF_CHECKPOINT_DIR)
{

View File

@@ -1041,9 +1041,14 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
if (internalExit < 0)
throw -1;
bool applyFor = (curr_regime == LOOPS_SPLITTER || curr_regime == LOOPS_COMBINER || curr_regime == PRIVATE_REMOVING ||
curr_regime == PRIVATE_ARRAYS_EXPANSION || curr_regime == PRIVATE_ARRAYS_SHRINKING);
if ((countOfTransform == 0 || internalExit > 0) && applyFor)
set<int> applyFor = { LOOPS_SPLITTER,
LOOPS_COMBINER,
PRIVATE_REMOVING,
PRIVATE_ARRAYS_EXPANSION,
PRIVATE_ARRAYS_SHRINKING,
REMOVE_DEAD_CODE };
if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end())
{
SgStatement* mainUnit = findMainUnit(&project, SPF_messages);
checkNull(mainUnit, convertFileName(__FILE__).c_str(), __LINE__);

View File

@@ -381,11 +381,12 @@ public:
};
void removeDeadCode(SgStatement* func,
const map<string, vector<FuncInfo*>>& allFuncs,
const map<string, CommonBlock*>& commonBlocks,
SgStatement* intervalDelStart, SgStatement* intervalDelEnd)
int removeDeadCode(SgStatement* func,
const map<string, vector<FuncInfo*>>& allFuncs,
const map<string, CommonBlock*>& commonBlocks,
SgStatement* intervalDelStart, SgStatement* intervalDelEnd)
{
int countOfTransform = 0;
if (intervalDelStart && !intervalDelEnd || !intervalDelStart && intervalDelEnd)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -521,7 +522,8 @@ void removeDeadCode(SgStatement* func,
__spf_print(PRINT_USELESS_STATEMENTS, "[Useless statement on line %d and file %s]\n", rem->lineNumber(), rem->fileName());
rem->deleteStmt();
}
countOfTransform += remove.size();
//remove empty blocks
do
{
@@ -559,7 +561,10 @@ void removeDeadCode(SgStatement* func,
__spf_print(PRINT_USELESS_STATEMENTS, "[Useless block statement on line %d and file %s]\n", rem->lineNumber(), rem->fileName());
rem->deleteStmt();
}
countOfTransform += remove.size();
} while (remove.size());
deleteCFG(cfg);
return countOfTransform;
}

View File

@@ -9,7 +9,7 @@
#include "../CFGraph/DataFlow/data_flow.h"
#include "../CFGraph/DataFlow/backward_data_flow.h"
void removeDeadCode(SgStatement* func,
const std::map<std::string, std::vector<FuncInfo*>>&allFuncs,
const std::map<std::string, CommonBlock*>& commonBlocks,
SgStatement* intervalDelStart = NULL, SgStatement* intervalDelEnd = NULL);
int removeDeadCode(SgStatement* func,
const std::map<std::string, std::vector<FuncInfo*>>&allFuncs,
const std::map<std::string, CommonBlock*>& commonBlocks,
SgStatement* intervalDelStart = NULL, SgStatement* intervalDelEnd = NULL);

View File

@@ -1153,7 +1153,7 @@ bool isSPF_stat(SgStatement *st)
const int var = st->variant();
//for details see dvm_tag.h
if (var >= SPF_ANALYSIS_DIR && var <= SPF_UNROLL_OP)
if (var >= SPF_ANALYSIS_DIR && var <= SPF_PROCESS_PRIVATE_OP)
ret = true;
return ret;
}

View File

@@ -1,7 +1,7 @@
//1001
R1 = "Неверное расположение директивы: можно располагать только %s %s %s"
RR1_1 = "перед"
RR1_2 = "объявлением переменных или"
RR1_2 = "объявлением переменных"
RR1_3 = "циклом"
RR1_4 = "после"
RR1_5 = "всех операторов объявления"

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2308"
#define VERSION_SPF "2311"