From 69cba903eea642442cf6fcd08318a5d6a932d19e Mon Sep 17 00:00:00 2001 From: ALEXks Date: Thu, 16 May 2024 09:23:02 +0300 Subject: [PATCH] added new implementation of checkpoints by Anton Milienkov --- .../_src/Transformations/checkpoints.cpp | 1193 +++++++++++------ .../experts/Sapfor_2017/_src/Utils/version.h | 2 +- 2 files changed, 790 insertions(+), 405 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/Transformations/checkpoints.cpp b/sapfor/experts/Sapfor_2017/_src/Transformations/checkpoints.cpp index 0ccf36e..a9a155d 100644 --- a/sapfor/experts/Sapfor_2017/_src/Transformations/checkpoints.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Transformations/checkpoints.cpp @@ -16,6 +16,22 @@ enum class typeEvery { TIME, ITER }; static const vector iosNames = { "spf_close_all", "spf_open_all", "spf_inc_num_part" }; +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); + } +} + static SgType* createArrayCharType(int len, int dim) { if (dim == 0) @@ -76,7 +92,7 @@ static void findDecls(SgExpression* ex, vector& local, const map< static FuncInfo* findFileInfoByName(SgStatement* func, const vector& allFuncInfo) { FuncInfo* funcI = NULL; - for (auto& funcs : allFuncInfo) + for (const auto& funcs : allFuncInfo) if (funcs->funcName == func->symbol()->identifier()) funcI = funcs; checkNull(funcI, convertFileName(__FILE__).c_str(), __LINE__); @@ -246,7 +262,6 @@ static void insertToOpenClose(const map& needToSave, const vecto printInternalError(convertFileName(__FILE__).c_str(), __LINE__); } -static void createModule(SgStatement*& module, const string& name, bool withFile = true); static bool createForIOs(const map& filesInfo, SgStatement* func) { SgStatement* moduleF = NULL; @@ -462,7 +477,7 @@ static int insertInitNamesOfFiles(const int numOfFiles, const string& additional 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); + insert->insertStmtAfter(*new SgAssignStmt(*new SgArrayRefExp(*files, *new SgValueExp(z)), *new SgValueExp(tmp.c_str())), *insert->controlParent()); } } @@ -472,7 +487,7 @@ static int insertInitNamesOfFiles(const int numOfFiles, const string& additional 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); + insert->insertStmtAfter(*new SgAssignStmt(*journal, *new SgValueExp(tmp.c_str())), *insert->controlParent()); } return maxFileLen; @@ -544,11 +559,589 @@ static SgStatement* createOpen(SgExpression* iostat, SgSymbol* files, SgExpressi return open; } +static string mergedChar(const string& l, const string& r) +{ + return l + "_" + r; +} + +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()); + + return newSymb; +} + +static void renameEx(SgExpression* sizeEx, const char* funcName) +{ + if (sizeEx->variant() == CONST_REF) + { + SgSymbol* symbSize = renamedNewSymb(sizeEx->symbol(), funcName); + sizeEx->setSymbol(symbSize); + } + + if (sizeEx->lhs()) + renameEx(sizeEx->lhs(), funcName); + + if (sizeEx->rhs()) + renameEx(sizeEx->rhs(), funcName); +} + +static void findSizeEx(SgExpression* sizeEx, const map& moduleStmts, + const map& moduleParamStmts, SgStatement* proc_moduleF, + set& addedModuleParams, SgStatement* borderStmt) +{ + if (sizeEx->variant() == CONST_REF) + { + if (moduleParamStmts.count(sizeEx->symbol()->identifier()) == 1 && addedModuleParams.count(sizeEx->symbol()->identifier()) == 0) + { + auto decl = (SgParameterStmt*)moduleParamStmts.at(sizeEx->symbol()->identifier()); + + SgStatement* copyParamStmt = moduleParamStmts.at(sizeEx->symbol()->identifier())->copyPtr(); + borderStmt->insertStmtBefore(*copyParamStmt, *proc_moduleF); + + if (moduleStmts.count(sizeEx->symbol()->identifier())) + { + 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& 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(); + } + } +} + +static void processVarStmt(SgStatement* st, map& moduleStmts, const char* funcName, + const set& inFuncParam) +{ + SgExpression* lhs2; + SgExpression* ex2 = st->expr(2); + + SgExpression* ex = st->expr(0); + SgExpression* lhs; + + SgStatement* baseStmt = st->copyPtr(); + baseStmt->expr(0)->setLhs(NULL); + baseStmt->expr(0)->setRhs(NULL); + baseStmt->setExpression(2, NULL); + + while (ex && ex->lhs()) + { + lhs = ex->lhs(); + + if (inFuncParam.count(lhs->symbol()->identifier())) + { + ex = ex->rhs(); + continue; + } + + 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); + + if (lhs->variant() == ARRAY_REF) + { + SgExpression* newArraySizeExpr = lhs->lhs()->copyPtr(); + + SgExpression* sizeEx = newArraySizeExpr; + SgExpression* sizeLhs; + + while (sizeEx && sizeEx->lhs()) + { + sizeLhs = sizeEx->lhs(); + renameEx(sizeLhs, funcName); + + sizeEx = sizeEx->rhs(); + } + + 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& 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& 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(); + } + } +} + +static void processVarBlock(SgStatement* func, SgStatement* firstExec, map& moduleStmts, + map& moduleParamStmts, set& commonVariables, + set& externVars, FuncInfo* funcFrom, const set& inFuncParam = { }) +{ + const char* funcName = func->symbol()->identifier(); + + 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& moduleStmts, const map& moduleParamStmts, + set& addedModuleParams, const set& commonVariables, SgStatement* proc_moduleF, + set& localVarNoParams, const set& externVars, const size_t prefixLen) +{ + SgStatement* endProcModuleF = proc_moduleF->lastNodeOfStmt(); + + SgStatement* borderStmt = new SgStatement(VAR_DECL); + proc_moduleF->insertStmtAfter(*borderStmt, *proc_moduleF); + + for (const auto& [varName, varStmt] : moduleStmts) + { + string varNameNoPref = varName; + + string::size_type pos{}; + varNameNoPref.erase(0, pos + prefixLen + 1); + + if (commonVariables.count(varNameNoPref) == 0 && moduleParamStmts.count(varName) == 0 + && externVars.count(varNameNoPref) == 0) + { + localVarNoParams.insert(varNameNoPref); + + endProcModuleF->insertStmtBefore(*varStmt, *proc_moduleF); + if (varStmt->expr(0)->variant() == ARRAY_REF) + { + SgExpression* arraySizeExpr = varStmt->expr(0)->lhs(); + + SgExpression* sizeEx = arraySizeExpr; + SgExpression* sizeLhs; + + while (sizeEx && sizeEx->lhs()) + { + sizeLhs = sizeEx->lhs(); + findSizeEx(sizeLhs, moduleStmts, moduleParamStmts, proc_moduleF, addedModuleParams, borderStmt); + + sizeEx = sizeEx->rhs(); + } + } + } + } + + borderStmt->deleteStmt(); +} + +static SgStatement* createLoadBlock(const vector& loadS, FuncInfo*& funcI, SgExpression* iostat, SgArrayRefExp* journal, + SgExpression& frmt, SgExpression& unit, SgSymbol* files, SgExpression* fileIdx, const int numOfFiles, + const vector& profS, SgExpression& frmtProf, SgExpression& unitNull, + SgStatement* profCallS, SgStatement* profCallE, const set& localVarNoParams, + const map& moduleStmts, const set& commonVariables, bool createdModuleForIO, + const vector& moduleNames, const int unitNum, + const string& baseFunc, vector>& chainLocalVarNoParams, + bool isBaseFunc = true, SgSymbol* procLabelSymb = NULL) +{ + const char* funcName = funcI->funcName.c_str(); + vector 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 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 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 varNames; + if (moduleStmts.size()) + { + vector 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) + { + 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 commanVariablesVec; + for (auto commanVar : commonVariables) + { + SgSymbol* symbCommon = new SgSymbol(VARIABLE_NAME, commanVar.c_str()); + SgExpression* exCommon = new SgVarRefExp(symbCommon); + commanVariablesVec.push_back(exCommon); + } + auto commonDataRead = new SgInputOutputStmt(READ_STAT, unit, *makeExprList(commanVariablesVec, false)); + ifLoadOk1->insertStmtAfter(*commonDataRead, *ifLoadOk1); + } + + 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 vecLabelSymb = { procLabelSymb }; + vector vecLabel0 = { procLabel0 }; + makeDeclaration(proc_moduleF, vecLabelSymb, &vecLabel0); + + return procLabelSymb; +} + +static SgStatement* createSaveBlock(const vector& loadS, FuncInfo*& funcI, SgExpression* iostat, SgArrayRefExp* journal, + SgExpression& frmt, SgExpression& unit, SgSymbol* files, SgExpression* fileIdx, const int numOfFiles, + const vector& profS, SgExpression& frmtProf, SgExpression& unitNull, + SgStatement* profCallS, SgStatement* profCallE, const set& localVarNoParams, + const map& moduleStmts, const set& commonVariables, bool createdModuleForIO, + const vector& moduleNames, const int unitNum, const vector>& chainLocalVarNoParams, + const vector& chainLabel) +{ + SgStatement* storeBlock = new SgIfStmt(IF_NODE); + + vector 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); + + SgIOControlStmt* open = new SgIOControlStmt(OPEN_STAT, *makeExprList(listSpec, false)); + storeBlock->insertStmtAfter(*open, *storeBlock); + + 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 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 ")); + + ifStoreOk->insertStmtAfter(*new SgInputOutputStmt(WRITE_STAT, *makeExprList({ &frmtProf, &unitNull }, false), *makeExprList(commentArgs, false)), *ifStoreOk); + ifStoreOk->insertStmtAfter(profCallE->copy(), *ifStoreOk); + + SgStatement* assign = ifStoreOk->lexNext(); + + //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) + { + 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 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 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); + } + 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 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& 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 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); + } + + execStmt = execStmt->lexNext(); + } +} + +static void processInFuncParam(FuncInfo* funcI, set& 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]); +} + static void processFunctionCallChain(SgStatement* func, const vector& allFuncInfo, SgStatement* moduleF, const vector& loadS, SgExpression* iostat, SgArrayRefExp* journal, SgExpression& frmt, SgExpression& unit, - SgSymbol* files, SgExpression* fileIdx, - const int every, const vector& everyS) + SgSymbol* files, SgExpression* fileIdx, const int every, + const int numOfFiles, const string additional, const vector profS, + SgExpression& frmtProf, SgExpression& unitNull, const int unitNum, + bool createdModuleForIO, const vector& moduleNames, + vector>& chainLocalVarNoParams, vector& chainLabel) { //find function structure FuncInfo* funcI = findFileInfoByName(func, allFuncInfo); @@ -562,180 +1155,101 @@ static void processFunctionCallChain(SgStatement* func, const vector& FuncInfo* funcTo = pairs.first; FuncInfo* funcFrom = pairs.second; + SgFile::switchToFile(funcFrom->fileName); + int callNum = 1; SgStatement* hedrTo = funcTo->funcPointer->GetOriginal(); SgStatement* hedrFrom = funcFrom->funcPointer->GetOriginal(); SgStatement* lastDecl = hedrFrom->lexNext(); - while (lastDecl && !isSgExecutableStatement(lastDecl->lexNext())) - lastDecl = lastDecl->lexNext(); + SgStatement* firstExec; + if (isSgExecutableStatement(lastDecl)) + { + firstExec = lastDecl; + lastDecl = NULL; + } + else + { + while (lastDecl && !isSgExecutableStatement(lastDecl->lexNext())) + lastDecl = lastDecl->lexNext(); + + firstExec = lastDecl->lexNext(); + } - SgStatement* firstExec = lastDecl->lexNext(); vector local; map localParams; set addedToList; - findLocalData(hedrFrom, firstExec, local, localParams, addedToList, allFuncInfo); 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 inFuncParam; + processInFuncParam(funcFrom, inFuncParam); + + map moduleStmts; + map moduleParamStmts; + set commonVariables; + set externVars; + processVarBlock(hedrFrom, firstExec, moduleStmts, moduleParamStmts, commonVariables, externVars, funcFrom, inFuncParam); + + set addedModuleParams; + set 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); - vector insertToGotoBlock; + gotoBlock->addComment("! goto next program unit\n"); + gotoBlock->setExpression(0, *new SgVarRefExp(loadS[0]) == *new SgValueExp(1)); + loadBlock->insertStmtAfter(*gotoBlock, *loadBlock->controlParent()); - gotoBlock->addComment("!GOTO LOAD BLOCK \n"); - gotoBlock->setExpression(0, *new SgVarRefExp(loadS[0]) == *new SgValueExp(0)); + // insert gotoBlock and save to module + processAllCalls(firstExec, funcTo->funcName, funcFrom->funcName, gotoBlock, localVarNoParams, procLabelSymb); - if (funcFrom->isMain) - { - SgAssignStmt* loadOne = new SgAssignStmt(*new SgVarRefExp(loadS[0]), *new SgValueExp(1)); - insertToGotoBlock.push_back(loadOne); - insertToGotoBlock.push_back(createOpenJ_old(iostat, journal, unit)); - - vector insertToifLoadOk; - SgIfStmt* ifLoadOk = new SgIfStmt(*iostat == *new SgValueExp(0)); - insertToGotoBlock.push_back(ifLoadOk); - - SgInputOutputStmt* read = new SgInputOutputStmt(READ_STAT, *makeExprList({ &frmt, &unit }, false), *fileIdx); - insertToifLoadOk.push_back(read); - insertToifLoadOk.push_back(new SgIOControlStmt(CLOSE_STAT, unit)); - insertToifLoadOk.push_back(createOpen(iostat, files, fileIdx, unit)); - - read = new SgInputOutputStmt(READ_STAT, *makeExprList({ &frmt, &unit }, false), *new SgVarRefExp(loadS[3])); - SgIfStmt* ifLoadOk1 = new SgIfStmt(*iostat == *new SgValueExp(0), *read); - SgAssignStmt* loadZero = new SgAssignStmt(*new SgVarRefExp(loadS[0]), *new SgValueExp(0)); - ifLoadOk1->insertStmtAfter(*loadZero, *ifLoadOk1); - - insertToifLoadOk.push_back(ifLoadOk1); - - firstExec->insertStmtBefore(*gotoBlock, *hedrFrom); - - for (int z = insertToGotoBlock.size() - 1; z >= 0; --z) - gotoBlock->insertStmtAfter(*insertToGotoBlock[z], *gotoBlock); - - for (int z = insertToifLoadOk.size() - 1; z >= 0; --z) - ifLoadOk->insertStmtAfter(*insertToifLoadOk[z], *ifLoadOk); - - processedFrom[funcFrom] = ifLoadOk1->lexNext(); - } - else - { - SgStatement* read = new SgInputOutputStmt(READ_STAT, *makeExprList({ &frmt, &unit }, false), *new SgVarRefExp(loadS[3])); - gotoBlock->insertStmtAfter(*read, *gotoBlock); - processedFrom[funcFrom] = gotoBlock->lexNext(); - firstExec->insertStmtBefore(*gotoBlock, *hedrFrom); - } - } - - for (auto& callInfo : funcFrom->callsFromDetailed) - { - auto& call = callInfo.pointerDetailCallsFrom; - SgStatement* st = NULL; - - if (isSgFuncHedrStmt(hedrTo) && call.second == FUNC_CALL) - { - SgFunctionCallExp* callExp = (SgFunctionCallExp*)call.first; - if (!strcmp(callExp->funName()->identifier(), funcTo->funcName.c_str())) - { - st = SgStatement::getStatmentByExpression(callExp); - SgSymbol* buf = new SgSymbol(VARIABLE_NAME, ("SPF_CALL_" + funcTo->funcName + "_" + to_string(callNum)).c_str(), callExp->type(), funcFrom->funcPointer->GetOriginal()); - SgExpression* bufRef = new SgVarRefExp(buf); - SgStatement* bufAssign = new SgAssignStmt(*bufRef, *callExp); - st->insertStmtBefore(*bufAssign, *(st->controlParent())); - replaceExprByExprInSt(st, callExp, bufRef); - makeDeclaration(hedrFrom, { buf }); - - for (int i = 0; i < callExp->numberOfArgs(); i++) - { - if (funcTo->funcParams.isArgInOut(i) || funcTo->funcParams.isArgOut(i)) - { - SgSymbol* s, * sl; - SgStatement* lst = hedrTo->lastNodeOfStmt(); - sl = lst->lexNext() ? lst->lexNext()->symbol() : NULL; - for (s = hedrTo->symbol(); s != sl && s; s = s->next()) - { - if (s->scope() == hedrTo && !strcmp(s->identifier(), funcTo->funcParams.identificators[i].c_str())) - { - break; - } - } - - SgSymbol* argBuf = new SgSymbol(VARIABLE_NAME, ("SPF_ARG_" + funcTo->funcName + "_" + to_string(callNum) + "_" + to_string(i)).c_str(), s->type(), funcFrom->funcPointer->GetOriginal()); - SgExpression* argBufRef = new SgVarRefExp(argBuf); - SgStatement* argBufAssign = new SgAssignStmt(*argBufRef, *(callExp->arg(i))); - bufAssign->insertStmtBefore(*argBufAssign, *(st->controlParent())); - SgStatement* decl = makeDeclaration(hedrFrom, { argBuf }); - - for (int i = 0; i < 3; i++) - { - SgExpression* e; - if (e = decl->expr(i)) - decl->setExpression(i, CalculateInteger(ReplaceConstant(e))); - } - - } - } - st = bufAssign; - callNum++; - } - } - else if (isSgProcHedrStmt(hedrTo) && call.second == PROC_STAT) - { - //TODO: need to revise!! - /*SgCallStmt* callSt = (SgCallStmt*)call.first; - if (!strcmp(callSt->name()->identifier(), funcTo->funcName.c_str())) { - st = callSt; - for (int i = 0; i < callSt->numberOfArgs(); i++) - { - if (funcTo->funcParams.isArgInOut(i) || funcTo->funcParams.isArgOut(i)) - { - SgSymbol* buf1 = new SgSymbol(VARIABLE_NAME, "TEMP1", callSt->arg(i)->type(), hedrFrom); - SgExpression* buf1Ref = new SgVarRefExp(buf1); - SgStatement* buf1Assign = new SgAssignStmt(*buf1Ref, *(callSt->arg(i))); - st->insertStmtBefore(*buf1Assign, *(st->controlParent())); - } - } - }*/ - } - - if (st) - { - SgStatement* loadBlock = new SgStatement(IF_NODE); - SgStatement* loadBlockLast = NULL; - SgStatement* storeBlock = new SgStatement(IF_NODE); - - st->insertStmtBefore(*loadBlock, *st->controlParent()); - st->insertStmtAfter(*storeBlock, *st->controlParent()); - - loadBlock->addComment("! LOAD CHECKPOINT\n"); - const int labNum = getNextFreeLabel(); - auto loadblockLab = new SgLabel(labNum); - loadBlock->setLabel(*loadblockLab); - - SgIfStmt* gotoIf = new SgIfStmt(*new SgVarRefExp(loadS[3]) == *new SgValueExp(labNum), *new SgGotoStmt(*loadblockLab)); - processedFrom[funcFrom]->insertStmtAfter(*gotoIf, *(processedFrom[funcFrom]->controlParent())); - - storeBlock->addComment("! STORE CHECKPOINT\n"); - - //TODO: this block incorrect!! - storeBlock->setExpression(0, *new SgVarRefExp(everyS[0]) >= *new SgValueExp(every)); - - vector insertToLoadS; - - loadBlock->setExpression(0, *new SgVarRefExp(loadS[0]) == *new SgValueExp(0)); - loadBlock->addComment("! LOAD DATA FROM CHECKPOINT\n"); - - //READ DATA - if (local.size()) - { - auto dataRead = new SgInputOutputStmt(READ_STAT, unit, *makeExprList(local)); - loadBlock->insertStmtAfter(*dataRead, *loadBlock); - } - } + makeDeclaration(hedrFrom, { timeF }); } + } + + SgFile::switchToFile(func->fileName()); } static void processModules(SgFile* file, const vector& allFuncInfo) @@ -744,7 +1258,9 @@ static void processModules(SgFile* file, const vector& allFuncInfo) findModulesInFile(file, modules); for (auto& mod : modules) { - if (!strcmp(mod->symbol()->identifier(), "spf_module_checkpoint")) + const string name = mod->symbol()->identifier(); + auto pos = name.find("spf_"); + if (pos != string::npos && pos == 0) continue; bool hasContains = false; @@ -760,7 +1276,7 @@ static void processModules(SgFile* file, const vector& allFuncInfo) set addedToList; findLocalData(mod, hasContains ? st : mod->lastNodeOfStmt(), local, localParams, addedToList, allFuncInfo); - SgProcHedrStmt* newF = new SgProcHedrStmt((string("spf_cp_") + mod->symbol()->identifier()).c_str()); + SgProcHedrStmt* newF = new SgProcHedrStmt(("spf_cp_" + name).c_str()); if (!hasContains) mod->lastNodeOfStmt()->insertStmtBefore(*new SgStatement(CONTAINS_STMT), *mod); mod->lastNodeOfStmt()->insertStmtBefore(*newF, *mod); @@ -803,12 +1319,9 @@ void createCheckpoints(SgFile* file, const map& commonBloc const vector moduleNames = findAllModules(); SgStatement* moduleF = NULL; - const string cpModule = "spf_module_checkpoint"; - SgSymbol* mainModuleCpS = new SgSymbol(MODULE_NAME, cpModule.c_str()); - moduleF = new SgStatement(MODULE_STMT, NULL, mainModuleCpS); - SgStatement* global = current_file->firstStatement(); - global->insertStmtAfter(*moduleF, *global); - + createModule(moduleF, "spf_module_checkpoint"); + SgSymbol* mainModuleCpS = moduleF->symbol(); + for (auto& checkps : inFileCp) { const int cpLine = checkps.first; @@ -837,7 +1350,6 @@ void createCheckpoints(SgFile* file, const map& commonBloc checkNull(func, convertFileName(__FILE__).c_str(), __LINE__); checkNull(point, convertFileName(__FILE__).c_str(), __LINE__); - const int labNum = getNextFreeLabel(); bool createdModuleForIO = createForIOs(filesInfo, func); SgStatement* lastDecl = func->lexNext(); @@ -851,18 +1363,36 @@ void createCheckpoints(SgFile* file, const map& commonBloc map localParams; set addedToList; findLocalData(func, firstExec, local, localParams, addedToList, allFuncInfo); + + 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 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 inFuncParam; + processInFuncParam(funcI, inFuncParam); + + map moduleStmts; + map moduleParamStmts; + set commonVariables; + set externVars; + processVarBlock(func, firstExec, moduleStmts, moduleParamStmts, commonVariables, externVars, funcI, inFuncParam); + + set addedModuleParams; + set localVarNoParams; + insertStmtToModule(moduleStmts, moduleParamStmts, addedModuleParams, commonVariables, proc_moduleF, localVarNoParams, + externVars, funcName.size()); + const vector useOfMods = findUseOfModules(func->lexNext(), firstExec); - SgStatement* loadBlock = new SgStatement(IF_NODE); - SgStatement* storeBlock = new SgStatement(IF_NODE); - - point->insertStmtBefore(*loadBlock, *point->controlParent()); - point->insertStmtBefore(*storeBlock, *point->controlParent()); - - loadBlock->addComment("! LOAD CHECKPOINT\n"); - auto loadblockLab = new SgLabel(labNum); - loadBlock->setLabel(*loadblockLab); - 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)); @@ -870,66 +1400,24 @@ void createCheckpoints(SgFile* file, const map& commonBloc //give max len, dont insert int maxFileLen = insertInitNamesOfFiles(numOfFiles, additional, files, journal, NULL); - vector everyS; vector profS; - vector initS; 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)); - SgSymbol* timeF = new SgSymbol(FUNCTION_NAME, "omp_get_wtime", SgTypeDouble(), func); // OR dvtime + 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)); - 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)); - } - vector loadS; vector initLoadS; - vector insertToLoadS; string cpLoadS = "spf_cp_load" + additional; loadS.push_back(new SgSymbol(VARIABLE_NAME, cpLoadS.c_str(), SgTypeInt(), func)); - initLoadS.push_back(new SgValueExp(0)); + initLoadS.push_back(new SgValueExp(1)); string fileNS = "spf_cp_file_n" + additional; loadS.push_back(new SgSymbol(VARIABLE_NAME, fileNS.c_str(), SgTypeInt(), func)); @@ -939,194 +1427,37 @@ void createCheckpoints(SgFile* file, const map& commonBloc loadS.push_back(new SgSymbol(VARIABLE_NAME, iostatS.c_str(), SgTypeInt(), func)); initLoadS.push_back(NULL); - /*string loadSaveS = "spf_cp_load_save" + additional; - loadS.push_back(new SgSymbol(VARIABLE_NAME, loadSaveS.c_str(), SgTypeInt(), func)); - initLoadS.push_back(new SgValueExp(0));*/ - 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)); - - string saveFS = "spf_cp_save_flag" + additional; - loadS.push_back(new SgSymbol(VARIABLE_NAME, saveFS.c_str(), SgTypeInt(), func)); - initLoadS.push_back(new SgValueExp(0)); - - loadBlock->setExpression(0, *new SgVarRefExp(loadS[0]) == *new SgValueExp(0)); - SgAssignStmt* init = new SgAssignStmt(*new SgVarRefExp(loadS[0]), *new SgValueExp(1)); - insertToLoadS.push_back(init); - - + 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())); + SgExpression* labelIdx = new SgVarRefExp(loadS[3]); SgExpression* iostat = new SgVarRefExp(loadS[2]); SgExpression* fileIdx = new SgVarRefExp(loadS[1]); - insertToLoadS.push_back(createOpenJ_old(iostat, journal, unit)); + vector> 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); + lastDecl->insertStmtAfter(*loadBlock, *lastDecl->controlParent()); - vector insertToifLoadOk; - SgIfStmt* ifLoadOk = new SgIfStmt(*iostat == *new SgValueExp(0)); - insertToLoadS.push_back(ifLoadOk); + if (funcI->isMain) + insertInitNamesOfFiles(numOfFiles, additional, files, journal, lastDecl, false); - SgInputOutputStmt* read = new SgInputOutputStmt(READ_STAT, *makeExprList({ &frmt, &unit }, false), *fileIdx); - 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); - 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 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->copy(), *ifLoadOk1); - - //open all files - if (createdModuleForIO) - { - SgCallStmt* call = new SgCallStmt(*new SgSymbol(FUNCTION_NAME, iosNames[1].c_str())); - ifLoadOk1->insertStmtAfter(*call, *ifLoadOk1); - } - - //READ from modules - for (auto& mod : moduleNames) - { - 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 DATA - if (local.size()) - { - auto dataRead = new SgInputOutputStmt(READ_STAT, unit, *makeExprList(local, false)); - ifLoadOk1->insertStmtAfter(*dataRead, *ifLoadOk1); - } - - ifLoadOk1->insertStmtAfter(profCallS->copy(), *ifLoadOk1); - - vector 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); - - SgIOControlStmt* open = new SgIOControlStmt(OPEN_STAT, *makeExprList(listSpec, false)); - storeBlock->insertStmtAfter(*open, *storeBlock); - - 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(local.size()) + " items\n").c_str()); - - commentArgs.clear(); - 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 ")); - - ifStoreOk->insertStmtAfter(*new SgInputOutputStmt(WRITE_STAT, *makeExprList({ &frmtProf, &unitNull }, false), *makeExprList(commentArgs, false)), *ifStoreOk); - ifStoreOk->insertStmtAfter(profCallE->copy(), *ifStoreOk); - - SgStatement* assign = ifStoreOk->lexNext(); - - //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) - { - 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); - } - - //WRITE DATA - if (local.size()) - { - SgStatement* dataWrite = new SgInputOutputStmt(WRITE_STAT, unit, *makeExprList(local, false)); - ifStoreOk->insertStmtAfter(*dataWrite, *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); - - SgStatement* copyForGoto = loadBlock->copyPtr(); - copyForGoto->deleteLabel(); - firstExec->insertStmtBefore(*copyForGoto, *func); - insertInitNamesOfFiles(numOfFiles, additional, files, journal, copyForGoto, true); - - copyForGoto->insertStmtAfter(insertToLoadS[insertToLoadS.size() - 1]->copy(), *copyForGoto); - copyForGoto->insertStmtAfter(insertToLoadS[insertToLoadS.size() - 2]->copy(), *copyForGoto); - - copyForGoto = copyForGoto->lexNext()->lexNext(); - - copyForGoto->insertStmtAfter(*new SgGotoStmt(*loadblockLab), *copyForGoto); - copyForGoto->insertStmtAfter(*new SgIOControlStmt(CLOSE_STAT, unit), *copyForGoto); - - 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); - - - //TODO: - /*set elemNotDeclHere; - for (auto& elem : commonVars) - { - if (addedToList.find(elem) == addedToList.end()) - elemNotDeclHere.insert(elem); - } - for (auto& elem : elemNotDeclHere) - printf("%s\n", elem.c_str());*/ - - // make all new declarations - makeDeclaration(moduleF, everyS, &initS); + // make all new declarations makeDeclaration(moduleF, loadS, &initLoadS); makeDeclaration(moduleF, profS); makeDeclaration(moduleF, { files }); makeDeclaration(func, { timeF }); func->insertStmtAfter(*new SgStatement(USE_STMT, NULL, mainModuleCpS), *func); + func->insertStmtAfter(*new SgStatement(USE_STMT, NULL, proc_mainModuleCpS), *func); //check use map modulesDone; @@ -1178,9 +1509,75 @@ void createCheckpoints(SgFile* file, const map& commonBloc func->insertStmtAfter(*use, *func); } } + + vector> chainLocalVarNoParams; + vector chainLabel; - //TODO: this function needs to be completely rewritten!! - //processFunctionCallChain(func, allFuncInfo, moduleF, loadS, iostat, journal, frmt, unit, files, fileIdx, every, everyS); + 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 everyS; + vector 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)); + } + + 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()); } processModules(file, allFuncInfo); @@ -1195,18 +1592,6 @@ static string cuttingType(const string& all_decl_with_init) return all_decl_with_init.substr(0, iter); } -static void createModule(SgStatement*& module, const string& name, bool withFile) -{ - if (module == NULL) - { - module = new SgStatement(MODULE_STMT, NULL, new SgSymbol(MODULE_NAME, (name + (withFile ? to_string(current_file_id) : "")).c_str()), NULL, NULL, NULL); - addControlEndToStmt(module->thebif); - - SgStatement* global = current_file->firstStatement(); - global->insertStmtAfter(*module, *global); - } -} - static SgExpression* moveSaveAssignToMod(SgExpression* ex, SgStatement*& saveModule, map& declLists, const string& procName, bool withInit) { diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/version.h b/sapfor/experts/Sapfor_2017/_src/Utils/version.h index f4f69b9..1f9f8a9 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/version.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2339" +#define VERSION_SPF "2340"