2025-06-02 19:08:09 +03:00
|
|
|
#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"
|
2025-06-02 19:08:09 +03:00
|
|
|
#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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
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;
|
2024-05-16 09:23:02 +03:00
|
|
|
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
|
2024-05-16 09:23:02 +03:00
|
|
|
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
|
2024-05-16 09:23:02 +03:00
|
|
|
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
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
static string mergedChar(const string& l, const string& r)
|
2023-12-18 21:12:27 +03:00
|
|
|
{
|
2024-05-16 09:23:02 +03:00
|
|
|
return l + "_" + r;
|
|
|
|
|
}
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
{
|
2024-05-16 09:23:02 +03:00
|
|
|
SgSymbol* symbSize = renamedNewSymb(sizeEx->symbol(), funcName);
|
|
|
|
|
sizeEx->setSymbol(symbSize);
|
|
|
|
|
}
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
if (sizeEx->lhs())
|
|
|
|
|
renameEx(sizeEx->lhs(), funcName);
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
if (sizeEx->rhs())
|
|
|
|
|
renameEx(sizeEx->rhs(), funcName);
|
|
|
|
|
}
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
{
|
2024-05-16 09:23:02 +03:00
|
|
|
auto decl = (SgParameterStmt*)moduleParamStmts.at(sizeEx->symbol()->identifier());
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
SgStatement* copyParamStmt = moduleParamStmts.at(sizeEx->symbol()->identifier())->copyPtr();
|
|
|
|
|
borderStmt->insertStmtBefore(*copyParamStmt, *proc_moduleF);
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
if (moduleStmts.count(sizeEx->symbol()->identifier()))
|
2023-09-14 19:43:13 +03:00
|
|
|
{
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
while (ex && ex->lhs())
|
|
|
|
|
{
|
|
|
|
|
lhs = ex->lhs();
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
if (inFuncParam.count(lhs->symbol()->identifier()))
|
|
|
|
|
{
|
|
|
|
|
ex = ex->rhs();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
if (lhs->variant() == ARRAY_REF)
|
|
|
|
|
{
|
|
|
|
|
SgExpression* newArraySizeExpr = lhs->lhs()->copyPtr();
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
SgExpression* sizeEx = newArraySizeExpr;
|
|
|
|
|
SgExpression* sizeLhs;
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
while (sizeEx && sizeEx->lhs())
|
2023-09-14 19:43:13 +03:00
|
|
|
{
|
2024-05-16 09:23:02 +03:00
|
|
|
sizeLhs = sizeEx->lhs();
|
|
|
|
|
renameEx(sizeLhs, funcName);
|
|
|
|
|
|
|
|
|
|
sizeEx = sizeEx->rhs();
|
2023-09-14 19:43:13 +03:00
|
|
|
}
|
2024-05-16 09:23:02 +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
|
|
|
}
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +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-16 09:23:02 +03:00
|
|
|
{
|
2024-05-25 17:41:28 +03:00
|
|
|
const auto& varName = stat.first;
|
|
|
|
|
SgStatement* varStmt = stat.second;
|
|
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
string varNameNoPref = varName;
|
2024-05-16 14:15:02 +03:00
|
|
|
varNameNoPref.erase(0, prefixLen + 1);
|
2024-05-16 09:23:02 +03:00
|
|
|
|
|
|
|
|
if (commonVariables.count(varNameNoPref) == 0 && moduleParamStmts.count(varName) == 0
|
|
|
|
|
&& externVars.count(varNameNoPref) == 0)
|
2023-12-18 21:12:27 +03:00
|
|
|
{
|
2024-05-16 09:23:02 +03:00
|
|
|
localVarNoParams.insert(varNameNoPref);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
endProcModuleF->insertStmtBefore(*varStmt, *proc_moduleF);
|
|
|
|
|
if (varStmt->expr(0)->variant() == ARRAY_REF)
|
2023-12-18 21:12:27 +03:00
|
|
|
{
|
2024-05-16 09:23:02 +03:00
|
|
|
SgExpression* arraySizeExpr = varStmt->expr(0)->lhs();
|
2023-09-14 19:43:13 +03:00
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
SgExpression* sizeEx = arraySizeExpr;
|
|
|
|
|
SgExpression* sizeLhs;
|
2023-09-14 19:43:13 +03:00
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
sizeEx = sizeEx->rhs();
|
2023-12-18 21:12:27 +03:00
|
|
|
}
|
|
|
|
|
}
|
2024-05-16 09:23:02 +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()));
|
2024-05-16 09:23:02 +03:00
|
|
|
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
|
|
|
{
|
2024-05-16 09:23:02 +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
|
|
|
}
|
2024-05-16 09:23:02 +03:00
|
|
|
auto commonDataRead = new SgInputOutputStmt(READ_STAT, unit, *makeExprList(commanVariablesVec, false));
|
|
|
|
|
ifLoadOk1->insertStmtAfter(*commonDataRead, *ifLoadOk1);
|
|
|
|
|
}
|
2023-09-14 19:43:13 +03:00
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
return procLabelSymb;
|
|
|
|
|
}
|
2023-09-14 19:43:13 +03:00
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
SgIOControlStmt* open = new SgIOControlStmt(OPEN_STAT, *makeExprList(listSpec, false));
|
|
|
|
|
storeBlock->insertStmtAfter(*open, *storeBlock);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
SgStatement* assign = ifStoreOk->lexNext();
|
2023-09-14 19:43:13 +03:00
|
|
|
|
2024-05-16 09:23:02 +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()));
|
2024-05-16 09:23:02 +03:00
|
|
|
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
|
|
|
}
|
2024-05-16 09:23:02 +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);
|
2024-05-16 09:23:02 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
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);
|
2024-05-16 09:23:02 +03:00
|
|
|
|
|
|
|
|
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");
|
2024-05-16 09:23:02 +03:00
|
|
|
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
|
|
|
}
|
|
|
|
|
}
|
2024-05-16 09:23:02 +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)
|
|
|
|
|
{
|
2024-05-16 09:23:02 +03:00
|
|
|
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
|
|
|
|
2024-05-16 09:23:02 +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;
|
2024-05-16 09:23:02 +03:00
|
|
|
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
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +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));
|
2024-05-16 09:23:02 +03:00
|
|
|
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));
|
2024-05-16 09:23:02 +03:00
|
|
|
|
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
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +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
|
|
|
|
2024-05-16 09:23:02 +03:00
|
|
|
if (funcI->isMain)
|
|
|
|
|
insertInitNamesOfFiles(numOfFiles, additional, files, journal, lastDecl, false);
|
2023-12-18 21:12:27 +03:00
|
|
|
|
2024-05-16 09:23:02 +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);
|
2024-05-16 09:23:02 +03:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-16 09:23:02 +03:00
|
|
|
|
|
|
|
|
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
|
|
|
|
2024-05-16 09:23:02 +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);
|
|
|
|
|
}*/
|
|
|
|
|
}
|