Files
SAPFOR/src/Transformations/CheckPoints/checkpoints.cpp

1940 lines
79 KiB
C++
Raw Normal View History

#include "leak_detector.h"
2023-09-14 19:43:13 +03:00
#include <vector>
#include <string>
#include <set>
#include "../Utils/SgUtils.h"
#include "../Utils/utils.h"
#include "expr_transform.h"
2023-09-14 19:43:13 +03:00
#include "checkpoints.h"
using namespace std;
enum class typeEvery { TIME, ITER };
static const vector<string> iosNames = { "spf_close_all", "spf_open_all", "spf_inc_num_part" };
2024-05-22 21:02:04 +03:00
static SgStatement* replaceForWithWhile(SgStatement* forSt)
{
checkNull(forSt, convertFileName(__FILE__).c_str(), __LINE__);
auto forStat = isSgForStmt(forSt);
checkNull(forStat, convertFileName(__FILE__).c_str(), __LINE__);
auto start = forStat->start();
auto end = forStat->end();
auto step = forStat->step();
if (step == NULL)
step = new SgValueExp(1);
auto stepCalc = CalculateInteger(step->copyPtr());
auto doName = forStat->doName();
checkNull(start, convertFileName(__FILE__).c_str(), __LINE__);
checkNull(end, convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* insert = forSt->lexPrev();
SgStatement* doWhile = NULL;
if (stepCalc->isInteger())
{
const int stepValue = stepCalc->valueInteger();
auto cond = (stepValue > 0) ? (*new SgVarRefExp(doName) < end->copy()) : (*new SgVarRefExp(doName) > end->copy());
auto cond2 = (stepValue > 0) ? (*new SgVarRefExp(doName) > end->copy()) : (*new SgVarRefExp(doName) < end->copy());
SgLogIfStmt* logIf = new SgLogIfStmt(cond2, *new SgStatement(EXIT_STMT));
doWhile = new SgWhileStmt(&cond, NULL);
insert->insertStmtAfter(*doWhile, *insert->controlParent());
auto insertTo = doWhile->lastNodeOfStmt();
SgStatement* last = forSt->lastNodeOfStmt();
while (forSt->lexNext() != last)
{
auto body = forSt->lexNext();
insertTo->insertStmtBefore(*body->extractStmt(), *doWhile);
}
doWhile->insertStmtBefore(*new SgAssignStmt(*new SgVarRefExp(doName), start->copy() - step->copy()), *insert->controlParent());
doWhile->insertStmtAfter(*logIf, *doWhile);
doWhile->insertStmtAfter(*new SgAssignStmt(*new SgVarRefExp(doName), (*new SgVarRefExp(doName) + *step)), *doWhile);
doWhile->addComment(forSt->comments());
forSt->extractStmt();
}
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return doWhile;
}
static void checkForToReplace(SgStatement* gotoBlock, SgStatement* goPoint)
{
//return;
auto cp = gotoBlock->controlParent();
while (goPoint->controlParent() != cp)
{
auto top = goPoint->controlParent();
if (top->variant() == FOR_NODE)
goPoint = replaceForWithWhile(top);
else
goPoint = top;
}
}
static void createModule(SgStatement*& module, const string& name, bool withFile = true)
{
if (module == NULL)
{
string full_name = name;
if (withFile)
full_name += "_" + to_string(current_file_id);
module = new SgStatement(MODULE_STMT, NULL, new SgSymbol(MODULE_NAME, full_name.c_str()));
addControlEndToStmt(module->thebif);
SgStatement* global = current_file->firstStatement();
global->insertStmtAfter(*module, *global);
}
}
2023-09-14 19:43:13 +03:00
static SgType* createArrayCharType(int len, int dim)
{
if (dim == 0)
{
auto simpleType = new SgType(*SgTypeChar());
auto lenght = new SgValueExp(len);
simpleType->thetype->entry.Template.kind_len = lenght->thellnd;
return simpleType;
}
else
{
auto arrayType = new SgArrayType(*SgTypeChar());
arrayType->addDimension(new SgValueExp(dim));
auto lenght = new SgValueExp(len);
arrayType->baseType()->thetype->entry.Template.kind_len = lenght->thellnd;
return arrayType;
}
}
static void findDecls(SgExpression* ex, vector<SgExpression*>& local, const map<string, SgStatement*>& localParams,
2023-12-27 12:57:00 +03:00
set<string>& added, set<string>& intentInParams)
2023-09-14 19:43:13 +03:00
{
if (ex)
{
if (ex->variant() == VAR_REF)
{
if (ex->symbol()->variant() == VARIABLE_NAME &&
localParams.find(ex->symbol()->identifier()) == localParams.end())
{
2023-12-20 16:31:16 +03:00
if (added.find(ex->symbol()->identifier()) == added.end() &&
2023-12-27 12:57:00 +03:00
intentInParams.find(ex->symbol()->identifier()) == intentInParams.end())
2023-09-14 19:43:13 +03:00
{
added.insert(ex->symbol()->identifier());
local.push_back(ex);
}
}
}
if (ex->variant() == ARRAY_REF)
{
if (ex->symbol()->variant() == VARIABLE_NAME &&
2023-12-20 16:31:16 +03:00
added.find(ex->symbol()->identifier()) == added.end() &&
2023-12-27 12:57:00 +03:00
intentInParams.find(ex->symbol()->identifier()) == intentInParams.end())
2023-09-14 19:43:13 +03:00
{
added.insert(ex->symbol()->identifier());
local.push_back(new SgArrayRefExp(*ex->symbol()));
}
}
2023-12-27 12:57:00 +03:00
findDecls(ex->lhs(), local, localParams, added, intentInParams);
findDecls(ex->rhs(), local, localParams, added, intentInParams);
2023-09-14 19:43:13 +03:00
}
}
2023-12-20 16:31:16 +03:00
static FuncInfo* findFileInfoByName(SgStatement* func, const vector<FuncInfo*>& allFuncInfo)
2023-09-14 19:43:13 +03:00
{
2023-12-20 16:31:16 +03:00
FuncInfo* funcI = NULL;
for (const auto& funcs : allFuncInfo)
2023-12-20 16:31:16 +03:00
if (funcs->funcName == func->symbol()->identifier())
funcI = funcs;
checkNull(funcI, convertFileName(__FILE__).c_str(), __LINE__);
return funcI;
}
static void findLocalData(SgStatement* func, SgStatement* end, vector<SgExpression*>& local,
map<string, SgStatement*>& localParams, set<string>& added, const vector<FuncInfo*>& allFuncInfo)
{
SgStatement* start = func->lexNext();
FuncInfo* funcI = findFileInfoByName(func, allFuncInfo);
2023-12-27 12:57:00 +03:00
set<string> intentInParams;
2023-12-20 16:31:16 +03:00
for (int i = 0; i < funcI->funcParams.countOfPars; ++i)
if (funcI->funcParams.isArgIn(i) && !funcI->funcParams.isArgOut(i))
2023-12-27 12:57:00 +03:00
intentInParams.insert(funcI->funcParams.identificators[i]);
2023-12-20 16:31:16 +03:00
2023-09-14 19:43:13 +03:00
for (SgStatement* st = start; st != end; st = st->lexNext())
{
if (st->variant() == PARAM_DECL)
{
auto decl = (SgParameterStmt*)st;
for (int z = 0; z < decl->numberOfConstants(); ++z)
localParams[decl->constant(z)->identifier()] = st;
}
if (st->variant() == EXTERN_STAT)
for (SgExpression* ex = st->expr(0); ex; ex = ex->rhs())
added.insert(ex->lhs()->symbol()->identifier());
}
for (SgStatement* st = start; st != end; st = st->lexNext())
{
//printf("line %d %s Var %s\n", st->lineNumber(), st->fileName(), tag[st->variant()]);
if (st->variant() == VAR_DECL || st->variant() == VAR_DECL_90)
2023-12-27 12:57:00 +03:00
findDecls(st->expr(0), local, localParams, added, intentInParams);
2023-09-14 19:43:13 +03:00
}
}
static vector<SgStatement*> findUseOfModules(SgStatement* start, SgStatement* end)
{
vector<SgStatement*> ret;
for (SgStatement* st = start; st != end; st = st->lexNext())
if (st->variant() == USE_STMT)
ret.push_back(st);
return ret;
}
static vector<string> findAllModules()
{
vector<string> ret;
const string old_file = current_file->filename();
for (int z = 0; z < CurrentProject->numberOfFiles(); ++z)
{
SgFile* file = &CurrentProject->file(z);
vector<SgStatement*> modules;
findModulesInFile(file, modules);
for (auto& elem : modules)
ret.push_back(elem->symbol()->identifier());
}
if (SgFile::switchToFile(old_file) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return ret;
}
static SgExpression* getAttribute(SgExpression* spec, const string& type)
{
while (spec)
{
if (spec->lhs() && spec->lhs()->variant() == SPEC_PAIR)
{
if (spec->lhs()->lhs()->variant() == KEYWORD_VAL)
{
SgKeywordValExp* val = (SgKeywordValExp*)(spec->lhs()->lhs());
if (val->value() == type)
return spec->lhs()->rhs();
}
}
spec = spec->rhs();
}
return NULL;
}
static SgSymbol* makeVar(const string& name) { return new SgSymbol(VARIABLE_NAME, name.c_str()); }
static void insertToOpenClose(const map<int, UserFiles>& needToSave, const vector<string>& names, const vector<string>& closedStatus,
const string& iosModule)
{
int z = 0;
map<string, map<SgStatement*, set<string>>> useOnlyByFileAndFunc;
for (auto& elem : needToSave)
{
for (int k = 0; k < elem.second.placesOpen.size(); ++k)
{
auto lastFile = current_file->filename();
SgStatement* currOpen = elem.second.placesOpen[k];
if (!currOpen->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
currOpen->insertStmtAfter(*new SgAssignStmt(*new SgVarRefExp(makeVar(closedStatus[z])), *new SgValueExp(1)), *currOpen->controlParent());
auto fileN = getAttribute(((SgIOControlStmt*)currOpen)->controlSpecList(), "file");
checkNull(fileN, convertFileName(__FILE__).c_str(), __LINE__);
currOpen->insertStmtAfter(*new SgAssignStmt(*new SgVarRefExp(makeVar(names[z])), *fileN), *currOpen->controlParent());
auto fStat = getFuncStat(currOpen, { MODULE_STMT });
checkNull(fStat, convertFileName(__FILE__).c_str(), __LINE__);
useOnlyByFileAndFunc[currOpen->fileName()][fStat].insert(closedStatus[z]);
useOnlyByFileAndFunc[currOpen->fileName()][fStat].insert(names[z]);
if (SgFile::switchToFile(lastFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
++z;
}
z = 0;
for (auto& elem : needToSave)
{
for (int k = 0; k < elem.second.placesClose.size(); ++k)
{
auto lastFile = current_file->filename();
SgStatement* currClose = elem.second.placesClose[k];
if (!currClose->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
currClose->insertStmtAfter(*new SgAssignStmt(*new SgVarRefExp(makeVar(closedStatus[z])), *new SgValueExp(0)), *currClose->controlParent());
auto fStat = getFuncStat(currClose, { MODULE_STMT });
checkNull(fStat, convertFileName(__FILE__).c_str(), __LINE__);
useOnlyByFileAndFunc[currClose->fileName()][fStat].insert(closedStatus[z]);
if (SgFile::switchToFile(lastFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
++z;
}
auto lastFile = current_file->filename();
for (auto& byFile : useOnlyByFileAndFunc)
{
if (SgFile::switchToFile(byFile.first) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& byStat : byFile.second)
{
vector<SgExpression*> onlyList;
for (auto& elem : byStat.second)
onlyList.push_back(new SgVarRefExp(new SgSymbol(VARIABLE_NAME, elem.c_str())));
SgExpression* only = new SgExpression(ONLY_NODE, makeExprList(onlyList), NULL);
SgStatement* use = new SgStatement(USE_STMT, NULL, makeVar(iosModule), only, NULL, NULL);
byStat.first->insertStmtBefore(*use, *byStat.first);
}
}
if (SgFile::switchToFile(lastFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
static bool createForIOs(const map<int, UserFiles>& filesInfo, SgStatement* func)
{
SgStatement* moduleF = NULL;
map<int, UserFiles> needToSave;
for (auto& elem : filesInfo)
{
if (elem.second.placesClose.size() != elem.second.placesOpen.size())
if (elem.second.placesClose.size() > 0 && elem.second.placesOpen.size() > 0)
needToSave[elem.first] = elem.second;
if (elem.second.placesClose.size() == 0 && elem.second.placesWrite.size() > 0 && elem.second.placesRead.size() == 0)
needToSave[elem.first] = elem.second;
}
if (needToSave.size() == 0)
return false;
const string iosModule = "spf_module_ios";
createModule(moduleF, iosModule, false);
vector<SgSymbol*> closedStatus;
vector<SgExpression*> closedStatusInit;
SgSymbol* counter = new SgSymbol(VARIABLE_NAME, "num_part", SgTypeInt(), func);
vector<SgSymbol*> names;
for (auto& elem : needToSave)
{
closedStatus.push_back(new SgSymbol(VARIABLE_NAME, ("spf_state_" + to_string(elem.first)).c_str(), SgTypeInt(), func));
closedStatusInit.push_back(new SgValueExp(0));
names.push_back(new SgSymbol(VARIABLE_NAME, ("spf_name_" + to_string(elem.first)).c_str(), createArrayCharType(32, 0), func));
}
makeDeclaration(moduleF, closedStatus, &closedStatusInit);
makeDeclaration(moduleF, names);
makeDeclaration(moduleF, { counter }, &closedStatusInit);
moduleF->lastNodeOfStmt()->insertStmtBefore(*new SgStatement(CONTAINS_STMT), *moduleF);
SgProcHedrStmt* close = new SgProcHedrStmt(iosNames[0].c_str());
SgProcHedrStmt* open = new SgProcHedrStmt(iosNames[1].c_str());
SgProcHedrStmt* inc = new SgProcHedrStmt(iosNames[2].c_str());
moduleF->lastNodeOfStmt()->insertStmtBefore(*close, *moduleF);
moduleF->lastNodeOfStmt()->insertStmtBefore(*open, *moduleF);
moduleF->lastNodeOfStmt()->insertStmtBefore(*inc, *moduleF);
inc->insertStmtAfter(*new SgAssignStmt(*new SgVarRefExp(counter), *new SgVarRefExp(counter) + *new SgValueExp(1)), *inc);
int z = 0;
for (auto& elem : needToSave)
{
SgIfStmt* ifstat = new SgIfStmt(*new SgVarRefExp(closedStatus[z]) != *new SgValueExp(0), *new SgIOControlStmt(CLOSE_STAT, *new SgValueExp(elem.first)));
ifstat->insertStmtAfter(*new SgAssignStmt(*new SgVarRefExp(closedStatus[z]), *new SgValueExp(0)), *ifstat);
close->insertStmtAfter(*ifstat, *close);
++z;
}
z = 0;
auto sSTR = new SgSymbol(FUNCTION_NAME, "TO_STR", createArrayCharType(32, 0), moduleF);
auto trim = new SgSymbol(FUNCTION_NAME, "TRIM");
for (auto& elem : needToSave)
{
vector<SgExpression*> listSpec;
/*listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("iostat"), *iostat));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("status"), *new SgValueExp("old")));*/
auto fCall = new SgFunctionCallExp(*trim, *new SgVarRefExp(names[z]));
auto fCall2 = new SgFunctionCallExp(*trim, *new SgFunctionCallExp(*sSTR, *new SgVarRefExp(counter)));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("file"), *new SgExpression(CONCAT_OP, fCall, fCall2)));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("unit"), *new SgValueExp(elem.first)));
SgIfStmt* ifstat = new SgIfStmt(*new SgVarRefExp(closedStatus[z]) == *new SgValueExp(0), *new SgIOControlStmt(OPEN_STAT, *makeExprList(listSpec, false)));
ifstat->insertStmtAfter(*new SgAssignStmt(*new SgVarRefExp(closedStatus[z]), *new SgValueExp(1)), *ifstat);
open->insertStmtAfter(*ifstat, *open);
++z;
}
auto k_par = new SgSymbol(VARIABLE_NAME, "k");
SgFuncHedrStmt* str_func = new SgFuncHedrStmt(*sSTR);
moduleF->lastNodeOfStmt()->insertStmtBefore(*str_func, *moduleF);
str_func->AddArg(*new SgVarRefExp(k_par));
str_func->setExpression(0, NULL); //bad solution!
str_func->insertStmtAfter(*makeDeclaration(NULL, { sSTR }), *str_func);
str_func->lastNodeOfStmt()->insertStmtBefore(*new SgInputOutputStmt(WRITE_STAT, *makeExprList({ new SgKeywordValExp("*"), new SgVarRefExp(sSTR)}, false), *new SgVarRefExp(k_par)), *str_func);
SgAssignStmt* adjustl = new SgAssignStmt(*new SgVarRefExp(sSTR), *new SgFunctionCallExp(*new SgSymbol(FUNCTION_NAME, "ADJUSTL"), *new SgVarRefExp(sSTR)));
str_func->lastNodeOfStmt()->insertStmtBefore(*adjustl, *str_func);
vector<string> namesS, closedStatusS;
for (int z = 0; z < names.size(); ++z)
{
namesS.push_back(names[z]->identifier());
closedStatusS.push_back(closedStatus[z]->identifier());
}
insertToOpenClose(needToSave, namesS, closedStatusS, iosModule);
moduleF->insertStmtAfter(*new SgImplicitStmt(NULL), *moduleF);
return true;
}
struct cpInfo
{
int line = -1;
int every = 60;
int numOfFiles = 2;
int unitNum = 789;
typeEvery type = typeEvery::ITER;
};
static bool findSpfCpDir(SgFile* file, map<int, cpInfo>& info)
{
bool found = false;
int numF = file->numberOfFunctions();
for (int z = 0; z < numF; ++z)
{
SgStatement* func = file->functions(z);
for (SgStatement* st = func; st != func->lastNodeOfStmt(); st = st->lexNext())
{
if (st->variant() == CONTAINS_STMT)
break;
if (!isSgExecutableStatement(st))
continue;
vector<SgStatement*> cpDirs = getAttributes<SgStatement*, SgStatement*>(st, set<int>{ SPF_CHECKPOINT_DIR });
if (cpDirs.size() == 1)
{
found = true;
cpInfo currInfo;
currInfo.line = st->lineNumber();
SgExpression* ex = cpDirs[0]->expr(0);
while (ex)
{
if (ex->lhs())
{
int var = ex->lhs()->variant();
if (var == SPF_INTERVAL_OP)
{
int type = ex->lhs()->lhs()->variant();
if (!ex->lhs()->rhs()->isInteger())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
int interval = ex->lhs()->rhs()->valueInteger();
if (type == SPF_ITER_OP)
{
currInfo.type = typeEvery::ITER;
currInfo.every = interval;
}
else if (type == SPF_TIME_OP)
{
currInfo.type = typeEvery::TIME;
currInfo.every = interval;
}
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
else if (var == SPF_FILES_COUNT_OP)
{
if (!ex->lhs()->lhs()->isInteger())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
currInfo.numOfFiles = ex->lhs()->lhs()->valueInteger();
}
}
ex = ex->rhs();
}
info[currInfo.line] = currInfo;
}
else if (cpDirs.size() > 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
deleteAttributes(st, set<int>{ SPF_CHECKPOINT_DIR });
}
}
return found;
}
static void fillToProcess(FuncInfo* funcI, set<pair<FuncInfo*, FuncInfo*>>& toProcess)
{
int oldSize = toProcess.size();
for (int k = 0; k < funcI->callsTo.size(); k++)
{
pair<FuncInfo*, FuncInfo*> n(funcI, funcI->callsTo[k]);
toProcess.insert(n);
if (toProcess.size() != oldSize)
{
oldSize = toProcess.size();
fillToProcess(funcI->callsTo[k], toProcess);
}
}
}
//TODO: reverse if 'before' == false
static int insertInitNamesOfFiles(const int numOfFiles, const string& additional, SgSymbol* files, SgArrayRefExp* journal,
SgStatement* insert, bool before = true)
{
int maxFileLen = -1;
string tmp;
for (int z = 1; z <= numOfFiles; ++z)
{
tmp = "spf_cp_file_" + to_string(z) + additional;
maxFileLen = std::max(maxFileLen, (int)(tmp.size() + 1));
if (insert)
{
if (before)
insert->insertStmtBefore(*new SgAssignStmt(*new SgArrayRefExp(*files, *new SgValueExp(z)), *new SgValueExp(tmp.c_str())), *insert->controlParent());
else
insert->insertStmtAfter(*new SgAssignStmt(*new SgArrayRefExp(*files, *new SgValueExp(z)), *new SgValueExp(tmp.c_str())), *insert->controlParent());
2023-09-14 19:43:13 +03:00
}
}
tmp = "spf_cp_journal" + additional;
if (insert)
{
if (before)
insert->insertStmtBefore(*new SgAssignStmt(*journal, *new SgValueExp(tmp.c_str())), *insert->controlParent());
else
insert->insertStmtAfter(*new SgAssignStmt(*journal, *new SgValueExp(tmp.c_str())), *insert->controlParent());
2023-09-14 19:43:13 +03:00
}
return maxFileLen;
}
static void replaceExprByExprInExpr(SgExpression* expr, SgExpression* from, SgExpression* to)
{
map<SgExpression*, string> collection;
if (!expr)
return;
if (isEqExpressions(expr->rhs(), from, collection))
expr->setRhs(to);
if (isEqExpressions(expr->lhs(), from, collection))
expr->setLhs(to);
replaceExprByExprInExpr(expr->rhs(), from, to);
replaceExprByExprInExpr(expr->lhs(), from, to);
}
static void replaceExprByExprInSt(SgStatement* st, SgExpression* from, SgExpression* to)
{
map<SgExpression*, string> collection;
for (int i = 0; i < 3; i++)
{
SgExpression* expr = st->expr(i);
if (!expr)
continue;
if (isEqExpressions(expr, from, collection))
st->setExpression(i, to);
if (isEqExpressions(expr->rhs(), from, collection))
expr->setRhs(to);
if (isEqExpressions(expr->lhs(), from, collection))
expr->setLhs(to);
else
{
replaceExprByExprInExpr(expr->rhs(), from, to);
replaceExprByExprInExpr(expr->lhs(), from, to);
}
}
}
2023-12-18 21:12:27 +03:00
static SgStatement* createOpenJ_old(SgExpression* iostat, SgArrayRefExp* journal, SgExpression& unit)
{
vector<SgExpression*> listSpec;
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("iostat"), *iostat));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("status"), *new SgValueExp("old")));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("file"), *journal));
listSpec.push_back(&unit);
SgIOControlStmt* openJ_old = new SgIOControlStmt(OPEN_STAT, *makeExprList(listSpec, false));
return openJ_old;
}
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
static SgStatement* createOpen(SgExpression* iostat, SgSymbol* files, SgExpression* fileIdx, SgExpression& unit)
2023-09-14 19:43:13 +03:00
{
2023-12-18 21:12:27 +03:00
vector<SgExpression*> listSpec;
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("form"), *new SgValueExp("unformatted")));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("iostat"), *iostat));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("status"), *new SgValueExp("old")));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("file"), *new SgArrayRefExp(*files, *fileIdx)));
listSpec.push_back(&unit);
SgIOControlStmt* open = new SgIOControlStmt(OPEN_STAT, *makeExprList(listSpec, false));
return open;
}
2023-09-14 19:43:13 +03:00
static string mergedChar(const string& l, const string& r)
2023-12-18 21:12:27 +03:00
{
return l + "_" + r;
}
2023-12-18 21:12:27 +03:00
static SgSymbol* renamedNewSymb(SgSymbol* oldSymb, const char* prefix)
{
const string result = mergedChar(prefix, oldSymb->identifier());
SgSymbol* newSymb = new SgSymbol(oldSymb->variant(), result.c_str(), oldSymb->type(), oldSymb->scope());
2023-12-18 21:12:27 +03:00
return newSymb;
}
static void renameEx(SgExpression* sizeEx, const char* funcName)
{
if (sizeEx->variant() == CONST_REF)
2023-09-14 19:43:13 +03:00
{
SgSymbol* symbSize = renamedNewSymb(sizeEx->symbol(), funcName);
sizeEx->setSymbol(symbSize);
}
2023-12-18 21:12:27 +03:00
if (sizeEx->lhs())
renameEx(sizeEx->lhs(), funcName);
2023-12-18 21:12:27 +03:00
if (sizeEx->rhs())
renameEx(sizeEx->rhs(), funcName);
}
2023-12-18 21:12:27 +03:00
static void findSizeEx(SgExpression* sizeEx, const map<string, SgStatement*>& moduleStmts,
const map<string, SgStatement*>& moduleParamStmts, SgStatement* proc_moduleF,
set<string>& addedModuleParams, SgStatement* borderStmt)
{
if (sizeEx->variant() == CONST_REF)
{
if (moduleParamStmts.count(sizeEx->symbol()->identifier()) == 1 && addedModuleParams.count(sizeEx->symbol()->identifier()) == 0)
2023-09-14 19:43:13 +03:00
{
auto decl = (SgParameterStmt*)moduleParamStmts.at(sizeEx->symbol()->identifier());
2023-12-18 21:12:27 +03:00
SgStatement* copyParamStmt = moduleParamStmts.at(sizeEx->symbol()->identifier())->copyPtr();
borderStmt->insertStmtBefore(*copyParamStmt, *proc_moduleF);
2023-12-18 21:12:27 +03:00
if (moduleStmts.count(sizeEx->symbol()->identifier()))
2023-09-14 19:43:13 +03:00
{
SgStatement* copyStmt = moduleStmts.at(sizeEx->symbol()->identifier())->copyPtr();
copyParamStmt->insertStmtBefore(*copyStmt, *proc_moduleF);
borderStmt = copyStmt;
}
else
borderStmt = copyParamStmt;
addedModuleParams.insert(sizeEx->symbol()->identifier());
findSizeEx(decl->value(0), moduleStmts, moduleParamStmts, proc_moduleF, addedModuleParams, borderStmt);
}
}
if (sizeEx->lhs())
findSizeEx(sizeEx->lhs(), moduleStmts, moduleParamStmts, proc_moduleF, addedModuleParams, borderStmt);
if (sizeEx->rhs())
findSizeEx(sizeEx->rhs(), moduleStmts, moduleParamStmts, proc_moduleF, addedModuleParams, borderStmt);
}
static void processCommonStmt(SgStatement* st, set<string>& commonVariables)
{
if (st->expr(0))
{
SgExpression* ex = st->expr(0)->lhs();
while (ex && ex->lhs())
{
auto lhs = ex->lhs();
commonVariables.insert(lhs->sunparse());
ex = ex->rhs();
}
}
}
2023-09-14 19:43:13 +03:00
static void processVarStmt(SgStatement* st, map<string, SgStatement*>& moduleStmts, const char* funcName,
const set<string>& inFuncParam)
{
SgExpression* ex = st->expr(0);
2024-05-16 14:15:02 +03:00
SgExpression* lhs = NULL;
2023-09-14 19:43:13 +03:00
SgStatement* baseStmt = st->copyPtr();
baseStmt->expr(0)->setLhs(NULL);
baseStmt->expr(0)->setRhs(NULL);
baseStmt->setExpression(2, NULL);
2023-09-14 19:43:13 +03:00
while (ex && ex->lhs())
{
lhs = ex->lhs();
2023-12-18 21:12:27 +03:00
if (inFuncParam.count(lhs->symbol()->identifier()))
{
ex = ex->rhs();
continue;
}
2023-12-18 21:12:27 +03:00
const string result = mergedChar(funcName, lhs->symbol()->identifier());
SgSymbol* symb = new SgSymbol(lhs->symbol()->variant(), result.c_str(), lhs->symbol()->type(), lhs->symbol()->scope());
SgExpression* newExpr = new SgExpression(lhs->variant());
newExpr->setSymbol(symb);
2023-12-18 21:12:27 +03:00
if (lhs->variant() == ARRAY_REF)
{
SgExpression* newArraySizeExpr = lhs->lhs()->copyPtr();
2023-12-18 21:12:27 +03:00
SgExpression* sizeEx = newArraySizeExpr;
SgExpression* sizeLhs;
2023-12-18 21:12:27 +03:00
while (sizeEx && sizeEx->lhs())
2023-09-14 19:43:13 +03:00
{
sizeLhs = sizeEx->lhs();
renameEx(sizeLhs, funcName);
sizeEx = sizeEx->rhs();
2023-09-14 19:43:13 +03:00
}
newExpr->setLhs(newArraySizeExpr);
}
SgStatement* moduleStmt = baseStmt->copyPtr();
moduleStmt->setExpression(0, newExpr);
SgExpression* typeExpr = st->expr(1)->copyPtr();
moduleStmt->setExpression(1, typeExpr);
moduleStmts[newExpr->symbol()->identifier()] = moduleStmt;
ex = ex->rhs();
}
}
static void processParamStmt(SgStatement* st, map<string, SgStatement*>& moduleParamStmts, const char* funcName)
{
auto decl = (SgParameterStmt*)st;
int n = decl->numberOfConstants();
for (int i = 0; i < n; ++i)
{
SgSymbol* constSymb = renamedNewSymb(decl->constant(i), funcName);
SgExpression* constExpr = new SgExpression(CONST_REF, NULL, NULL, constSymb);
SgExpression* valueExpr = decl->value(i)->copyPtr();
renameEx(valueExpr, funcName);
SgConstantSymb* paramSymb = new SgConstantSymb(constSymb->identifier(), *decl->controlParent(), *valueExpr);
SgParameterStmt* paramSt = new SgParameterStmt();
paramSt->addConstant(paramSymb);
moduleParamStmts[constSymb->identifier()] = paramSt;
}
}
static void processExternStmt(SgStatement* st, set<string>& externVars)
{
if (st->expr(0))
{
SgExpression* ex = st->expr(0);
SgExpression* lhs;
while (ex && ex->lhs())
{
lhs = ex->lhs();
externVars.insert(lhs->sunparse());
ex = ex->rhs();
2023-12-18 21:12:27 +03:00
}
}
}
static void processVarBlock(SgStatement* func, SgStatement* firstExec, map<string, SgStatement*>& moduleStmts,
map<string, SgStatement*>& moduleParamStmts, set<string>& commonVariables,
set<string>& externVars, FuncInfo* funcFrom, const set<string>& inFuncParam = { })
{
const char* funcName = func->symbol()->identifier();
2023-09-14 19:43:13 +03:00
for (SgStatement* st = func->lexNext(); st != firstExec; st = st->lexNext())
{
if (st->variant() == COMM_STAT)
processCommonStmt(st, commonVariables);
else if (st->variant() == VAR_DECL || st->variant() == VAR_DECL_90)
processVarStmt(st, moduleStmts, funcName, inFuncParam);
else if (st->variant() == PARAM_DECL)
processParamStmt(st, moduleParamStmts, funcName);
else if (st->variant() == EXTERN_STAT)
processExternStmt(st, externVars);
}
}
static void insertStmtToModule(const map<string, SgStatement*>& moduleStmts, const map<string, SgStatement*>& moduleParamStmts,
set<string>& addedModuleParams, const set<string>& commonVariables, SgStatement* proc_moduleF,
set<string>& localVarNoParams, const set<string>& externVars, const size_t prefixLen)
{
SgStatement* endProcModuleF = proc_moduleF->lastNodeOfStmt();
SgStatement* borderStmt = new SgStatement(VAR_DECL);
proc_moduleF->insertStmtAfter(*borderStmt, *proc_moduleF);
2024-05-25 17:41:28 +03:00
for (auto& stat : moduleStmts)
{
2024-05-25 17:41:28 +03:00
const auto& varName = stat.first;
SgStatement* varStmt = stat.second;
string varNameNoPref = varName;
2024-05-16 14:15:02 +03:00
varNameNoPref.erase(0, prefixLen + 1);
if (commonVariables.count(varNameNoPref) == 0 && moduleParamStmts.count(varName) == 0
&& externVars.count(varNameNoPref) == 0)
2023-12-18 21:12:27 +03:00
{
localVarNoParams.insert(varNameNoPref);
2023-09-14 19:43:13 +03:00
endProcModuleF->insertStmtBefore(*varStmt, *proc_moduleF);
if (varStmt->expr(0)->variant() == ARRAY_REF)
2023-12-18 21:12:27 +03:00
{
SgExpression* arraySizeExpr = varStmt->expr(0)->lhs();
2023-09-14 19:43:13 +03:00
SgExpression* sizeEx = arraySizeExpr;
SgExpression* sizeLhs;
2023-09-14 19:43:13 +03:00
while (sizeEx && sizeEx->lhs())
{
sizeLhs = sizeEx->lhs();
findSizeEx(sizeLhs, moduleStmts, moduleParamStmts, proc_moduleF, addedModuleParams, borderStmt);
2023-09-14 19:43:13 +03:00
sizeEx = sizeEx->rhs();
2023-12-18 21:12:27 +03:00
}
}
}
}
borderStmt->deleteStmt();
}
static SgStatement* createLoadBlock(const vector<SgSymbol*>& loadS, FuncInfo*& funcI, SgExpression* iostat, SgArrayRefExp* journal,
SgExpression& frmt, SgExpression& unit, SgSymbol* files, SgExpression* fileIdx, const int numOfFiles,
const vector<SgSymbol*>& profS, SgExpression& frmtProf, SgExpression& unitNull,
SgStatement* profCallS, SgStatement* profCallE, const set<string>& localVarNoParams,
const map<string, SgStatement*>& moduleStmts, const set<string>& commonVariables, bool createdModuleForIO,
const vector<string>& moduleNames, const int unitNum,
const string& baseFunc, vector<vector<string>>& chainLocalVarNoParams,
bool isBaseFunc = true, SgSymbol* procLabelSymb = NULL)
{
const char* funcName = funcI->funcName.c_str();
vector<SgStatement*> insertToLoadS;
SgStatement* loadBlock = new SgIfStmt(*new SgVarRefExp(loadS[0]) == *new SgValueExp(1)); //*new SgVarRefExp(loadS[0])
loadBlock->addComment("! LOAD CHECKPOINT\n");
if (funcI->isMain)
{
SgAssignStmt* init = new SgAssignStmt(*new SgVarRefExp(loadS[0]), *new SgValueExp(0));
insertToLoadS.push_back(init);
insertToLoadS.push_back(createOpenJ_old(iostat, journal, unit));
}
vector<SgStatement*> insertToifLoadOk;
SgIfStmt* ifLoadOk = new SgIfStmt(*iostat == *new SgValueExp(0));
insertToLoadS.push_back(ifLoadOk);
if (funcI->isMain)
{
SgInputOutputStmt* read = new SgInputOutputStmt(READ_STAT, *makeExprList({ &frmt, &unit }, false), *fileIdx); //*makeExprList({ fileIdx, labelIdx })
insertToifLoadOk.push_back(read);
insertToifLoadOk.push_back(new SgIOControlStmt(CLOSE_STAT, unit));
insertToifLoadOk.push_back(createOpen(iostat, files, fileIdx, unit));
}
SgIfStmt* ifLoadOk1 = new SgIfStmt(*iostat == *new SgValueExp(0)); //, *new SgIOControlStmt(CLOSE_STAT, unit)
insertToifLoadOk.push_back(ifLoadOk1);
if (funcI->isMain)
{
SgAssignStmt* init = new SgAssignStmt(*new SgVarRefExp(loadS[0]), *new SgValueExp(1));
ifLoadOk1->insertStmtAfter(*init, *ifLoadOk1);
}
if (isBaseFunc)
{
ifLoadOk1->insertStmtAfter(*new SgIOControlStmt(CLOSE_STAT, unit), *ifLoadOk1);
ifLoadOk1->insertStmtAfter(*new SgIfStmt(*fileIdx == *new SgValueExp(numOfFiles + 1), *new SgAssignStmt(*fileIdx, *new SgValueExp(1))), *ifLoadOk1);
ifLoadOk1->insertStmtAfter(*new SgAssignStmt(*fileIdx, *fileIdx + *new SgValueExp(1)), *ifLoadOk1);
}
ifLoadOk1->addComment("! LOAD DATA FROM CHECKPOINT\n");
vector<SgExpression*> commentArgs;
commentArgs.push_back(new SgValueExp(" SECONDS"));
commentArgs.push_back(&(*new SgVarRefExp(profS[1]) - *new SgVarRefExp(profS[0])));
commentArgs.push_back(new SgArrayRefExp(*files, *fileIdx));
commentArgs.push_back(new SgValueExp("SPF CHECKPOINT LOADED FROM "));
ifLoadOk1->insertStmtAfter(*new SgInputOutputStmt(WRITE_STAT, *makeExprList({ &frmtProf, &unitNull }, false), *makeExprList(commentArgs, false)), *ifLoadOk1);
ifLoadOk1->insertStmtAfter(*profCallE->copyPtr(), *ifLoadOk1);
// insert copy_block
for (auto localVar : localVarNoParams)
{
SgSymbol* leftSymb = new SgSymbol(VARIABLE_NAME, localVar.c_str());
SgExpression* leftEx = new SgVarRefExp(leftSymb);
SgSymbol* rightSymb = renamedNewSymb(leftSymb, funcName);
SgExpression* rightEx = new SgVarRefExp(rightSymb);
ifLoadOk1->insertStmtAfter(*new SgAssignStmt(*leftEx, *rightEx), *ifLoadOk1);
}
//open all files
if (createdModuleForIO)
{
SgCallStmt* call = new SgCallStmt(*new SgSymbol(FUNCTION_NAME, iosNames[1].c_str()));
ifLoadOk1->insertStmtAfter(*call, *ifLoadOk1);
}
//READ LOCAL DATA
vector<string> varNames;
if (moduleStmts.size())
{
vector<SgExpression*> variablesVec;
for (auto localVar : localVarNoParams)
{
const char* varName = localVar.c_str();
const string varNameWithPref = mergedChar(funcName, varName);
SgSymbol* symbVar = new SgSymbol(VARIABLE_NAME, varNameWithPref.c_str());
SgExpression* exVar = new SgVarRefExp(symbVar);
variablesVec.push_back(exVar);
varNames.push_back(varNameWithPref);
}
auto dataRead = new SgInputOutputStmt(READ_STAT, unit, *makeExprList(variablesVec, false));
ifLoadOk1->insertStmtAfter(*dataRead, *ifLoadOk1);
}
chainLocalVarNoParams.push_back(varNames);
if (!isBaseFunc)
{
SgExpression* procLabelExpr = new SgVarRefExp(procLabelSymb);
auto labelRead = new SgInputOutputStmt(READ_STAT, unit, *procLabelExpr);
ifLoadOk1->insertStmtAfter(*labelRead, *ifLoadOk1);
}
//READ from modules
for (auto& mod : moduleNames)
{
2024-05-16 14:15:02 +03:00
SgCallStmt* call = new SgCallStmt(*new SgSymbol(FUNCTION_NAME, ("spf_cp_" + mod).c_str()));
call->addArg(*new SgValueExp(unitNum));
call->addArg(*new SgValueExp(0));
ifLoadOk1->insertStmtAfter(*call, *ifLoadOk1);
}
//READ COMMON DATA
if (funcI->isMain)
if (commonVariables.size())
{
vector<SgExpression*> commanVariablesVec;
for (auto commanVar : commonVariables)
2023-12-18 21:12:27 +03:00
{
SgSymbol* symbCommon = new SgSymbol(VARIABLE_NAME, commanVar.c_str());
SgExpression* exCommon = new SgVarRefExp(symbCommon);
commanVariablesVec.push_back(exCommon);
2023-12-18 21:12:27 +03:00
}
auto commonDataRead = new SgInputOutputStmt(READ_STAT, unit, *makeExprList(commanVariablesVec, false));
ifLoadOk1->insertStmtAfter(*commonDataRead, *ifLoadOk1);
}
2023-09-14 19:43:13 +03:00
ifLoadOk1->insertStmtAfter(*profCallS->copyPtr(), *ifLoadOk1);
for (int z = insertToLoadS.size() - 1; z >= 0; --z)
loadBlock->insertStmtAfter(*insertToLoadS[z], *loadBlock);
for (int z = insertToifLoadOk.size() - 1; z >= 0; --z)
ifLoadOk->insertStmtAfter(*insertToifLoadOk[z], *ifLoadOk);
return loadBlock;
}
static SgSymbol* createLabel(const string namelabel, SgStatement*& proc_moduleF)
{
SgSymbol* procLabelSymb = new SgSymbol(VARIABLE_NAME, namelabel.c_str(), SgTypeInt(), proc_moduleF);
SgExpression* procLabel0 = new SgValueExp(0);
vector<SgSymbol*> vecLabelSymb = { procLabelSymb };
vector<SgExpression*> vecLabel0 = { procLabel0 };
makeDeclaration(proc_moduleF, vecLabelSymb, &vecLabel0);
2023-09-14 19:43:13 +03:00
return procLabelSymb;
}
2023-09-14 19:43:13 +03:00
static SgStatement* createSaveBlock(const vector<SgSymbol*>& loadS, FuncInfo*& funcI, SgExpression* iostat, SgArrayRefExp* journal,
SgExpression& frmt, SgExpression& unit, SgSymbol* files, SgExpression* fileIdx, const int numOfFiles,
const vector<SgSymbol*>& profS, SgExpression& frmtProf, SgExpression& unitNull,
SgStatement* profCallS, SgStatement* profCallE, const set<string>& localVarNoParams,
const map<string, SgStatement*>& moduleStmts, const set<string>& commonVariables, bool createdModuleForIO,
const vector<string>& moduleNames, const int unitNum, const vector<vector<string>>& chainLocalVarNoParams,
const vector<string>& chainLabel)
{
2024-05-22 21:02:04 +03:00
SgStatement* storeBlock = new SgIfStmt((SgExpression*)NULL);
2023-09-14 19:43:13 +03:00
vector<SgExpression*> listSpec;
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("form"), *new SgValueExp("unformatted")));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("iostat"), *iostat));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("file"), *new SgArrayRefExp(*files, *fileIdx)));
listSpec.push_back(&unit);
2023-09-14 19:43:13 +03:00
SgIOControlStmt* open = new SgIOControlStmt(OPEN_STAT, *makeExprList(listSpec, false));
storeBlock->insertStmtAfter(*open, *storeBlock);
2023-09-14 19:43:13 +03:00
SgIfStmt* ifStoreOk = new SgIfStmt(*iostat == *new SgValueExp(0));
open->insertStmtAfter(*ifStoreOk, *storeBlock);
ifStoreOk->insertStmtAfter(*new SgIfStmt(*fileIdx == *new SgValueExp(numOfFiles + 1), *new SgAssignStmt(*fileIdx, *new SgValueExp(1))), *ifStoreOk);
ifStoreOk->insertStmtAfter(*new SgAssignStmt(*fileIdx, *fileIdx + *new SgValueExp(1)), *ifStoreOk);
ifStoreOk->addComment(("! STORE DATA TO CHECKPOINT " + to_string(localVarNoParams.size() + commonVariables.size()) + " items\n").c_str());
//commentArgs.clear();
vector<SgExpression*> commentArgs;
commentArgs.push_back(new SgValueExp(" SECONDS"));
commentArgs.push_back(&(*new SgVarRefExp(profS[1]) - *new SgVarRefExp(profS[0])));
commentArgs.push_back(new SgArrayRefExp(*files, *fileIdx));
commentArgs.push_back(new SgValueExp("SPF CHECKPOINT STORED TO "));
2023-09-14 19:43:13 +03:00
ifStoreOk->insertStmtAfter(*new SgInputOutputStmt(WRITE_STAT, *makeExprList({ &frmtProf, &unitNull }, false), *makeExprList(commentArgs, false)), *ifStoreOk);
ifStoreOk->insertStmtAfter(profCallE->copy(), *ifStoreOk);
2023-09-14 19:43:13 +03:00
SgStatement* assign = ifStoreOk->lexNext();
2023-09-14 19:43:13 +03:00
//open all files
if (createdModuleForIO)
{
SgCallStmt* call = new SgCallStmt(*new SgSymbol(FUNCTION_NAME, iosNames[1].c_str()));
ifStoreOk->insertStmtAfter(*call, *ifStoreOk);
}
//WRITE from modules
for (auto& mod : moduleNames)
{
2024-05-16 14:15:02 +03:00
SgCallStmt* call = new SgCallStmt(*new SgSymbol(FUNCTION_NAME, ("spf_cp_" + mod).c_str()));
call->addArg(*new SgValueExp(unitNum));
call->addArg(*new SgValueExp(1));
ifStoreOk->insertStmtAfter(*call, *ifStoreOk);
}
//close and inc
if (createdModuleForIO)
{
SgCallStmt* call = new SgCallStmt(*new SgSymbol(FUNCTION_NAME, iosNames[2].c_str()));
ifStoreOk->insertStmtAfter(*call, *ifStoreOk);
call = new SgCallStmt(*new SgSymbol(FUNCTION_NAME, iosNames[0].c_str()));
ifStoreOk->insertStmtAfter(*call, *ifStoreOk);
}
if (moduleStmts.size())
{
vector<SgExpression*> variablesVec;
for (auto localVar : localVarNoParams)
{
const char* varName = localVar.c_str();
const string varNameWithPref = mergedChar(funcI->funcName.c_str(), varName);
SgSymbol* symbVar = new SgSymbol(VARIABLE_NAME, varNameWithPref.c_str());
SgExpression* exVar = new SgVarRefExp(symbVar);
variablesVec.push_back(exVar);
}
auto dataWrite = new SgInputOutputStmt(WRITE_STAT, unit, *makeExprList(variablesVec, false));
ifStoreOk->insertStmtAfter(*dataWrite, *ifStoreOk);
}
for (size_t i = 0; i < chainLabel.size(); i++)
{
if (!chainLocalVarNoParams[i].empty())
{
vector<SgExpression*> variablesVec;
for (auto localVar : chainLocalVarNoParams[i])
{
const char* varNameWithPref = localVar.c_str();
SgSymbol* symbVar = new SgSymbol(VARIABLE_NAME, varNameWithPref);
SgExpression* exVar = new SgVarRefExp(symbVar);
variablesVec.push_back(exVar);
2023-12-18 21:12:27 +03:00
}
auto dataWrite = new SgInputOutputStmt(WRITE_STAT, unit, *makeExprList(variablesVec, false));
ifStoreOk->insertStmtAfter(*dataWrite, *ifStoreOk);
}
SgSymbol* procLabelSymb = new SgSymbol(VARIABLE_NAME, chainLabel[i].c_str());
SgExpression* procLabelExpr = new SgVarRefExp(procLabelSymb);
auto labelRead = new SgInputOutputStmt(WRITE_STAT, unit, *procLabelExpr);
ifStoreOk->insertStmtAfter(*labelRead, *ifStoreOk);
}
if (commonVariables.size())
{
vector<SgExpression*> commanVariablesVec;
for (auto commanVar : commonVariables)
{
SgSymbol* symbCommon = new SgSymbol(VARIABLE_NAME, commanVar.c_str());
SgExpression* exCommon = new SgVarRefExp(symbCommon);
commanVariablesVec.push_back(exCommon);
}
auto commonDataWrite = new SgInputOutputStmt(WRITE_STAT, unit, *makeExprList(commanVariablesVec, false));
ifStoreOk->insertStmtAfter(*commonDataWrite, *ifStoreOk);
}
// insert copy_block
for (auto localVar : localVarNoParams)
{
SgSymbol* rightSymb = new SgSymbol(VARIABLE_NAME, localVar.c_str());
SgExpression* rightEx = new SgVarRefExp(rightSymb);
SgSymbol* leftSymb = renamedNewSymb(rightSymb, funcI->funcName.c_str());
SgExpression* leftEx = new SgVarRefExp(leftSymb);
ifStoreOk->insertStmtAfter(*new SgAssignStmt(*leftEx, *rightEx), *ifStoreOk);
}
listSpec.clear();
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("iostat"), *iostat));
listSpec.push_back(&SgAssignOp(*new SgKeywordValExp("file"), *journal));
listSpec.push_back(&unit);
SgIOControlStmt* openJ_new = new SgIOControlStmt(OPEN_STAT, *makeExprList(listSpec, false));
assign->insertStmtBefore(*new SgIOControlStmt(CLOSE_STAT, unit), *ifStoreOk);
assign->insertStmtBefore(*openJ_new, *ifStoreOk);
assign->insertStmtBefore(*new SgInputOutputStmt(WRITE_STAT, *makeExprList({ &frmt, &unit }, false), *fileIdx), *ifStoreOk);
assign->insertStmtBefore(*new SgIOControlStmt(CLOSE_STAT, unit), *ifStoreOk);
ifStoreOk->insertStmtAfter(profCallS->copy(), *ifStoreOk);
return storeBlock;
}
static void saveVarToModule(const set<string>& localVarNoParams, SgStatement* callPU, const char* funcName,
SgSymbol* procLabelSymb, const int labNum)
{
for (auto localVar : localVarNoParams)
{
SgSymbol* rightSymb = new SgSymbol(VARIABLE_NAME, localVar.c_str());
SgExpression* rightEx = new SgVarRefExp(rightSymb);
SgSymbol* leftSymb = renamedNewSymb(rightSymb, funcName);
SgExpression* leftEx = new SgVarRefExp(leftSymb);
callPU->insertStmtBefore(*new SgAssignStmt(*leftEx, *rightEx), *callPU->controlParent());
}
SgExpression* procLabelExpr = new SgVarRefExp(procLabelSymb);
SgExpression* labNumExpr = new SgValueExp(labNum);
callPU->insertStmtBefore(*new SgAssignStmt(*procLabelExpr, *labNumExpr), *callPU->controlParent());
}
static void processAllCalls(SgStatement* firstExec, const string funcToName, const string funcFromName,
SgStatement* gotoBlock, const set<string> localVarNoParams, SgSymbol* procLabelSymb)
{
SgStatement* execStmt = firstExec;
while (execStmt && isSgExecutableStatement(execStmt))
{
if (execStmt->variant() == PROC_STAT && execStmt->symbol()->identifier() == funcToName)
{
const int labNum = getNextFreeLabel();
auto nextPULabel = new SgLabel(labNum);
execStmt->setLabel(*nextPULabel);
SgStatement* gotoNextPU = new SgIfStmt(*new SgVarRefExp(procLabelSymb) == *new SgValueExp(labNum));
gotoNextPU->insertStmtAfter(*new SgGotoStmt(*nextPULabel), *gotoNextPU);
gotoBlock->insertStmtBefore(*gotoNextPU, *gotoBlock);
saveVarToModule(localVarNoParams, execStmt, funcFromName.c_str(), procLabelSymb, labNum);
2024-05-22 21:02:04 +03:00
checkForToReplace(gotoBlock, execStmt);
}
execStmt = execStmt->lexNext();
}
}
static void processInFuncParam(FuncInfo* funcI, set<string>& inFuncParam)
{
for (int i = 0; i < funcI->funcParams.countOfPars; ++i)
if (funcI->funcParams.isArgIn(i) && !funcI->funcParams.isArgOut(i))
inFuncParam.insert(funcI->funcParams.identificators[i]);
}
2024-05-16 14:15:02 +03:00
static SgStatement* getFirstExecStat(SgStatement* func)
{
SgStatement* firstExec = func->lexNext();
SgStatement* last = func->lastNodeOfStmt();
while (firstExec && firstExec != last && !isSgExecutableStatement(firstExec))
{
firstExec = firstExec->lastNodeOfStmt();
firstExec = firstExec->lexNext();
}
return firstExec;
}
static void processFunctionCallChain(SgStatement* func, const vector<FuncInfo*>& allFuncInfo, SgStatement* moduleF,
const vector<SgSymbol*>& loadS, SgExpression* iostat, SgArrayRefExp* journal,
SgExpression& frmt, SgExpression& unit,
SgSymbol* files, SgExpression* fileIdx, const int every,
const int numOfFiles, const string additional, const vector<SgSymbol*> profS,
SgExpression& frmtProf, SgExpression& unitNull, const int unitNum,
bool createdModuleForIO, const vector<string>& moduleNames,
vector<vector<string>>& chainLocalVarNoParams, vector<string>& chainLabel)
{
//find function structure
FuncInfo* funcI = findFileInfoByName(func, allFuncInfo);
set<pair<FuncInfo*, FuncInfo*>> toProcess;
fillToProcess(funcI, toProcess);
map<FuncInfo*, SgStatement*> processedFrom;
for (auto& pairs : toProcess)
{
FuncInfo* funcTo = pairs.first;
FuncInfo* funcFrom = pairs.second;
SgFile::switchToFile(funcFrom->fileName);
SgStatement* hedrFrom = funcFrom->funcPointer->GetOriginal();
2024-05-16 14:15:02 +03:00
SgStatement* firstExec = getFirstExecStat(hedrFrom);
if (!processedFrom.count(funcFrom))
{
if (funcFrom->isMain)
insertInitNamesOfFiles(numOfFiles, additional, files, journal, firstExec);
SgSymbol* timeF = new SgSymbol(FUNCTION_NAME, "omp_get_wtime", SgTypeDouble(), func); // OR dvtime
SgStatement* profCallS = new SgAssignStmt(*new SgVarRefExp(profS[0]), *new SgFunctionCallExp(*timeF));
SgStatement* profCallE = new SgAssignStmt(*new SgVarRefExp(profS[1]), *new SgFunctionCallExp(*timeF));
const string funcName = funcFrom->funcName;
SgStatement* proc_moduleF = NULL;
const string proc_cpModule = "spf_module_" + funcName;
createModule(proc_moduleF, proc_cpModule);
SgSymbol* proc_mainModuleCpS = proc_moduleF->symbol();
set<string> inFuncParam;
processInFuncParam(funcFrom, inFuncParam);
map<string, SgStatement*> moduleStmts;
map<string, SgStatement*> moduleParamStmts;
set<string> commonVariables;
set<string> externVars;
processVarBlock(hedrFrom, firstExec, moduleStmts, moduleParamStmts, commonVariables, externVars, funcFrom, inFuncParam);
set<string> addedModuleParams;
set<string> localVarNoParams;
insertStmtToModule(moduleStmts, moduleParamStmts, addedModuleParams, commonVariables, proc_moduleF, localVarNoParams,
externVars, funcName.size());
const string namelabelSymb = funcFrom->funcName + "_label";
SgSymbol* procLabelSymb = createLabel(namelabelSymb, proc_moduleF);
chainLabel.push_back(namelabelSymb);
hedrFrom->insertStmtAfter(*new SgStatement(USE_STMT, NULL, proc_mainModuleCpS), *hedrFrom);
SgFile::switchToFile(func->fileName());
SgStatement* useModuleSt = new SgStatement(USE_STMT);
useModuleSt->setSymbol(*proc_mainModuleCpS);
func->insertStmtAfter(*useModuleSt, *func);
SgSymbol* modS = moduleF->symbol();
SgFile::switchToFile(funcFrom->fileName);
SgStatement* useSt = new SgStatement(USE_STMT);
useSt->setSymbol(*modS);
hedrFrom->insertStmtAfter(*useSt, *hedrFrom);
SgStatement* loadBlock = createLoadBlock(loadS, funcFrom, iostat, journal, frmt, unit, files, fileIdx,
numOfFiles, profS, frmtProf, unitNull, profCallS, profCallE,
localVarNoParams, moduleStmts, commonVariables, createdModuleForIO,
moduleNames, unitNum, funcI->funcName, chainLocalVarNoParams, false, procLabelSymb);
firstExec->insertStmtBefore(*loadBlock, *firstExec->controlParent());
SgStatement* gotoBlock = new SgStatement(IF_NODE);
2024-05-22 21:02:04 +03:00
gotoBlock->addComment("! GOTO NEXT PROGRAM UNIT\n");
gotoBlock->setExpression(0, *new SgVarRefExp(loadS[0]) == *new SgValueExp(1));
loadBlock->insertStmtAfter(*gotoBlock, *loadBlock->controlParent());
// insert gotoBlock and save to module
processAllCalls(firstExec, funcTo->funcName, funcFrom->funcName, gotoBlock, localVarNoParams, procLabelSymb);
makeDeclaration(hedrFrom, { timeF });
2023-12-18 21:12:27 +03:00
}
}
SgFile::switchToFile(func->fileName());
2023-12-18 21:12:27 +03:00
}
2023-09-14 19:43:13 +03:00
2023-12-20 16:31:16 +03:00
static void processModules(SgFile* file, const vector<FuncInfo*>& allFuncInfo)
2023-12-18 21:12:27 +03:00
{
vector<SgStatement*> modules;
findModulesInFile(file, modules);
for (auto& mod : modules)
{
const string name = mod->symbol()->identifier();
auto pos = name.find("spf_");
if (pos != string::npos && pos == 0)
2023-12-18 21:12:27 +03:00
continue;
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
bool hasContains = false;
SgStatement* st = mod->lexNext();
while (st != mod->lastNodeOfStmt() && !hasContains)
{
hasContains = st->variant() == CONTAINS_STMT;
st = st->lexNext();
}
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
vector<SgExpression*> local;
map<string, SgStatement*> localParams;
set<string> addedToList;
2023-12-20 16:31:16 +03:00
findLocalData(mod, hasContains ? st : mod->lastNodeOfStmt(), local, localParams, addedToList, allFuncInfo);
2023-09-14 19:43:13 +03:00
SgProcHedrStmt* newF = new SgProcHedrStmt(("spf_cp_" + name).c_str());
2023-12-18 21:12:27 +03:00
if (!hasContains)
mod->lastNodeOfStmt()->insertStmtBefore(*new SgStatement(CONTAINS_STMT), *mod);
mod->lastNodeOfStmt()->insertStmtBefore(*newF, *mod);
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
newF->AddArg("unit_f", *SgTypeInt());
newF->AddArg("type_of_op", *SgTypeInt());
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
if (local.size())
{
SgExpression& unit = SgAssignOp(*new SgKeywordValExp("unit"), *new SgVarRefExp(*newF->parameter(0)));
auto dataRead = new SgInputOutputStmt(READ_STAT, unit, *makeExprList(local));
auto dataWrite = new SgInputOutputStmt(WRITE_STAT, unit, *makeExprList(local));
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
SgIfStmt* ifBlock = new SgIfStmt(*new SgVarRefExp(*newF->parameter(1)) == *new SgValueExp(0), *dataRead, *dataWrite);
newF->lastNodeOfStmt()->insertStmtBefore(*ifBlock, *newF);
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
ifBlock->addComment(("!STORE OR LOAD " + to_string(local.size()) + " ITEMS\n").c_str());
}
}
}
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
void createCheckpoints(SgFile* file, const map<string, CommonBlock*>& commonBlocks, const map<int, UserFiles>& filesInfo,
const vector<FuncInfo*>& allFuncInfo)
{
map<int, cpInfo> inFileCp;
bool inFile = findSpfCpDir(file, inFileCp);
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
if (!inFile)
{
2023-12-20 16:31:16 +03:00
processModules(file, allFuncInfo);
2023-12-18 21:12:27 +03:00
return;
}
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
set<string> commonVars;
for (auto& common : commonBlocks)
for (auto& elem : common.second->getVariables())
if (elem->getType() != CONST)
commonVars.insert(elem->getName());
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
const vector<string> moduleNames = findAllModules();
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
SgStatement* moduleF = NULL;
createModule(moduleF, "spf_module_checkpoint");
SgSymbol* mainModuleCpS = moduleF->symbol();
2023-12-18 21:12:27 +03:00
for (auto& checkps : inFileCp)
{
const int cpLine = checkps.first;
const int every = checkps.second.every;
const int numOfFiles = checkps.second.numOfFiles;
const int unitNum = checkps.second.unitNum;
const string additional = string("_") + to_string(current_file_id) + "_" + to_string(cpLine);
const typeEvery type = checkps.second.type;
const int numF = file->numberOfFunctions();
SgStatement* func = NULL;
SgStatement* point = NULL;
for (int z = 0; z < numF; ++z)
{
func = file->functions(z);
point = func->lexNext();
2024-03-20 10:08:06 +03:00
while (point && ((point->fileName() != file->filename()) || (point->lineNumber() < cpLine)) && point != func->lastNodeOfStmt() && point->variant() != CONTAINS_STMT)
2023-12-18 21:12:27 +03:00
point = point->lexNext();
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
//cp place was found
if (point != func->lastNodeOfStmt())
break;
point = NULL;
func = NULL;
}
checkNull(func, convertFileName(__FILE__).c_str(), __LINE__);
checkNull(point, convertFileName(__FILE__).c_str(), __LINE__);
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
bool createdModuleForIO = createForIOs(filesInfo, func);
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
SgStatement* lastDecl = func->lexNext();
while (lastDecl && !isSgExecutableStatement(lastDecl->lexNext()))
lastDecl = lastDecl->lexNext();
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
checkNull(lastDecl, convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* firstExec = lastDecl->lexNext();
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
vector<SgExpression*> local;
map<string, SgStatement*> localParams;
set<string> addedToList;
2023-12-20 16:31:16 +03:00
findLocalData(func, firstExec, local, localParams, addedToList, allFuncInfo);
2023-09-14 19:43:13 +03:00
const string funcName = func->symbol()->identifier();
SgStatement* proc_moduleF = NULL;
const string proc_cpModule = "spf_module_" + funcName;
createModule(proc_moduleF, proc_cpModule);
SgSymbol* proc_mainModuleCpS = proc_moduleF->symbol();
FuncInfo* funcI = findFileInfoByName(func, allFuncInfo);
set<string> intentInParams;
for (int i = 0; i < funcI->funcParams.countOfPars; ++i)
if (funcI->funcParams.isArgIn(i) && !funcI->funcParams.isArgOut(i))
intentInParams.insert(funcI->funcParams.identificators[i]);
set<string> inFuncParam;
processInFuncParam(funcI, inFuncParam);
map<string, SgStatement*> moduleStmts;
map<string, SgStatement*> moduleParamStmts;
set<string> commonVariables;
set<string> externVars;
processVarBlock(func, firstExec, moduleStmts, moduleParamStmts, commonVariables, externVars, funcI, inFuncParam);
set<string> addedModuleParams;
set<string> localVarNoParams;
insertStmtToModule(moduleStmts, moduleParamStmts, addedModuleParams, commonVariables, proc_moduleF, localVarNoParams,
externVars, funcName.size());
const vector<SgStatement*> useOfMods = findUseOfModules(func->lexNext(), firstExec);
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
string filesS = "spf_cp_files" + additional;
SgSymbol* files = new SgSymbol(VARIABLE_NAME, filesS.c_str(), createArrayCharType(32, numOfFiles + 1), func);
SgArrayRefExp* journal = new SgArrayRefExp(*files, *new SgValueExp(numOfFiles + 1));
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
//give max len, dont insert
int maxFileLen = insertInitNamesOfFiles(numOfFiles, additional, files, journal, NULL);
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
vector<SgSymbol*> profS;
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
string profSs = "spf_cp_prof_s" + additional;
string profEs = "spf_cp_prof_e" + additional;
profS.push_back(new SgSymbol(VARIABLE_NAME, profSs.c_str(), SgTypeFloat(), func));
profS.push_back(new SgSymbol(VARIABLE_NAME, profEs.c_str(), SgTypeFloat(), func));
2023-09-14 19:43:13 +03:00
SgSymbol* timeF = new SgSymbol(FUNCTION_NAME, "omp_get_wtime", SgTypeDouble(), func); // OR dvtime
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
SgStatement* profCallS = new SgAssignStmt(*new SgVarRefExp(profS[0]), *new SgFunctionCallExp(*timeF));
SgStatement* profCallE = new SgAssignStmt(*new SgVarRefExp(profS[1]), *new SgFunctionCallExp(*timeF));
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
vector<SgSymbol*> loadS;
vector<SgExpression*> initLoadS;
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
string cpLoadS = "spf_cp_load" + additional;
loadS.push_back(new SgSymbol(VARIABLE_NAME, cpLoadS.c_str(), SgTypeInt(), func));
initLoadS.push_back(new SgValueExp(1));
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
string fileNS = "spf_cp_file_n" + additional;
loadS.push_back(new SgSymbol(VARIABLE_NAME, fileNS.c_str(), SgTypeInt(), func));
initLoadS.push_back(new SgValueExp(1));
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
string iostatS = "spf_cp_iostat" + additional;
loadS.push_back(new SgSymbol(VARIABLE_NAME, iostatS.c_str(), SgTypeInt(), func));
initLoadS.push_back(NULL);
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
string loadLabelS = "spf_cp_load_label" + additional;
loadS.push_back(new SgSymbol(VARIABLE_NAME, loadLabelS.c_str(), SgTypeInt(), func));
initLoadS.push_back(new SgValueExp(0));
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
SgExpression& unitNull = SgAssignOp(*new SgKeywordValExp("unit"), *new SgKeywordValExp("*"));
SgExpression& unit = SgAssignOp(*new SgKeywordValExp("unit"), *new SgValueExp(unitNum));
SgExpression& frmt = SgAssignOp(*new SgKeywordValExp("fmt"), *new SgKeywordValExp("*"));
SgExpression& frmtProf = SgAssignOp(*new SgKeywordValExp("fmt"), *new SgValueExp(("(A,A" + to_string(maxFileLen) + ",F4.2,A)").c_str()));
2023-09-14 19:43:13 +03:00
SgExpression* labelIdx = new SgVarRefExp(loadS[3]);
2023-12-18 21:12:27 +03:00
SgExpression* iostat = new SgVarRefExp(loadS[2]);
SgExpression* fileIdx = new SgVarRefExp(loadS[1]);
2023-09-14 19:43:13 +03:00
vector<vector<string>> chainLocalVarNoParamsa;
SgStatement* loadBlock = createLoadBlock(loadS, funcI, iostat, journal, frmt, unit, files, fileIdx,
numOfFiles, profS, frmtProf, unitNull, profCallS, profCallE, localVarNoParams, moduleStmts,
commonVariables, createdModuleForIO, moduleNames, unitNum, funcName, chainLocalVarNoParamsa);
2024-05-16 14:15:02 +03:00
lastDecl->insertStmtAfter(*loadBlock, *func);
2023-09-14 19:43:13 +03:00
if (funcI->isMain)
insertInitNamesOfFiles(numOfFiles, additional, files, journal, lastDecl, false);
2023-12-18 21:12:27 +03:00
// make all new declarations
2023-12-18 21:12:27 +03:00
makeDeclaration(moduleF, loadS, &initLoadS);
makeDeclaration(moduleF, profS);
makeDeclaration(moduleF, { files });
makeDeclaration(func, { timeF });
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
func->insertStmtAfter(*new SgStatement(USE_STMT, NULL, mainModuleCpS), *func);
func->insertStmtAfter(*new SgStatement(USE_STMT, NULL, proc_mainModuleCpS), *func);
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
//check use
map<string, bool> modulesDone;
for (auto& elem : moduleNames)
modulesDone[elem] = false;
2023-09-14 19:43:13 +03:00
2023-12-18 21:12:27 +03:00
//check with ONLY
for (auto& use : useOfMods)
{
const string modName = use->symbol()->identifier();
if (!modulesDone[modName])
{
if (use->expr(0)) // has ONLY
{
SgExpression* ex = use->expr(0);
if (ex && ex->variant() == ONLY_NODE)
{
modulesDone[modName] = true;
2024-05-16 14:15:02 +03:00
auto callName = new SgSymbol(VARIABLE_NAME, ("spf_cp_" + modName).c_str());
2023-12-18 21:12:27 +03:00
ex->setLhs(new SgExpression(EXPR_LIST, new SgVarRefExp(callName), ex->lhs()));
2023-09-14 19:43:13 +03:00
}
}
}
}
2023-12-18 21:12:27 +03:00
//check other
for (auto& use : useOfMods)
2023-09-14 19:43:13 +03:00
{
2023-12-18 21:12:27 +03:00
const string modName = use->symbol()->identifier();
if (!modulesDone[modName])
modulesDone[modName] = true;
2023-09-14 19:43:13 +03:00
}
2023-12-18 21:12:27 +03:00
for (auto& elem : modulesDone)
2023-09-14 19:43:13 +03:00
{
2023-12-18 21:12:27 +03:00
if (!elem.second)
{
2024-05-16 14:15:02 +03:00
auto callName = new SgSymbol(VARIABLE_NAME, ("spf_cp_" + elem.first).c_str());
2023-12-18 21:12:27 +03:00
SgSymbol* modS = new SgSymbol(VARIABLE_NAME, elem.first.c_str());
vector<SgExpression*> onlyList;
onlyList.push_back(new SgVarRefExp(callName));
if (elem.first == "spf_module_ios")
for (int z = 0; z < 3; ++z)
onlyList.push_back(new SgVarRefExp(new SgSymbol(VARIABLE_NAME, iosNames[z].c_str())));
SgExpression* only = new SgExpression(ONLY_NODE, makeExprList(onlyList), NULL);
SgStatement* use = new SgStatement(USE_STMT, NULL, modS, only, NULL, NULL);
func->insertStmtAfter(*use, *func);
}
}
vector<vector<string>> chainLocalVarNoParams;
vector<string> chainLabel;
processFunctionCallChain(func, allFuncInfo, moduleF, loadS, iostat, journal, frmt, unit, files,
fileIdx, every, numOfFiles, additional, profS, frmtProf, unitNull,
unitNum, createdModuleForIO, moduleNames, chainLocalVarNoParams, chainLabel);
SgStatement* storeBlock = createSaveBlock(loadS, funcI, iostat, journal, frmt, unit, files, fileIdx,
numOfFiles, profS, frmtProf, unitNull, profCallS, profCallE,
localVarNoParams, moduleStmts, commonVariables, createdModuleForIO,
moduleNames, unitNum, chainLocalVarNoParams, chainLabel);
point->insertStmtBefore(*storeBlock, *point->controlParent());
vector<SgSymbol*> everyS;
vector<SgExpression*> initS;
if (type == typeEvery::TIME)
{
string everySs = "spf_cp_start" + additional;
string everyEs = "spf_cp_end" + additional;
everyS.push_back(new SgSymbol(VARIABLE_NAME, everySs.c_str(), SgTypeFloat(), func));
everyS.push_back(new SgSymbol(VARIABLE_NAME, everyEs.c_str(), SgTypeFloat(), func));
initS.push_back(NULL);
initS.push_back(NULL);
SgStatement* call = new SgAssignStmt(*new SgVarRefExp(everyS[0]), *new SgFunctionCallExp(*timeF));
lastDecl->insertStmtAfter(*call, *func);
lastDecl->insertStmtAfter(*new SgStatement(DVM_BARRIER_DIR), *func);
storeBlock->insertStmtAfter(call->copy(), *storeBlock);
storeBlock->insertStmtAfter(*new SgStatement(DVM_BARRIER_DIR), *storeBlock);
call = new SgAssignStmt(*new SgVarRefExp(everyS[1]), *new SgFunctionCallExp(*timeF));
storeBlock->insertStmtBefore(*new SgStatement(DVM_BARRIER_DIR), *storeBlock->controlParent());
storeBlock->insertStmtBefore(*call, *storeBlock->controlParent());
call->lexPrev()->addComment("! STORE CHECKPOINT\n");
storeBlock->setExpression(0, *new SgVarRefExp(everyS[1]) - *new SgVarRefExp(everyS[0]) >= *new SgValueExp(every));
}
else if (type == typeEvery::ITER)
{
string everyIs = "spf_cp_interval" + additional;
everyS.push_back(new SgSymbol(VARIABLE_NAME, everyIs.c_str(), SgTypeInt(), func));
initS.push_back(new SgValueExp(0));
SgAssignStmt* init = new SgAssignStmt(*new SgVarRefExp(everyS[0]), *new SgValueExp(0));
storeBlock->insertStmtAfter(*init, *storeBlock);
SgAssignStmt* inc = new SgAssignStmt(*new SgVarRefExp(everyS[0]), *new SgVarRefExp(everyS[0]) + *new SgValueExp(1));
storeBlock->insertStmtBefore(*inc, *storeBlock->controlParent());
inc->addComment("! STORE CHECKPOINT\n");
storeBlock->setExpression(0, *new SgVarRefExp(everyS[0]) >= *new SgValueExp(every));
}
2023-09-14 19:43:13 +03:00
makeDeclaration(moduleF, everyS, &initS);
const int labNum = getNextFreeLabel();
auto nextStLab = new SgLabel(labNum);
point->setLabel(*nextStLab);
SgStatement* gotoBlock = new SgIfStmt(*new SgVarRefExp(loadS[0]) == *new SgValueExp(1));
gotoBlock->addComment("! GOTO CP\n");
gotoBlock->insertStmtAfter(*new SgGotoStmt(*nextStLab), *gotoBlock);
SgAssignStmt* init = new SgAssignStmt(*new SgVarRefExp(loadS[0]), *new SgValueExp(0));
gotoBlock->insertStmtAfter(*init, *gotoBlock);
loadBlock->insertStmtAfter(*gotoBlock, *loadBlock->controlParent());
2024-05-22 21:02:04 +03:00
checkForToReplace(gotoBlock, point);
2023-12-18 21:12:27 +03:00
}
2023-09-14 19:43:13 +03:00
2023-12-20 16:31:16 +03:00
processModules(file, allFuncInfo);
2023-09-14 19:43:13 +03:00
}
static string cuttingType(const string& all_decl_with_init)
{
auto iter = all_decl_with_init.find("::");
if (iter == string::npos)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return all_decl_with_init.substr(0, iter);
}
static SgExpression* moveSaveAssignToMod(SgExpression* ex, SgStatement*& saveModule,
map<string, SgStatement*>& declLists, const string& procName, bool withInit)
{
if (saveModule == NULL)
createModule(saveModule, "spf_module_save_");
if (withInit)
{
if (ex->variant() != ASSGN_OP)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
else
{
if (ex->variant() != VAR_REF && ex->variant() != ARRAY_REF)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
SgSymbol* copy = (withInit) ? &ex->lhs()->symbol()->copy() : &ex->symbol()->copy();
copy->changeName((string(copy->identifier()) + "_" + procName).c_str());
SgStatement* decl = NULL;
if (withInit)
{
vector<SgExpression*> inits = { ex->rhs()->copyPtr() };
decl = makeDeclaration(NULL, { ex->lhs()->symbol() }, &inits);
}
else
decl = makeDeclaration(NULL, { ex->symbol() }, NULL);
const string typeKey = cuttingType(decl->unparse());
if (withInit)
{
decl->expr(0)->lhs()->setLhs(withInit ? ex->lhs()->copyPtr() : ex->copyPtr());
decl->expr(0)->lhs()->lhs()->setSymbol(copy);
}
else
decl->expr(0)->lhs()->setSymbol(copy);
auto it = declLists.find(typeKey);
if (it == declLists.end())
{
declLists.insert(it, make_pair(typeKey, decl));
saveModule->insertStmtAfter(*decl, *saveModule);
}
else
it->second->setExpression(0, new SgExpression(EXPR_LIST, decl->expr(0)->lhs(), it->second->expr(0)));
return new SgExpression(RENAME_NODE, new SgVarRefExp((withInit) ? ex->lhs()->symbol() : ex->symbol()), new SgVarRefExp(copy));
}
void convertSaveToModule(SgFile* file)
{
int numF = file->numberOfFunctions();
SgStatement* saveModule = NULL;
map<string, SgStatement*> declLists;
for (int ff = 0; ff < numF; ++ff)
{
vector<SgExpression*> renames;
SgStatement* func = file->functions(ff);
string procName = file->functions(ff)->symbol()->identifier();
set<SgStatement*> toRem;
vector<SgValueExp*> dataValues;
map<string, string> dataRenames;
set<string> symbolsDone;
vector<int> varsToProcess = { VAR_DECL_90 , DIM_STAT };
for (int z = 0; z < 2; ++z)
{
SgStatement* st = func->lexNext();
while (st && !isSgExecutableStatement(st))
{
if (st->variant() == SAVE_DECL)
{
printf("save in %d %s\n", st->lineNumber(), st->fileName());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
if (st->variant() == DATA_DECL && z == 0)
{
if (saveModule == NULL)
createModule(saveModule, "spf_module_save_");
SgStatement* copyData = st->copyPtr();
dataValues.push_back((SgValueExp*)copyData->expr(0));
saveModule->lastNodeOfStmt()->insertStmtBefore(*copyData, *saveModule);
toRem.insert(st);
}
if (st->variant() == varsToProcess[z])
{
SgExpression* list = st->expr(0);
vector<SgExpression*> newList;
bool changed = false;
while (list)
{
if (list->lhs()->variant() == ASSGN_OP)
{
changed = true;
if (symbolsDone.find(list->lhs()->lhs()->symbol()->identifier()) != symbolsDone.end())
{
list = list->rhs();
continue;
}
symbolsDone.insert(list->lhs()->lhs()->symbol()->identifier());
//printf("here %d %s - %s\n", st->lineNumber(), st->fileName(), list->lhs()->unparse());
renames.push_back(moveSaveAssignToMod(list->lhs(), saveModule, declLists, procName, true));
}
else
{
if (list->lhs()->symbol())
{
bool isInData = (list->lhs()->symbol()->attributes() & DATA_BIT) != 0;
if (isInData)
{
changed = true;
if (symbolsDone.find(list->lhs()->symbol()->identifier()) != symbolsDone.end())
{
list = list->rhs();
continue;
}
symbolsDone.insert(list->lhs()->symbol()->identifier());
renames.push_back(moveSaveAssignToMod(list->lhs(), saveModule, declLists, procName, false));
string left = renames.back()->lhs()->symbol()->identifier();
convertToUpper(left);
string right = renames.back()->rhs()->symbol()->identifier();
convertToUpper(right);
dataRenames[left] = right;
}
else
newList.push_back(list->lhs());
}
else
newList.push_back(list->lhs());
}
list = list->rhs();
}
if (newList.size() && changed)
{
reverse(newList.begin(), newList.end());
st->setExpression(0, makeExprList(newList));
}
else if (newList.size() == 0 && changed)
toRem.insert(st);
}
st = st->lexNext();
}
}
for (auto& elem : toRem)
elem->deleteStmt();
if (renames.size())
{
SgSymbol* modS = new SgSymbol(VARIABLE_NAME, saveModule->symbol()->identifier());
SgStatement* use = new SgStatement(USE_STMT, NULL, modS, makeExprList(renames), NULL, NULL);
func->insertStmtAfter(*use, *func);
for (auto& dataV : dataValues)
{
char* value = dataV->thellnd->entry.string_val;
string dataS(value);
convertToUpper(dataS);
dataS = preprocDataString(dataS);
for (auto& elem : dataRenames)
{
auto it = dataS.find(elem.first);
if (it != string::npos &&
(dataS[it + elem.first.size()] == ' ' || dataS[it + elem.first.size()] == '/') &&
(dataS[it - 1] == ',' || dataS[it - 1] == ' ' || dataS[it - 1] == '/'))
{
dataS = dataS.substr(0, it) + elem.second + dataS.substr(it + elem.first.size());
}
}
value = (char*)malloc(dataS.size() + 1);
value[dataS.size()] = '\0';
memcpy(value, dataS.c_str(), sizeof(char) * dataS.size());
dataV->thellnd->entry.string_val = value;
}
}
}
if (saveModule)
saveModule->insertStmtAfter(*new SgImplicitStmt(NULL), *saveModule);
}
static int getUnit(SgExpression* spec)
{
int unit = -1;
while (spec)
{
if (spec->lhs() && spec->lhs()->variant() == SPEC_PAIR)
{
if (spec->lhs()->lhs()->variant() == KEYWORD_VAL)
{
SgKeywordValExp* val = (SgKeywordValExp*)(spec->lhs()->lhs());
if (spec->lhs()->rhs()->variant() == INT_VAL)
{
if (val->value() == string("unit"))
return spec->lhs()->rhs()->valueInteger();
}
else if (spec->lhs()->rhs()->variant() == KEYWORD_VAL)
{
SgKeywordValExp* valR = (SgKeywordValExp*)(spec->lhs()->rhs());
if (val->value() == string("unit") && valR->value() == string("*"))
return -2;
}
}
}
else if (spec->variant() == INT_VAL)
return spec->valueInteger();
spec = spec->rhs();
}
return unit;
}
void preprocessOpenOperators(SgFile* file, map<int, UserFiles>& filesInfo)
{
int numF = file->numberOfFunctions();
set<SgStatement*> unrec;
for (int ff = 0; ff < numF; ++ff)
{
SgStatement* func = file->functions(ff);
for (SgStatement* st = func->lexNext(); st != func->lastNodeOfStmt(); st = st->lexNext())
{
if (st->variant() == OPEN_STAT)
{
int unit = getUnit(((SgIOControlStmt*)st)->controlSpecList());
if (unit >= 0)
filesInfo[unit].placesOpen.push_back(st);
else if (unit != -2)
unrec.insert(st);
}
else if (st->variant() == CLOSE_STAT)
{
int unit = getUnit(((SgIOControlStmt*)st)->controlSpecList());
if (unit >= 0)
filesInfo[unit].placesClose.push_back(st);
else if (unit != -2)
unrec.insert(st);
}
else if (st->variant() == WRITE_STAT)
{
int unit = getUnit(((SgInputOutputStmt*)st)->specList());
if (unit >= 0)
filesInfo[unit].placesWrite.push_back(st);
else if (unit != -2)
unrec.insert(st);
}
else if (st->variant() == READ_STAT)
{
int unit = getUnit(((SgInputOutputStmt*)st)->specList());
if (unit >= 0)
filesInfo[unit].placesRead.push_back(st);
else if (unit != -2)
unrec.insert(st);
}
else if (st->variant() == CONTAINS_STMT)
break;
}
}
for (auto& elem : unrec)
elem->unparsestdout();
/*for (auto& elem : filesInfo)
{
if (elem.second.placesClose.size() != elem.second.placesOpen.size())
if (elem.second.placesClose.size() > 0 && elem.second.placesOpen.size() > 0)
printf("UNIT = %d has not equal open and close\n", elem.first);
if (elem.second.placesClose.size() == 0 && elem.second.placesWrite.size() > 0 && elem.second.placesRead.size() == 0)
printf("UNIT = %d need to save\n", elem.first);
}*/
}