diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index 80fddf6..ff10c5c 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1914,6 +1914,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne calculateStatsForPredictor(allFuncInfo, gCovInfo); parseDvmDirForPredictor(declaredArrays, commonBlocks, allFuncInfo, gCovInfo); } + else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS) + transformAssumedSizeParameters(allFuncInfo); const float elapsed = duration_cast(high_resolution_clock::now() - timeForPass).count() / 1000.; const float elapsedGlobal = duration_cast(high_resolution_clock::now() - globalTime).count() / 1000.; @@ -2149,6 +2151,8 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam runAnalysis(*project, REMOVE_COPIES, false); runAnalysis(*project, SWAP_LOOPS, false); + runPass(TRANSFORM_ASSUMED_SIZE_PARAMETERS, proj_name, folderName); + if (folderName || consoleMode) runAnalysis(*project, UNPARSE_FILE, true, additionalName.c_str(), folderName); } diff --git a/src/Sapfor.h b/src/Sapfor.h index 2ed5a83..8277cb8 100644 --- a/src/Sapfor.h +++ b/src/Sapfor.h @@ -185,6 +185,8 @@ enum passes { FIND_PRIVATE_ARRAYS, + TRANSFORM_ASSUMED_SIZE_PARAMETERS, + TEST_PASS, EMPTY_PASS }; @@ -371,6 +373,8 @@ static void setPassValues() passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI"; passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS"; + passNames[TRANSFORM_ASSUMED_SIZE_PARAMETERS] = "TRANSFORM_ASSUMED_SIZE_PARAMETERS"; + passNames[TEST_PASS] = "TEST_PASS"; } diff --git a/src/Transformations/FunctionPurifying/function_purifying.cpp b/src/Transformations/FunctionPurifying/function_purifying.cpp index 38c12ff..b7f8437 100644 --- a/src/Transformations/FunctionPurifying/function_purifying.cpp +++ b/src/Transformations/FunctionPurifying/function_purifying.cpp @@ -66,7 +66,7 @@ void insertIntrinsicStat(const vector& allFuncInfo) void* ptr = call.pointerDetailCallsFrom.first; int var = call.pointerDetailCallsFrom.second; - + SgSymbol* s = NULL; if (var == PROC_STAT) s = ((SgStatement*)ptr)->symbol(); @@ -126,7 +126,7 @@ bool checkOutCalls(const set& outCalls) return false; } -void createInterfacesForOutCalls(FuncInfo* func) +void createInterfacesForOutCalls(FuncInfo* func) { if (func->isPure && !func->isMain) { @@ -136,33 +136,41 @@ void createInterfacesForOutCalls(FuncInfo* func) } } -static bool changeIfHasStarRange(SgExpression* arrayDecl, bool doReplace = false) +static bool changeIfHasStarRange(SgExpression* arrayDecl, SgStatement* scope, vector& parNames) { SgExpression* list = arrayDecl->lhs(); - bool has = doReplace; - + string varN = arrayDecl->symbol()->identifier() + string("_sz"); + bool has = false; + + SgExpression* allDimsBefore = NULL; while (list) { const int var = list->lhs()->variant(); if (var == STAR_RANGE) - has = true; - list = list->rhs(); - } - - if (has) - { - list = arrayDecl->lhs(); - while (list) { - list->setLhs(new SgExpression(DDOT)); - list = list->rhs(); + has = true; + + parNames.push_back(new SgSymbol(VARIABLE_NAME, varN.c_str(), SgTypeInt(), scope)); + SgExpression* par = allDimsBefore ? &(*new SgVarRefExp(parNames.back()) / *allDimsBefore) : (new SgVarRefExp(parNames.back())); + + list->setLhs(par); + break; } + else + { + if (allDimsBefore == NULL) + allDimsBefore = list->lhs(); + else + allDimsBefore = &(*allDimsBefore * *list->lhs()->copyPtr()); + } + + list = list->rhs(); } return has; } -static void removeExternalStat(SgStatement* func, const set& addedInterfaceFor) +/*static void removeExternalStat(SgStatement* func, const set& addedInterfaceFor) { vector toRem; for (auto st = func; st != func->lastNodeOfStmt(); st = st->lexNext()) @@ -197,7 +205,7 @@ static void removeExternalStat(SgStatement* func, const set& addedInterf for (auto& rem : toRem) rem->deleteStmt(); -} +}*/ template static vector sortByName(const T &funcs) @@ -210,10 +218,25 @@ static vector sortByName(const T &funcs) return funcList; } -//XXX: incorrect!! -/*void createInterfacesForAssumedSize(const map>& allFuncInfo) +static bool hasDvmParallel(SgStatement *func) { - set hasAssumedSizeArrays; + for (auto st = func; st != func->lastNodeOfStmt(); st = st->lexNext()) + { + const int var = st->variant(); + if (var == DVM_PARALLEL_ON_DIR || var == ACC_REGION_DIR || + var == ACC_ACTUAL_DIR || var == ACC_GET_ACTUAL_DIR) + return true; + + if (st->variant() == CONTAINS_STMT) + break; + } + + return false; +} + +void transformAssumedSizeParameters(const map>& allFuncInfo) +{ + map> assumedSizeArraysByFunc; for (auto& funcByFile : allFuncInfo) { @@ -221,11 +244,17 @@ static vector sortByName(const T &funcs) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); for (auto& func : funcByFile.second) - { + { SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal()); if (prog == NULL) continue; + if (!hasDvmParallel(prog)) + continue; + + vector parNames; + SgStatement* scope = prog->getScopeForDeclare(); + vector arrayRefs; bool hasRefs = false; for (int z = 0; z < func->funcParams.countOfPars; ++z) @@ -245,13 +274,8 @@ static vector sortByName(const T &funcs) { if (list->lhs() && list->lhs()->symbol()->identifier() == name) { - if (changeIfHasStarRange(list->lhs())) - { - hasRefs = true; - hasAssumedSizeArrays.insert(func); - } - else - arrayRefs.push_back(list->lhs()); + if (changeIfHasStarRange(list->lhs(), scope, parNames)) + assumedSizeArraysByFunc[func->funcName].push_back(z); break; } list = list->rhs(); @@ -260,13 +284,33 @@ static vector sortByName(const T &funcs) } } - if (hasRefs) - for (auto& ref : arrayRefs) - changeIfHasStarRange(ref, true); + if (parNames.size()) + { + SgProcHedrStmt* proc = isSgProcHedrStmt(func->funcPointer->GetOriginal()); + checkNull(proc, convertFileName(__FILE__).c_str(), __LINE__); + + makeDeclaration(parNames, scope); + + for (auto& newPar : parNames) + { + auto arg = new SgVarRefExp(newPar); + BIF_LL1(proc->thebif) = addToExprList(BIF_LL1(proc->thebif), arg->thellnd); + + PTR_LLND ll; + PTR_SYMB symb; + ll = giveLlSymbInDeclList(arg->thellnd); + if (ll && (symb = NODE_SYMB(ll))) + { + appendSymbToArgList(BIF_SYMB(proc->thebif), symb); + SYMB_SCOPE(symb) = proc->thebif; + } + //proc->AddArg(*new SgVarRefExp(newPar)); + } + } } } - if (hasAssumedSizeArrays.size() == 0) + if (assumedSizeArraysByFunc.size() == 0) return; for (auto& funcByFile : allFuncInfo) @@ -274,29 +318,58 @@ static vector sortByName(const T &funcs) if (SgFile::switchToFile(funcByFile.first) == -1) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + SgSymbol* funcSize = new SgSymbol(FUNCTION_NAME, "size"); + for (auto& func : sortByName(funcByFile.second)) { SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal()); if (prog == NULL) continue; - set addedInterfaceFor; - for (auto& elem : sortByName(func->callsFromV)) + for (auto& detailedCall : func->callsFromDetailed) { - auto it = hasAssumedSizeArrays.find(elem); - if (it != hasAssumedSizeArrays.end()) + auto it = assumedSizeArraysByFunc.find(detailedCall.detailCallsFrom.first); + if (it != assumedSizeArraysByFunc.end()) { - auto callFrom = *it; - DvmhRegionInserter::createInterfaceBlockForOutCall(func, callFrom); - addedInterfaceFor.insert(callFrom->funcName); + auto pointer = detailedCall.pointerDetailCallsFrom; + + SgExpression* list = NULL; + if (pointer.second == FUNC_CALL) + { + SgExpression* p = (SgExpression*)pointer.first; + list = p->lhs(); + } + else + { + SgStatement* p = (SgStatement*)pointer.first; + list = p->expr(0); + } + + SgExpression* last = list; + vector pars; + while (list) + { + last = list; + pars.push_back(list->lhs()); + list = list->rhs(); + } + + for (int z = 0; z < it->second.size(); ++z) + { + int parNum = it->second[z]; + if (parNum >= pars.size()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + SgFunctionCallExp* call = new SgFunctionCallExp(*funcSize, *pars[parNum]); + + last->setRhs(new SgExpression(EXPR_LIST, call)); + last = last->rhs(); + } } } - - if (addedInterfaceFor.size()) - removeExternalStat(prog, addedInterfaceFor); - } + } } -}*/ +} static void setPureStatus(FuncInfo* func) { @@ -314,7 +387,7 @@ static void setPureStatus(FuncInfo* func) bool hasIO = func->linesOfIO.size() || func->linesOfStop.size(); if (!hasPure && !hasIO && ((isFunc == false) || (isFunc && hasOut == false))) - { + { header->setExpression(2, new SgExpression(PURE_OP)); header->symbol()->setAttribute(header->symbol()->attributes() | PURE_BIT); } @@ -528,7 +601,7 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt) OutIdentificators.insert(ident); } - //remove conflicted intents + //remove conflicted intents for (auto& entry : func->entry) { for (int i = 0; i < entry->funcParams.countOfPars; i++) @@ -559,11 +632,11 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt) } insertIntents(InOutIdentificators, headerSt, parSym, INOUT_OP, INOUT_BIT); - insertIntents(InIdentificators, headerSt, parSym, IN_OP, IN_BIT); + insertIntents(InIdentificators, headerSt, parSym, IN_OP, IN_BIT); insertIntents(OutIdentificators, headerSt, parSym, OUT_OP, OUT_BIT); } -void intentInsert(const vector& allFuncInfo) +void intentInsert(const vector& allFuncInfo) { for (auto& func : allFuncInfo) { @@ -632,7 +705,7 @@ static void collectForChange(set& allForChange, FuncInfo* start) for (auto& call : elem->callsFromV) if (allForChange.find(call) == allForChange.end()) newAdd.insert(call); - + chagned = newAdd.size() != 0; allForChange.insert(newAdd.begin(), newAdd.end()); @@ -640,7 +713,7 @@ static void collectForChange(set& allForChange, FuncInfo* start) } template -static void transferVarToArg(const map>& commonVarsUsed, const map& commonBlocks, +static void transferVarToArg(const map>& commonVarsUsed, const map& commonBlocks, const FuncInfo* curFunc, CallExp* callExp) { for (auto& common : commonVarsUsed) @@ -724,7 +797,7 @@ static void transferCommons(set& allForChange, map funName()->identifier() == precFunc->funcName) - transferVarToArg(commonVarsUsed, commonBlocks, curFunc, callExp); + transferVarToArg(commonVarsUsed, commonBlocks, curFunc, callExp); } else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT) { @@ -749,7 +822,7 @@ static void transferCommons(set& allForChange, map & allForChange, map second->getGroupedVars(); - + if (curFunc->commonBlocks.count(common.first) > 0) //rename common vars in funcs { uses = true; @@ -799,7 +872,7 @@ static void transferCommons(set& allForChange, map >& allFuncInfo, const map if (func->commonBlocks.size() > 0 && st->variant() != PROG_HEDR) { - for (SgStatement* start = st, *end = st->lastNodeOfStmt(); start != end;) + for (SgStatement* start = st, *end = st->lastNodeOfStmt(); start != end;) { if (start->variant() == CONTAINS_STMT) break; SgStatement* next = start->lexNext(); - if (start->variant() == COMM_STAT && string(start->fileName()) == func->fileName) + if (start->variant() == COMM_STAT && string(start->fileName()) == func->fileName) { if (funcCommonDeclared.count(func) == 0) funcCommonDeclared[func] = set(); @@ -999,11 +1072,11 @@ void commonTransfer(const map>& allFuncInfo, const map if (st->variant() < 0 || st->variant() == PROG_HEDR || func->isInterface) continue; - if (func->commonBlocks.size() > 0) + if (func->commonBlocks.size() > 0) { map> commonVarsUsed; set usedVars; - for (SgStatement* start = st->lastDeclaration()->lexNext(), *end = st->lastNodeOfStmt(); start != end; start = start->lexNext()) + for (SgStatement* start = st->lastDeclaration()->lexNext(), *end = st->lastNodeOfStmt(); start != end; start = start->lexNext()) { if (start->variant() == CONTAINS_STMT) break; @@ -1073,7 +1146,7 @@ static string changeData(const string& data, const map& constSym return res; } -static void transferSave(map>& funcAddedVarsFuncs, vector & varsToTransfer, vector & dataToTransfer, +static void transferSave(map>& funcAddedVarsFuncs, vector & varsToTransfer, vector & dataToTransfer, FuncInfo* curFunc, FuncInfo* precFunc, FuncInfo* startFunc) { if (curFunc != precFunc) @@ -1094,7 +1167,7 @@ static void transferSave(map>& funcAddedVarsFuncs, vec else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT) { SgCallStmt* callSt = (SgCallStmt*)call.first; - if (callSt->name()->identifier() == precFunc->funcName) + if (callSt->name()->identifier() == precFunc->funcName) for (auto& var : varsToTransfer) callSt->addArg(*new SgVarRefExp(*var)); } @@ -1120,7 +1193,7 @@ static void transferSave(map>& funcAddedVarsFuncs, vec { ((SgProcHedrStmt*)(hedr))->AddArg(*new SgVarRefExp(var->copy())); hedr->lexNext()->deleteStmt(); - if (curFunc != startFunc || i!=0) + if (curFunc != startFunc || i!=0) { vector varVec = vector(); varVec.push_back(var); @@ -1160,7 +1233,7 @@ static void transferSave(map>& funcAddedVarsFuncs, vec for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext()) { - if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && !strcmp(hedr->fileName(), start->fileName())) + if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && !strcmp(hedr->fileName(), start->fileName())) { firstExDec = start; break; @@ -1199,7 +1272,7 @@ void saveTransfer(const map>& allFuncInfo) for (auto& byfile : allFuncInfo) for (auto& func : byfile.second) if (func->isMain) - start = func; + start = func; collectForChange(allForChange, start); allForChange.erase(start); @@ -1241,8 +1314,8 @@ void saveTransfer(const map>& allFuncInfo) if (s->scope() == st) { - if ( (s->attributes() & SAVE_BIT) || - (s->attributes() & DATA_BIT) || + if ( (s->attributes() & SAVE_BIT) || + (s->attributes() & DATA_BIT) || allSave && s->variant() == VARIABLE_NAME && !params.count(s->identifier())) { if ((s->type() ? s->type()->variant() : (T_COMPLEX + 1)) > T_COMPLEX) @@ -1293,21 +1366,21 @@ void saveTransfer(const map>& allFuncInfo) SgExprListExp* attrsNoSave = new SgExprListExp(); bool needChange = false; - for (int i = 0; i < vst->numberOfAttributes(); i++) + for (int i = 0; i < vst->numberOfAttributes(); i++) { if (vst->attribute(i)->variant() != SAVE_OP) { attrsNoSave->append(vst->attribute(i)->copy()); - } + } else - needChange = true; + needChange = true; } - if (needChange) + if (needChange) { SgVarDeclStmt* newVst; if (!attrsNoSave->length()) - newVst = new SgVarDeclStmt(vst->varList()->copy(), *attrsNoSave, vst->type()->copy()); + newVst = new SgVarDeclStmt(vst->varList()->copy(), *attrsNoSave, vst->type()->copy()); else newVst = new SgVarDeclStmt(vst->varList()->copy(), vst->type()->copy()); @@ -1335,8 +1408,8 @@ void saveTransfer(const map>& allFuncInfo) } }*/ -static string makeName(SgSymbol* var, map>& modVarsToAdd, const set& useMod, - const map>>& modByUse, +static string makeName(SgSymbol* var, map>& modVarsToAdd, const set& useMod, + const map>>& modByUse, const map>>& modByUseOnly) { string name = "", modName = OriginalSymbol(var)->scope()->symbol()->identifier(); @@ -1358,7 +1431,7 @@ static string makeName(SgSymbol* var, map>& modVarsTo } if (!name.length()) - name = varOrName; + name = varOrName; } else if (mbuo) { @@ -1492,7 +1565,7 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //insert tabs - const string tab = " "; + const string tab = " "; const int countEnds = std::count(codeString.begin(), codeString.end(), '\n'); string retVal = " "; @@ -1584,7 +1657,7 @@ static void createInterfaceBlockForToCalls(FuncInfo* func) } } -static void transferModule(map>& funcAddedVarsMods, set& allForChange, +static void transferModule(map>& funcAddedVarsMods, set& allForChange, vector& varsToTransfer, FuncInfo* curFunc, FuncInfo* precFunc, set& funcForInterfaceAdd) { SgStatement* st = curFunc->funcPointer->GetOriginal(); @@ -1636,7 +1709,7 @@ static void transferModule(map>& funcAddedVarsMods, se else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT) { SgCallStmt* callSt = (SgCallStmt*)call.first; - if (callSt->name()->identifier() == precFunc->funcName) + if (callSt->name()->identifier() == precFunc->funcName) { for (auto& var : varsToTransfer) { @@ -1688,7 +1761,7 @@ static void transferModule(map>& funcAddedVarsMods, se { if (i == 0) curFunc->funcParams.identificators.push_back(var->identifier()); - + ((SgProcHedrStmt*)(hedr))->AddArg(*new SgVarRefExp(var->copy())); hedr->lexNext()->deleteStmt(); vector varVec = vector(); @@ -1712,7 +1785,7 @@ static void transferModule(map>& funcAddedVarsMods, se } } - if (!isAuto) + if (!isAuto) { funcForInterfaceAdd.insert(curFunc); SgAttributeExp* a = new SgAttributeExp(ALLOCATABLE_OP); @@ -1732,8 +1805,8 @@ static void transferModule(map>& funcAddedVarsMods, se SgStatement* firstExDec = NULL; for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext()) { - if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && - !strcmp(hedr->fileName(), start->fileName())) + if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && + !strcmp(hedr->fileName(), start->fileName())) { firstExDec = start; break; @@ -1824,7 +1897,7 @@ void moduleTransfer(const map>& allFuncInfo) break; SgStatement* next = start->lexNext(); - if (start->variant() == USE_STMT) + if (start->variant() == USE_STMT) { SgExpression* onlyE = start->expr(0); if (onlyE) @@ -1850,7 +1923,7 @@ void moduleTransfer(const map>& allFuncInfo) } if (renameL) - onlyE->setLhs(renameL); + onlyE->setLhs(renameL); else start->deleteStmt(); } @@ -1858,7 +1931,7 @@ void moduleTransfer(const map>& allFuncInfo) if (isSgExecutableStatement(start)|| isSgDeclarationStatement(start)) for (int i = 0; i < 3; i++) fillUsedVars(usedVars, start->expr(i)); - + // if (start->variant() == IMPL_DECL) // start->deleteStmt(); start = next; diff --git a/src/Transformations/FunctionPurifying/function_purifying.h b/src/Transformations/FunctionPurifying/function_purifying.h index 9f8d529..6b0d6ad 100644 --- a/src/Transformations/FunctionPurifying/function_purifying.h +++ b/src/Transformations/FunctionPurifying/function_purifying.h @@ -14,4 +14,6 @@ void commonTransfer(const std::map>& allFunc void saveTransfer(const std::map>& allFuncInfo); void moduleTransfer(const std::map>& allFuncInfo); -void insertInterface(SgStatement* func, const FuncInfo* callFrom); \ No newline at end of file +void insertInterface(SgStatement* func, const FuncInfo* callFrom); + +void transformAssumedSizeParameters(const std::map>& allFuncInfo); \ No newline at end of file diff --git a/src/Utils/version.h b/src/Utils/version.h index 7a6ceb8..737af8b 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2436" +#define VERSION_SPF "2437"