From 39abbafb3a48ee47e703b6dbfdc6c6066bfae517 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Thu, 9 Apr 2026 15:35:28 +0300 Subject: [PATCH 01/32] fixed intent insertion --- src/GraphCall/graph_calls.cpp | 43 +++++++++++++++++++++++++++++------ src/Utils/version.h | 2 +- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/GraphCall/graph_calls.cpp b/src/GraphCall/graph_calls.cpp index 1e44544..1ec24f9 100644 --- a/src/GraphCall/graph_calls.cpp +++ b/src/GraphCall/graph_calls.cpp @@ -800,29 +800,58 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co static map> supportedKeyWordArg = { {"system_clock", { OUT_BIT, OUT_BIT, OUT_BIT } } }; - map parNames; + map parNamesMain; + map parNamesContains; for (int i = 0; i < currF->funcParams.identificators.size(); ++i) - parNames[currF->funcParams.identificators[i]] = i; + parNamesMain[currF->funcParams.identificators[i]] = i; + map& parNames = parNamesMain; + + bool isContainsFunctions = false; for (auto st = start; st != last; st = st->lexNext()) { - if (st->variant() == CONTAINS_STMT) - break; + if (st->variant() == CONTAINS_STMT) { + isContainsFunctions = true; + continue; + } + + if (isContainsFunctions) { + if (st->variant() == PROC_HEDR || st->variant() == FUNC_HEDR) { + parNamesContains = parNamesMain; + + SgProgHedrStmt* hedr = (SgProgHedrStmt*)st; + + int numOfParams = hedr->numberOfParameters(); + if (numOfParams > 0) + { + for (int i = 0; i < numOfParams; ++i) + { + auto it = parNamesContains.find(hedr->parameter(i)->identifier()); + if (it != parNamesContains.end()) + parNamesContains.erase(it); + } + } + parNames = parNamesContains; + } + } if (st->variant() == ENTRY_STAT) continue; if (isSgExecutableStatement(st) == NULL) { - checkInTypeDescription(st->expr(0), currF, parNames); + if (!isContainsFunctions) + checkInTypeDescription(st->expr(0), currF, parNames); continue; } if (st->lineNumber() <= 0) continue; - if (activeOps.size() && activeOps.find(st) == activeOps.end()) - continue; + //XXX: use parameters removing in block ... isContainsFunctions ... + //TODO need to use IR for parameters checking + /*if (activeOps.size() && activeOps.find(st) == activeOps.end()) + continue; */ if (st->variant() == ASSIGN_STAT) { diff --git a/src/Utils/version.h b/src/Utils/version.h index 05ba3d0..207a063 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2472" +#define VERSION_SPF "2473" From 97e60e16bebf153c41cc4a5b6ebf207708d6ab50 Mon Sep 17 00:00:00 2001 From: Oleg Nikitin Date: Thu, 12 Mar 2026 04:25:45 +0300 Subject: [PATCH 02/32] add ddot, change array propagation --- src/ArrayConstantPropagation/propagation.cpp | 288 ++++++++++-------- src/PrivateAnalyzer/private_arrays_search.cpp | 24 +- src/PrivateAnalyzer/region.cpp | 2 +- 3 files changed, 175 insertions(+), 139 deletions(-) diff --git a/src/ArrayConstantPropagation/propagation.cpp b/src/ArrayConstantPropagation/propagation.cpp index bf56a3f..2e94e69 100644 --- a/src/ArrayConstantPropagation/propagation.cpp +++ b/src/ArrayConstantPropagation/propagation.cpp @@ -9,7 +9,10 @@ using namespace std; -static SgStatement* declPlace = NULL; +SgStatement* declPlace = NULL; +unordered_set changed; +unordered_set variablesToAdd; +unordered_set positionsToAdd; static bool CheckConstIndexes(SgExpression* exp) { @@ -40,137 +43,117 @@ static SgExpression* CreateVar(int& variableNumber, SgType* type) string name = varName + std::to_string(variableNumber) + "__"; variableNumber++; - SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *declPlace->controlParent()); + SgStatement* funcStart = declPlace->controlParent(); + SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *funcStart); + + variablesToAdd.insert(varSymbol); + positionsToAdd.insert(declPlace); + + return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr()); +} + +static SgStatement* FindLastDeclStatement(SgStatement* funcStart) +{ + SgStatement* endSt = funcStart->lastNodeOfStmt(); + SgStatement* cur = funcStart->lexNext(); + SgStatement* lastDecl = funcStart; + const set declVariants = { VAR_DECL, VAR_DECL_90, ALLOCATABLE_STMT, DIM_STAT, + EXTERN_STAT, COMM_STAT, HPF_TEMPLATE_STAT, DVM_VAR_DECL, STRUCT_DECL }; + + while (cur && cur != endSt) + { + if (cur->variant() == INTERFACE_STMT) + cur = cur->lastNodeOfStmt(); + + if (declVariants.find(cur->variant()) != declVariants.end()) + lastDecl = cur; + else if (isSgExecutableStatement(cur)) + break; + + cur = cur->lexNext(); + } + + return lastDecl; +} + +static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unordered_set& symbols) +{ + if (symbols.empty()) + return; const string commonBlockName = "__propagation_common__"; - SgStatement* funcStart = declPlace->controlParent(); + SgStatement* funcEnd = funcStart->lastNodeOfStmt(); SgStatement* commonStat = NULL; SgExpression* commonList = NULL; - SgStatement* funcEnd = funcStart->lastNodeOfStmt(); - SgStatement* current = funcStart->lexNext(); - - while (current != funcEnd && current) + for (SgStatement* cur = funcStart->lexNext(); + cur && cur != funcEnd; cur = cur->lexNext()) { - if (current->variant() == COMM_STAT) + if (cur->variant() != COMM_STAT) + continue; + + for (SgExpression* exp = cur->expr(0); exp; exp = exp->rhs()) { - for (SgExpression* exp = current->expr(0); exp; exp = exp->rhs()) + if (exp->variant() != COMM_LIST) + continue; + + const char* id = exp->symbol() ? exp->symbol()->identifier() : NULL; + string existingName = id ? string(id) : string("spf_unnamed"); + if (existingName == commonBlockName) { - if (exp->variant() == COMM_LIST) - { - string existingName = exp->symbol() ? - string(exp->symbol()->identifier()) : - string("spf_unnamed"); - if (existingName == commonBlockName) - { - commonStat = current; - commonList = exp; - break; - } - } - } - if (commonStat) + commonStat = cur; + commonList = exp; break; + } } - current = current->lexNext(); + if (commonStat) + break; } vector varRefs; - if (commonList) - { - SgExpression* varList = commonList->lhs(); - if (varList) - { - auto extractSymbol = [](SgExpression* exp) -> SgSymbol* { - if (!exp) - return NULL; - if (exp->symbol()) - return exp->symbol(); - if (exp->lhs() && exp->lhs()->symbol()) - return exp->lhs()->symbol(); - return NULL; - }; - if (varList->variant() == EXPR_LIST) - { - for (SgExpression* exp = varList; exp; exp = exp->rhs()) - { - SgExpression* varExp = exp->lhs(); - SgSymbol* sym = extractSymbol(varExp); - if (sym) - { - varRefs.push_back(new SgVarRefExp(sym)); - } - } - } - else - { - for (SgExpression* varExp = varList; varExp; varExp = varExp->rhs()) - { - SgSymbol* sym = extractSymbol(varExp); - if (sym) - { - varRefs.push_back(new SgVarRefExp(sym)); - } - } - } - } - } + for (SgSymbol* sym : symbols) + varRefs.push_back(new SgVarRefExp(sym)); + SgExpression* varList = makeExprList(varRefs, false); if (!commonList) { - current = funcStart->lexNext(); - while (current != funcEnd && current) - { - if (current->variant() == COMM_STAT) - { - commonStat = current; - break; - } - current = current->lexNext(); - } - SgSymbol* commonSymbol = new SgSymbol(COMMON_NAME, commonBlockName.c_str()); - commonList = new SgExpression(COMM_LIST, NULL, NULL, commonSymbol); + commonList = new SgExpression(COMM_LIST, varList, NULL, commonSymbol); - if (commonStat) - { - SgExpression* lastCommList = commonStat->expr(0); - if (lastCommList) - { - while (lastCommList->rhs()) - lastCommList = lastCommList->rhs(); - lastCommList->setRhs(commonList); - } - else - { - commonStat->setExpression(0, commonList); - } - } - else - { - commonStat = new SgStatement(COMM_STAT); - commonStat->setFileName(declPlace->fileName()); - commonStat->setFileId(declPlace->getFileId()); - commonStat->setProject(declPlace->getProject()); - commonStat->setlineNumber(getNextNegativeLineNumber()); - commonStat->setExpression(0, commonList); - - declPlace->insertStmtBefore(*commonStat, *declPlace->controlParent()); - } + commonStat = new SgStatement(COMM_STAT); + commonStat->setFileName(funcStart->fileName()); + commonStat->setFileId(funcStart->getFileId()); + commonStat->setProject(funcStart->getProject()); + commonStat->setlineNumber(getNextNegativeLineNumber()); + commonStat->setExpression(0, commonList); + SgStatement* lastDecl = FindLastDeclStatement(funcStart); + lastDecl->insertStmtAfter(*commonStat, *funcStart); } - varRefs.push_back(new SgVarRefExp(varSymbol)); - - if (varRefs.size() > 0) + else { - std::reverse(varRefs.begin(), varRefs.end()); - SgExpression* varList = makeExprList(varRefs, false); - commonList->setLhs(varList); } - return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr()); + SgStatement* insertAfter = commonStat; + for (SgSymbol* sym : symbols) + { + SgStatement* declStmt = sym->makeVarDeclStmt(); + if (!declStmt) + continue; + + if (SgVarDeclStmt* vds = isSgVarDeclStmt(declStmt)) + vds->setVariant(VAR_DECL_90); + + declStmt->setFileName(funcStart->fileName()); + declStmt->setFileId(funcStart->getFileId()); + declStmt->setProject(funcStart->getProject()); + declStmt->setlineNumber(getNextNegativeLineNumber()); + + insertAfter->insertStmtAfter(*declStmt, *funcStart); + insertAfter = declStmt; + } } static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) @@ -227,6 +210,8 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map< { if (exp->symbol()->type()->variant() == T_STRING) return; + if (changed.find(st) != changed.end()) + return; string expUnparsed = exp->unparse(); if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) { @@ -234,12 +219,62 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map< } SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, arrayToVariable[expUnparsed]->copyPtr(), st->expr(1)->copyPtr(), NULL); - newStatement->setFileId(st->getFileId()); + newStatement->setFileId(st->getFileId()); newStatement->setProject(st->getProject()); newStatement->setlineNumber(getNextNegativeLineNumber()); newStatement->setLocalLineNumber(st->lineNumber()); st->insertStmtBefore(*newStatement, *st->controlParent()); + changed.insert(st); +} + +static void TransformBorder(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) +{ + SgStatement* firstStatement = declPlace->lexPrev(); + st = st->lexPrev(); + string array = exp->unparse(); + arrayToVariable[array] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); + while (st != firstStatement) + { + if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) + { + if (st->expr(1)) + { + TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); + } + if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) + { + TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); + } + } + st = st->lexPrev(); + } +} + +static void CheckVariable(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) +{ + SgStatement* firstStatement = declPlace->lexPrev(); + st = st->lexPrev(); + string varName = exp->unparse(); + while (st != firstStatement) + { + if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol()) + { + TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); + } + if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) + { + if (st->expr(1)) + { + TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); + } + if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) + { + TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); + } + } + st = st->lexPrev(); + } } void ArrayConstantPropagation(SgProject& project) @@ -262,40 +297,37 @@ void ArrayConstantPropagation(SgProject& project) for (; st != lastNode; st = st->lexNext()) { - if (st->variant() == ASSIGN_STAT) - { - if (st->expr(1)) - { - TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); - } - if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs())) - { - TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); - } - } - else if (st->variant() == FOR_NODE) + if (st->variant() == FOR_NODE) { SgExpression* lowerBound = st->expr(0)->lhs(); SgExpression* upperBound = st->expr(0)->rhs(); string lowerBoundUnparsed = lowerBound->unparse(), upperBoundUnparsed = upperBound->unparse(); if (upperBound->variant() == ARRAY_REF && upperBound->symbol()->type()->baseType() && CheckConstIndexes(upperBound->lhs())) { - if (arrayToVariable.find(upperBoundUnparsed) == arrayToVariable.end()) - { - arrayToVariable[upperBoundUnparsed] = CreateVar(variableNumber, upperBound->symbol()->type()->baseType()); - } + TransformBorder(st, upperBound, arrayToVariable, variableNumber); st->expr(0)->setRhs(arrayToVariable[upperBoundUnparsed]->copyPtr()); } + else if (upperBound->variant() == VAR_REF) + CheckVariable(st, upperBound, arrayToVariable, variableNumber); + if (lowerBound->variant() == ARRAY_REF && lowerBound->symbol()->type()->baseType() && CheckConstIndexes(lowerBound->lhs())) { - if (arrayToVariable.find(lowerBoundUnparsed) == arrayToVariable.end()) - { - arrayToVariable[lowerBoundUnparsed] = CreateVar(variableNumber, lowerBound->symbol()->type()->baseType()); - } + TransformBorder(st, lowerBound, arrayToVariable, variableNumber); st->expr(0)->setLhs(arrayToVariable[lowerBoundUnparsed]->copyPtr()); } + else if (lowerBound->variant() == VAR_REF) + CheckVariable(st, lowerBound, arrayToVariable, variableNumber); } } } + unordered_set funcStarts; + for (SgStatement* st : positionsToAdd) + { + SgStatement* scope = st->controlParent(); + if (scope) + funcStarts.insert(scope); + } + for (const auto& st: funcStarts) + InsertCommonAndDeclsForFunction(st, variablesToAdd); } } \ No newline at end of file diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index 95624f5..e50ae25 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -33,10 +33,9 @@ static void RemoveEmptyPoints(ArrayAccessingIndexes& container) points.push_back(arrayPoint); } - if (points.size() < accessingSet.GetElements().size() && !points.empty()) + if (!points.empty()) resultContainer[arrayName] = points; - - if (points.empty()) + else toRemove.insert(arrayName); } @@ -281,7 +280,6 @@ static void SolveDataFlow(Region* DFG) static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector& declaredDims) { - declaredDims.clear(); if (!arrayRef || !arrayRef->symbol() || !isSgArrayType(arrayRef->symbol()->type())) return false; SgArrayType* arrayType = (SgArrayType*)arrayRef->symbol()->type(); @@ -290,17 +288,22 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector { SgExpression* sizeExpr = arrayType->sizeInDim(i); SgConstantSymb* constValSymb = isSgConstantSymb(sizeExpr->symbol()); - string strDimLength; + SgSubscriptExp* subscriptExpr = isSgSubscriptExp(sizeExpr); + uint64_t dimLength; if (sizeExpr && sizeExpr->variant() == INT_VAL) - strDimLength = sizeExpr->unparse(); + dimLength = stol(sizeExpr->unparse()); else if (constValSymb) - strDimLength = constValSymb->constantValue()->unparse(); + dimLength = stol(constValSymb->constantValue()->unparse()); + else if (subscriptExpr) + { + dimLength = stol(subscriptExpr->rhs()->unparse()) - stol(subscriptExpr->lhs()->unparse()); + } else return false; - if (strDimLength == "0") + if (dimLength == 0) return false; - declaredDims.push_back((uint64_t)stoi(strDimLength)); + declaredDims.push_back(dimLength); } return true; } @@ -313,7 +316,8 @@ static bool CheckDimensionLength(const AccessingSet& array) SgArrayRefExp* arrayRef = array.GetElements()[0][0].array; if (!arrayRef) return false; - vector declaredDims(dimCount); + vector declaredDims; + declaredDims.reserve(dimCount); if (!getArrayDeclaredDimensions(arrayRef, declaredDims)) return false; vector testArray(dimCount); diff --git a/src/PrivateAnalyzer/region.cpp b/src/PrivateAnalyzer/region.cpp index 7e47308..5657729 100644 --- a/src/PrivateAnalyzer/region.cpp +++ b/src/PrivateAnalyzer/region.cpp @@ -204,7 +204,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces current_dim = { start, step, iters, ref }; } - if (current_dim.start != 0 && current_dim.step != 0 && current_dim.tripCount != 0) + if (current_dim.step != 0 && current_dim.tripCount != 0) { accessPoint[n - index_vars.size()] = current_dim; fillCount++; From 8632dfbf31ff85a524c0e24d5d0ed35e6dc3591a Mon Sep 17 00:00:00 2001 From: Oleg Nikitin Date: Thu, 26 Mar 2026 16:01:14 +0300 Subject: [PATCH 03/32] fixes --- src/ArrayConstantPropagation/propagation.cpp | 6 +- src/PrivateAnalyzer/private_arrays_search.cpp | 72 +++++++++++++++---- src/PrivateAnalyzer/region.cpp | 33 +++++++-- src/PrivateAnalyzer/region.h | 4 +- src/Utils/SgUtils.cpp | 2 +- 5 files changed, 94 insertions(+), 23 deletions(-) diff --git a/src/ArrayConstantPropagation/propagation.cpp b/src/ArrayConstantPropagation/propagation.cpp index 2e94e69..dddf265 100644 --- a/src/ArrayConstantPropagation/propagation.cpp +++ b/src/ArrayConstantPropagation/propagation.cpp @@ -287,7 +287,6 @@ void ArrayConstantPropagation(SgProject& project) if (!file) continue; - const int funcNum = file->numberOfFunctions(); for (int i = 0; i < funcNum; ++i) { @@ -327,7 +326,10 @@ void ArrayConstantPropagation(SgProject& project) if (scope) funcStarts.insert(scope); } - for (const auto& st: funcStarts) + for (const auto& st : funcStarts) + { + SgFile::switchToFile(st->fileName()); InsertCommonAndDeclsForFunction(st, variablesToAdd); + } } } \ No newline at end of file diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index e50ae25..95cb090 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -7,16 +7,20 @@ #include #include +#include "CFGraph/CFGraph.h" +#include "Distribution/Array.h" +#include "graph_loops.h" #include "private_arrays_search.h" #include "range_structures.h" #include "region.h" #include "SgUtils.h" -#include "graph_loops.h" -#include "CFGraph/CFGraph.h" #include "utils.h" +#include "Utils/AstWrapper.h" using namespace std; +extern std::map, std::pair> declaredArrays; + static unordered_set collapsed; static void RemoveEmptyPoints(ArrayAccessingIndexes& container) @@ -308,29 +312,63 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector return true; } +static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym) +{ + if (!arrSym) + return nullptr; + for (auto& [key, val] : declaredArrays) + { + DIST::Array* distArr = val.first; + if (!distArr) + continue; + Symbol* declSym = distArr->GetDeclSymbol(); + if (!declSym) + continue; + SgSymbol* sgDecl = declSym->GetOriginal(); + if (sgDecl && isEqSymbols(sgDecl, arrSym)) + return distArr; + } + return nullptr; +} + static bool CheckDimensionLength(const AccessingSet& array) { if (array.GetElements().empty()) return false; size_t dimCount = array.GetElements()[0].size(); SgArrayRefExp* arrayRef = array.GetElements()[0][0].array; - if (!arrayRef) + if (!arrayRef || !arrayRef->symbol()) return false; + vector declaredDims; declaredDims.reserve(dimCount); - if (!getArrayDeclaredDimensions(arrayRef, declaredDims)) - return false; - vector testArray(dimCount); - for (size_t i = 0; i < dimCount; i++) + + DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol()); + if (distArr && distArr->GetDimSize() == (int)dimCount) { - testArray[i] = { 1, 1, declaredDims[i], nullptr }; + const auto& sizes = distArr->GetSizes(); + bool valid = true; + for (size_t i = 0; i < dimCount && valid; ++i) + { + int lo = sizes[i].first; + int hi = sizes[i].second; + if (lo > hi) + valid = false; + else + declaredDims.push_back((uint64_t)(hi - lo + 1)); + } + if (valid && declaredDims.size() == dimCount) + { + vector testArray(dimCount); + for (size_t i = 0; i < dimCount; i++) + testArray[i] = { 1, 1, declaredDims[i], nullptr }; + return AccessingSet({ testArray }).Diff(array).GetElements().empty(); + } } - AccessingSet diff = AccessingSet({ testArray }).Diff(array); - return diff.GetElements().empty(); + return false; } - static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set& insertedPrivates) { SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR); @@ -338,6 +376,7 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& spfStat->setFileName(loop->loop->fileName()); SgExpression* toAdd = new SgExpression(EXPR_LIST, new SgExpression(ACC_PRIVATE_OP), NULL, NULL); set arraysToInsert; + std::cout << "First bp\n"; for (const auto& [_, accessingSet] : privates) { if (!CheckDimensionLength(accessingSet)) @@ -395,7 +434,15 @@ void FindPrivateArrays(map>& loopGraph, mapfileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func) { - Region* loopRegion = new Region(loop, blocks); + Region* loopRegion; + try + { + loopRegion = new Region(loop, blocks); + } + catch (...) + { + continue; + } if (loopRegion->getBasickBlocks().size() <= 1) { delete(loopRegion); @@ -407,7 +454,6 @@ void FindPrivateArrays(map>& loopGraph, map accessPoint(n); auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); + if (!ref) + continue; int fillCount = 0; vector> coeffsForDims; @@ -267,13 +269,30 @@ static void DFS(Region* block, vector& result, unordered_set c result.push_back(block); } -void TopologySort(std::vector& basikBlocks, Region* header) +bool HasCycle(Region* block, const std::unordered_set& cycleBlocks, std::unordered_set& visitedBlocks) +{ + if (visitedBlocks.find(block) != visitedBlocks.end()) + return true; + visitedBlocks.insert(block); + for (Region* nextBlock : block->getNextRegions()) + { + if (cycleBlocks.find(nextBlock) != cycleBlocks.end() && HasCycle(nextBlock, cycleBlocks, visitedBlocks)) + return true; + } + return false; +} + +bool TopologySort(std::vector& basikBlocks, Region* header) { - vector result; unordered_set cycleBlocks(basikBlocks.begin(), basikBlocks.end()); + unordered_set visitedBlocks; + if (HasCycle(header, cycleBlocks, visitedBlocks)) + return false; + vector result; DFS(header, result, cycleBlocks); reverse(result.begin(), result.end()); - basikBlocks = result; + basikBlocks = move(result); + return true; } static void SetConnections(unordered_map& bbToRegion, const unordered_set& blockSet) @@ -313,7 +332,8 @@ static Region* CreateSubRegion(LoopGraph* loop, const vectoraddSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); } - TopologySort(region->getBasickBlocks(), region->getHeader()); + if (!TopologySort(region->getBasickBlocks(), region->getHeader())) + throw std::runtime_error("Unnoticed cycle"); return region; } @@ -337,6 +357,7 @@ Region::Region(LoopGraph* loop, const vector& Blocks) if (!childLoop->isFor()) continue; subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); - } - TopologySort(basickBlocks, this->header); + } + if (!TopologySort(basickBlocks, this->header)) + throw std::runtime_error("Unnoticed cycle"); } \ No newline at end of file diff --git a/src/PrivateAnalyzer/region.h b/src/PrivateAnalyzer/region.h index 3baa8a0..2b39af2 100644 --- a/src/PrivateAnalyzer/region.h +++ b/src/PrivateAnalyzer/region.h @@ -79,4 +79,6 @@ private: Region* header; }; -void TopologySort(std::vector& basikBlocks, Region* header); \ No newline at end of file +bool HasCycle(Region* block, const std::unordered_set& cycleBlocks, std::unordered_set& visitedBlocks); + +bool TopologySort(std::vector& basikBlocks, Region* header); \ No newline at end of file diff --git a/src/Utils/SgUtils.cpp b/src/Utils/SgUtils.cpp index cb009ff..5360662 100644 --- a/src/Utils/SgUtils.cpp +++ b/src/Utils/SgUtils.cpp @@ -658,7 +658,7 @@ string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const ch if (wasDeleted) { - if (str.size() || str.back() != '\n') + if (str.size() && str.back() != '\n') str += '\n'; st->setComments(str.c_str()); } From 7bca67b75c7ec919fe1c35424832479800f9b562 Mon Sep 17 00:00:00 2001 From: Oleg Nikitin Date: Thu, 9 Apr 2026 21:56:03 +0300 Subject: [PATCH 04/32] new changes --- src/ArrayConstantPropagation/propagation.cpp | 149 ++++++++++++------ src/ArrayConstantPropagation/propagation.h | 16 ++ src/PrivateAnalyzer/private_arrays_search.cpp | 20 +++ src/Utils/PassManager.h | 2 +- 4 files changed, 134 insertions(+), 53 deletions(-) diff --git a/src/ArrayConstantPropagation/propagation.cpp b/src/ArrayConstantPropagation/propagation.cpp index dddf265..a9400fc 100644 --- a/src/ArrayConstantPropagation/propagation.cpp +++ b/src/ArrayConstantPropagation/propagation.cpp @@ -3,16 +3,35 @@ #include "../Utils/SgUtils.h" #include +#include #include #include #include using namespace std; +namespace { + + struct MyHash { + size_t operator()(const SgSymbol* s) const { + return std::hash{}(s->identifier()); + } + }; + + struct MyEq { + bool operator()(const SgSymbol* a, const SgSymbol* b) const { + return std::strcmp(a->identifier(), b->identifier()) == 0; + } + }; + +} + SgStatement* declPlace = NULL; unordered_set changed; -unordered_set variablesToAdd; +unordered_set variablesToAdd; unordered_set positionsToAdd; +unordered_set statementsToRemove; +unordered_map>> expToChange; static bool CheckConstIndexes(SgExpression* exp) { @@ -76,7 +95,7 @@ static SgStatement* FindLastDeclStatement(SgStatement* funcStart) return lastDecl; } -static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unordered_set& symbols) +static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unordered_set& symbols) { if (symbols.empty()) return; @@ -113,30 +132,15 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unorde vector varRefs; for (SgSymbol* sym : symbols) - varRefs.push_back(new SgVarRefExp(sym)); + { + if (!sym || sym->variant() != VARIABLE_NAME || string(sym->identifier()) == commonBlockName) + continue; + SgSymbol* symToAdd = new SgSymbol(VARIABLE_NAME, sym->identifier(), *sym->type(), *funcStart); + varRefs.push_back(new SgVarRefExp(symToAdd)); + } SgExpression* varList = makeExprList(varRefs, false); - if (!commonList) - { - SgSymbol* commonSymbol = new SgSymbol(COMMON_NAME, commonBlockName.c_str()); - commonList = new SgExpression(COMM_LIST, varList, NULL, commonSymbol); - - commonStat = new SgStatement(COMM_STAT); - commonStat->setFileName(funcStart->fileName()); - commonStat->setFileId(funcStart->getFileId()); - commonStat->setProject(funcStart->getProject()); - commonStat->setlineNumber(getNextNegativeLineNumber()); - commonStat->setExpression(0, commonList); - - SgStatement* lastDecl = FindLastDeclStatement(funcStart); - lastDecl->insertStmtAfter(*commonStat, *funcStart); - } - else - { - commonList->setLhs(varList); - } - - SgStatement* insertAfter = commonStat; + SgStatement* insertAfter = FindLastDeclStatement(funcStart); for (SgSymbol* sym : symbols) { SgStatement* declStmt = sym->makeVarDeclStmt(); @@ -153,28 +157,53 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unorde insertAfter->insertStmtAfter(*declStmt, *funcStart); insertAfter = declStmt; + statementsToRemove.insert(declStmt); } + + if (!commonList) + { + SgSymbol* commonSymbol = new SgSymbol(COMMON_NAME, commonBlockName.c_str()); + commonList = new SgExpression(COMM_LIST, varList, NULL, commonSymbol); + + commonStat = new SgStatement(COMM_STAT); + commonStat->setFileName(funcStart->fileName()); + commonStat->setFileId(funcStart->getFileId()); + commonStat->setProject(funcStart->getProject()); + commonStat->setlineNumber(getNextNegativeLineNumber()); + commonStat->setExpression(0, commonList); + + SgStatement* lastDecl = FindLastDeclStatement(funcStart); + lastDecl->insertStmtAfter(*commonStat, *funcStart); + statementsToRemove.insert(commonStat); + } + else + { + commonList->setLhs(varList); + } + } static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) { if (!exp) - { return; - } - vector subnodes = { exp->lhs(), exp->rhs() }; string expUnparsed; SgExpression* toAdd = NULL; if (exp->variant() == ARRAY_REF && CheckConstIndexes(exp->lhs())) { - cout << st->unparse() << endl; + expUnparsed = exp->unparse(); if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) { arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); } - st->setExpression(1, arrayToVariable[expUnparsed]->copyPtr()); + positionsToAdd.insert(declPlace); + SgSymbol* builder = arrayToVariable[expUnparsed]->symbol(); + auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent()); + auto* newVarExp = new SgVarRefExp(sym); + expToChange[st->fileName()].push_back({ st , st->copyPtr() }); + st->setExpression(1, newVarExp); return; } for (int i = 0; i < 2; i++) @@ -182,27 +211,30 @@ static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map if (subnodes[i] && subnodes[i]->variant() == ARRAY_REF && subnodes[i]->symbol()->type()->baseType() && CheckConstIndexes(subnodes[i]->lhs())) { expUnparsed = subnodes[i]->unparse(); - if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) - { - arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType());; - } - toAdd = arrayToVariable[expUnparsed]->copyPtr(); + if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) + arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType()); + + positionsToAdd.insert(declPlace); + SgSymbol* builder = arrayToVariable[expUnparsed]->symbol(); + auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent()); + toAdd = new SgVarRefExp(sym); if (toAdd) { if (i == 0) { + expToChange[st->fileName()].push_back({ st , st->copyPtr() });; exp->setLhs(toAdd); } else { + expToChange[st->fileName()].push_back({ st , st->copyPtr() });; exp->setRhs(toAdd); } } } else - { TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber); - } + } } @@ -217,15 +249,17 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map< { arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); } + positionsToAdd.insert(declPlace); SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, arrayToVariable[expUnparsed]->copyPtr(), st->expr(1)->copyPtr(), NULL); - newStatement->setFileId(st->getFileId()); + newStatement->setFileId(st->getFileId()); newStatement->setProject(st->getProject()); newStatement->setlineNumber(getNextNegativeLineNumber()); newStatement->setLocalLineNumber(st->lineNumber()); st->insertStmtBefore(*newStatement, *st->controlParent()); changed.insert(st); + statementsToRemove.insert(newStatement); } static void TransformBorder(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) @@ -233,7 +267,8 @@ static void TransformBorder(SgStatement* st, SgExpression* exp, unordered_maplexPrev(); st = st->lexPrev(); string array = exp->unparse(); - arrayToVariable[array] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); + if (arrayToVariable.find(array) == arrayToVariable.end()) + arrayToVariable[array] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); while (st != firstStatement) { if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) @@ -243,9 +278,7 @@ static void TransformBorder(SgStatement* st, SgExpression* exp, unordered_mapexpr(1), arrayToVariable, variableNumber); } if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) - { TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); - } } st = st->lexPrev(); } @@ -261,16 +294,19 @@ static void CheckVariable(SgStatement* st, SgExpression* exp, unordered_mapvariant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol()) { TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); + positionsToAdd.insert(declPlace); } if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) { if (st->expr(1)) { TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); + positionsToAdd.insert(declPlace); } if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) { TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); + positionsToAdd.insert(declPlace); } } st = st->lexPrev(); @@ -287,6 +323,7 @@ void ArrayConstantPropagation(SgProject& project) if (!file) continue; + SgFile::switchToFile(file->filename()); const int funcNum = file->numberOfFunctions(); for (int i = 0; i < funcNum; ++i) { @@ -300,36 +337,44 @@ void ArrayConstantPropagation(SgProject& project) { SgExpression* lowerBound = st->expr(0)->lhs(); SgExpression* upperBound = st->expr(0)->rhs(); + SgStatement* boundCopy = NULL; string lowerBoundUnparsed = lowerBound->unparse(), upperBoundUnparsed = upperBound->unparse(); if (upperBound->variant() == ARRAY_REF && upperBound->symbol()->type()->baseType() && CheckConstIndexes(upperBound->lhs())) { + boundCopy = st->copyPtr(); TransformBorder(st, upperBound, arrayToVariable, variableNumber); st->expr(0)->setRhs(arrayToVariable[upperBoundUnparsed]->copyPtr()); + expToChange[st->fileName()].push_back({ st ,boundCopy });; + positionsToAdd.insert(declPlace); } else if (upperBound->variant() == VAR_REF) CheckVariable(st, upperBound, arrayToVariable, variableNumber); if (lowerBound->variant() == ARRAY_REF && lowerBound->symbol()->type()->baseType() && CheckConstIndexes(lowerBound->lhs())) { + boundCopy = st->copyPtr(); TransformBorder(st, lowerBound, arrayToVariable, variableNumber); st->expr(0)->setLhs(arrayToVariable[lowerBoundUnparsed]->copyPtr()); + expToChange[st->fileName()].push_back({ st , boundCopy });; + positionsToAdd.insert(declPlace); } else if (lowerBound->variant() == VAR_REF) CheckVariable(st, lowerBound, arrayToVariable, variableNumber); } } } - unordered_set funcStarts; - for (SgStatement* st : positionsToAdd) - { - SgStatement* scope = st->controlParent(); - if (scope) - funcStarts.insert(scope); - } - for (const auto& st : funcStarts) - { - SgFile::switchToFile(st->fileName()); - InsertCommonAndDeclsForFunction(st, variablesToAdd); - } + } + unordered_set funcStarts; + for (SgStatement* st : positionsToAdd) + { + SgFile::switchToFile(st->fileName()); + SgStatement* scope = st->controlParent(); + if (scope) + funcStarts.insert(scope); + } + for (const auto& st : funcStarts) + { + SgFile::switchToFile(st->fileName()); + InsertCommonAndDeclsForFunction(st, variablesToAdd); } } \ No newline at end of file diff --git a/src/ArrayConstantPropagation/propagation.h b/src/ArrayConstantPropagation/propagation.h index e2e76cd..f33523c 100644 --- a/src/ArrayConstantPropagation/propagation.h +++ b/src/ArrayConstantPropagation/propagation.h @@ -1,4 +1,20 @@ #pragma once #include "../Utils/SgUtils.h" +#include +#include + +using namespace std; + +struct ExprRestoreEntry +{ + enum Kind { kStatementExpr, kExprChild }; + Kind kind; + SgStatement* stmt; + int stmtExprIndex; + SgExpression* parent; + bool childIsRhs; + SgExpression* savedCopy; +}; + void ArrayConstantPropagation(SgProject& project); \ No newline at end of file diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index 95cb090..041c2bc 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -7,6 +7,7 @@ #include #include +#include "ArrayConstantPropagation/propagation.h" #include "CFGraph/CFGraph.h" #include "Distribution/Array.h" #include "graph_loops.h" @@ -21,6 +22,9 @@ using namespace std; extern std::map, std::pair> declaredArrays; +extern unordered_set statementsToRemove; +extern unordered_map>> expToChange; + static unordered_set collapsed; static void RemoveEmptyPoints(ArrayAccessingIndexes& container) @@ -458,4 +462,20 @@ void FindPrivateArrays(map>& loopGraph, mapfileName()); + st->deleteStmt(); + } + + for (auto& [filename, statements] : expToChange) + { + SgFile::switchToFile(filename); + for (auto& [statement, statementCopy] : statements) + { + statement->insertStmtBefore(*statementCopy, *statement->controlParent()); + statement->deleteStmt(); + } + } } \ No newline at end of file diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index 95b0e61..cd69c2f 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -318,7 +318,7 @@ void InitPassesDependencies(map> &passDepsIn, set list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE); - list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS); + list({ ARRAY_PROPAGATION, CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS); list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS); list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS); From 446f4d54d7288e81017a275a66d86335a0bbba18 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Fri, 10 Apr 2026 17:29:20 +0300 Subject: [PATCH 05/32] vesion updated --- src/Utils/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/version.h b/src/Utils/version.h index 207a063..3680f7f 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2473" +#define VERSION_SPF "2474" From 2d25a61ee7e99f491157f460de89df9c79772d8c Mon Sep 17 00:00:00 2001 From: ALEXks Date: Fri, 10 Apr 2026 20:09:50 +0300 Subject: [PATCH 06/32] fixed analysis of arrays with type character in function parameters --- src/GraphCall/graph_calls.cpp | 6 +++--- src/Utils/version.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/GraphCall/graph_calls.cpp b/src/GraphCall/graph_calls.cpp index 1ec24f9..1100366 100644 --- a/src/GraphCall/graph_calls.cpp +++ b/src/GraphCall/graph_calls.cpp @@ -723,7 +723,7 @@ static void fillIn(FuncInfo *currF, SgExpression *ex, const map &pa { if (ex) { - if (!isInFuncPar && (ex->variant() == VAR_REF || isArrayRef(ex))) + if (!isInFuncPar && (ex->variant() == VAR_REF || ex->variant() == ARRAY_REF)) { const char *name = ex->symbol()->identifier(); if (name && name != string("")) @@ -880,7 +880,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co for (auto ex = read->itemList(); ex; ex = ex->rhs()) { SgExpression* item = ex->lhs(); - if (item->variant() == VAR_REF || isArrayRef(item)) + if (item && (item->variant() == VAR_REF || item->variant() == ARRAY_REF)) { string symb = ""; if (item->symbol()) @@ -901,7 +901,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co if (item->rhs()) queue.push(item->rhs()); - if (item->variant() == VAR_REF || isArrayRef(item)) + if (item->variant() == VAR_REF || item->variant() == ARRAY_REF) { string symb = ""; if (item->symbol()) diff --git a/src/Utils/version.h b/src/Utils/version.h index 3680f7f..f4e1cca 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2474" +#define VERSION_SPF "2475" From b71df882fb1d37b49351535534fd9b134943eeae Mon Sep 17 00:00:00 2001 From: xnpster Date: Sun, 12 Apr 2026 15:32:09 +0300 Subject: [PATCH 07/32] REMOVE_DIST_ARRAYS_FROM_IO: fix type, add TODO --- .../ReplaceArraysInIO/replace_dist_arrays_in_io.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp index c40bdba..5ac5afe 100644 --- a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp +++ b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp @@ -504,7 +504,7 @@ static void replaceArrayInFragment(SgSymbol* replace_symb, } } -static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound) +static bool ioRegionBorder(SgStatement* stat, SgStatement* last_io_bound) { auto var = stat->variant(); @@ -535,8 +535,6 @@ static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound) if (last_io_bound && last_io_bound->lastNodeOfStmt() && last_io_bound->lastNodeOfStmt() == stat) return true; - int parent_var; - if (var == CONTROL_END && border_stats.find(stat->controlParent()->variant()) != border_stats.end()) return true; @@ -602,6 +600,7 @@ void replaceDistributedArraysInIO(vector& regions, auto var = curr_stmt->variant(); + // TODO: does not work with user regions if (var == PROC_HEDR || var == PROG_HEDR || var == FUNC_HEDR) { current_func_info = NULL; @@ -628,7 +627,7 @@ void replaceDistributedArraysInIO(vector& regions, break; } - if (ioReginBorder(curr_stmt, last_io_bound)) + if (ioRegionBorder(curr_stmt, last_io_bound)) { for (const auto& by_array_to_copy : need_replace) { From db5062c41663a6c157193581e19e7a96ee3a7ebe Mon Sep 17 00:00:00 2001 From: xnpster Date: Sun, 12 Apr 2026 15:32:09 +0300 Subject: [PATCH 08/32] REMOVE_DIST_ARRAYS_FROM_IO: find current FuncInfo properly --- .../replace_dist_arrays_in_io.cpp | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp index 5ac5afe..0989851 100644 --- a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp +++ b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp @@ -541,6 +541,18 @@ static bool ioRegionBorder(SgStatement* stat, SgStatement* last_io_bound) return false; } +FuncInfo* getCurrentFuncInfo(const vector& fileFuncInfo, int line) +{ + for (auto* func : fileFuncInfo) + { + if (func->linesNum.first <= line && line <= func->linesNum.second) + return func; + } + + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + return NULL; +} + void replaceDistributedArraysInIO(vector& regions, const map>& allFuncInfo, map>& SPF_messages, @@ -560,6 +572,8 @@ void replaceDistributedArraysInIO(vector& regions, if (SgFile::switchToFile(current_file_name) == -1) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + FuncInfo *current_func_info = NULL; + auto func_info_it = allFuncInfo.find(current_file_name); if (func_info_it == allFuncInfo.end()) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); @@ -586,13 +600,12 @@ void replaceDistributedArraysInIO(vector& regions, { curr_stmt = lines.stats.first->GetOriginal(); end = lines.stats.second->GetOriginal()->lexNext(); + current_func_info = getCurrentFuncInfo(func_info_it->second, curr_stmt->lineNumber()); } map> need_replace; SgStatement* last_io_bound = NULL; - FuncInfo *current_func_info = NULL; - while (curr_stmt != end) { if (!curr_stmt) @@ -600,21 +613,9 @@ void replaceDistributedArraysInIO(vector& regions, auto var = curr_stmt->variant(); - // TODO: does not work with user regions if (var == PROC_HEDR || var == PROG_HEDR || var == FUNC_HEDR) { - current_func_info = NULL; - for (auto *func_info : func_info_it->second) - { - if (func_info->funcName == curr_stmt->symbol()->identifier()) - { - current_func_info = func_info; - break; - } - } - - if (!current_func_info) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + current_func_info = getCurrentFuncInfo(func_info_it->second, curr_stmt->lineNumber()); curr_stmt = curr_stmt->lexNext(); while (curr_stmt && !isSgExecutableStatement(curr_stmt)) From a8ddc94734721ae4492b3256c51e19d1d6e46b0a Mon Sep 17 00:00:00 2001 From: ALEXks Date: Sun, 12 Apr 2026 20:16:23 +0300 Subject: [PATCH 09/32] version updated --- src/Utils/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/version.h b/src/Utils/version.h index f4e1cca..4eb8abe 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2475" +#define VERSION_SPF "2476" From e733d3d68a9ab21dd8a6c251dd9d8d3f567a3801 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Tue, 14 Apr 2026 11:47:59 +0300 Subject: [PATCH 10/32] improved and fixed transformAssumedSizeParameters function --- .../FunctionPurifying/function_purifying.cpp | 66 +++++++++++++++++-- src/Utils/version.h | 2 +- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/Transformations/FunctionPurifying/function_purifying.cpp b/src/Transformations/FunctionPurifying/function_purifying.cpp index 7c65db2..0e8b03e 100644 --- a/src/Transformations/FunctionPurifying/function_purifying.cpp +++ b/src/Transformations/FunctionPurifying/function_purifying.cpp @@ -234,9 +234,8 @@ static bool hasDvmParallel(SgStatement *func) return false; } -void transformAssumedSizeParameters(const map>& allFuncInfo) -{ - map> assumedSizeArraysByFunc; +static map createDvmParallelInfo(const map>& allFuncInfo) { + map hasDvmParallelMap; for (auto& funcByFile : allFuncInfo) { @@ -249,7 +248,63 @@ void transformAssumedSizeParameters(const map>& allFun if (prog == NULL) continue; - if (!hasDvmParallel(prog)) + hasDvmParallelMap[func] = hasDvmParallel(prog); + } + } + + bool changed = true; + while (changed) + { + changed = false; + + for (auto& funcByFile : allFuncInfo) + { + for (auto& func : funcByFile.second) + { + if (!hasDvmParallelMap[func]) + { + bool hasParallel = false; + for (auto& callF : func->callsFromV) + { + if (hasDvmParallelMap[callF]) + { + hasParallel = true; + break; + } + } + + if (hasParallel) + { + changed = true; + hasDvmParallelMap[func] = true; + } + + } + } + } + } + + return hasDvmParallelMap; +} + + +void transformAssumedSizeParameters(const map>& allFuncInfo) +{ + map> assumedSizeArraysByFunc; + const map hasDvmParallelMap = createDvmParallelInfo(allFuncInfo); + + for (auto& funcByFile : allFuncInfo) + { + if (SgFile::switchToFile(funcByFile.first) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + for (auto& func : funcByFile.second) + { + SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal()); + if (prog == NULL) + continue; + + if (!hasDvmParallelMap.at(func)) continue; vector parNames; @@ -259,7 +314,8 @@ void transformAssumedSizeParameters(const map>& allFun bool hasRefs = false; for (int z = 0; z < func->funcParams.countOfPars; ++z) { - if (func->funcParams.parametersT[z] == ARRAY_T) + if (func->funcParams.parametersT[z] == ARRAY_T || + func->funcParams.parametersT[z] == STRING_ARRAY_T) { auto s = prog->parameter(z); const string name = s->identifier(); diff --git a/src/Utils/version.h b/src/Utils/version.h index 4eb8abe..e8531ab 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2476" +#define VERSION_SPF "2477" From b87b18615d4aaabb8e6bce9c38890ec3e8b57e3c Mon Sep 17 00:00:00 2001 From: ALEXks Date: Tue, 14 Apr 2026 16:44:06 +0300 Subject: [PATCH 11/32] fixed DCLARE analysis --- src/DvmhRegions/DvmhRegionInserter.cpp | 3 +++ src/Sapfor.cpp | 2 +- src/Utils/version.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/DvmhRegions/DvmhRegionInserter.cpp b/src/DvmhRegions/DvmhRegionInserter.cpp index 002f40b..5777280 100644 --- a/src/DvmhRegions/DvmhRegionInserter.cpp +++ b/src/DvmhRegions/DvmhRegionInserter.cpp @@ -1289,6 +1289,9 @@ static set SgStatement* declStat = NULL; + if (realArray->GetLocation().first == DIST::l_PARAMETER) + continue; + if (realArray->GetLocation().first == DIST::l_COMMON) { commonArrays.insert(realArray); diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index a25ea29..8ba8b92 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -741,7 +741,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne else if (curr_regime == LOOP_DATA_DEPENDENCIES) doDependenceAnalysisOnTheFullFile(file, 1, 1, 1); else if (curr_regime == REMOVE_DVM_DIRS || curr_regime == REMOVE_DVM_DIRS_TO_COMMENTS || curr_regime == REMOVE_SPF_DIRS) { - bool removeDvm = (curr_regime == REMOVE_DVM_DIRS || curr_regime == REMOVE_DVM_DIRS); + bool removeDvm = (curr_regime == REMOVE_DVM_DIRS); bool removeSpf = (curr_regime == REMOVE_SPF_DIRS); bool toComment = (curr_regime == REMOVE_DVM_DIRS_TO_COMMENTS); removeDvmSpfDirectives(file, removeDvm, removeSpf, toComment); diff --git a/src/Utils/version.h b/src/Utils/version.h index e8531ab..b895678 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2477" +#define VERSION_SPF "2478" From 54e83e194d43376f562d34d267792b5f97553dba Mon Sep 17 00:00:00 2001 From: ALEXks Date: Sat, 18 Apr 2026 20:33:30 +0300 Subject: [PATCH 12/32] added IPA to complete the formation of names of parallelization regions --- src/ParallelizationRegions/ParRegions.cpp | 62 ++++++++++++++++++++ src/ParallelizationRegions/ParRegions_func.h | 4 ++ src/Sapfor.cpp | 25 ++------ src/Utils/version.h | 2 +- 4 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src/ParallelizationRegions/ParRegions.cpp b/src/ParallelizationRegions/ParRegions.cpp index a05d827..b27531b 100644 --- a/src/ParallelizationRegions/ParRegions.cpp +++ b/src/ParallelizationRegions/ParRegions.cpp @@ -24,6 +24,7 @@ using std::make_pair; using std::map; using std::set; using std::wstring; +using std::tuple; extern void createMapLoopGraph(map &sortedLoopGraph, const vector *loopGraph); @@ -954,4 +955,65 @@ void calculateLinesOfCode(vector &allRegions) __spf_print(1, " Count of lines in region '%s' = %d\n", elem->GetName().c_str(), lineCounter); } +} + +void propagateRegionInfo(map, pair>& declaredArrays, + const map>& arrayLinksByFuncCalls, + const vector ¶llelRegions) +{ + bool modified = true; + while (modified) + { + modified = false; + + for (auto &array_pair: declaredArrays) + { + auto array = array_pair.second.first; + if (array->GetLocation().first == DIST::l_PARAMETER) + { + set realArrayRef; + getAllArrayRefs(array, array, realArrayRef, arrayLinksByFuncCalls); + + auto regs = array->GetRegionsName(); + for (auto& ref : realArrayRef) + { + auto regsRef = ref->GetRegionsName(); + for (auto& reg : regsRef) + { + if (regs.count(reg) == 0) + { + array->SetRegionPlace(reg); + modified = true; + } + } + + } + } + } + } + + bool hasNonDefaultReg = false; + for (auto& elem : parallelRegions) + { + string regName = elem->GetName(); + convertToLower(regName); + if (regName != "default") + hasNonDefaultReg = true; + } + + if (hasNonDefaultReg) + { + for (auto array : declaredArrays) + { + if (array.second.first->GetRegionsName().size() == 0) + array.second.first->SetDistributeFlag(DIST::NO_DISTR); + else if (array.second.first->GetRegionsName().size() == 1) + { + string regName = *array.second.first->GetRegionsName().begin(); + convertToLower(regName); + if (regName == "default") + array.second.first->SetDistributeFlag(DIST::NO_DISTR); + } + } + } } \ No newline at end of file diff --git a/src/ParallelizationRegions/ParRegions_func.h b/src/ParallelizationRegions/ParRegions_func.h index d1ac9b8..1cc15df 100644 --- a/src/ParallelizationRegions/ParRegions_func.h +++ b/src/ParallelizationRegions/ParRegions_func.h @@ -10,3 +10,7 @@ int printParalleRegions(const char *fileName, std::vector ®i bool buildGraphFromUserDirectives(const std::vector &userDvmAlignDirs, DIST::GraphCSR &G, DIST::Arrays &allArrays, const std::map> &arrayLinksByFuncCalls, const std::set& alignedArrays, std::set& addedArrays, const std::map>& funcsByFile); void clearRegionStaticData(); void calculateLinesOfCode(std::vector &allRegions); + +void propagateRegionInfo(std::map, std::pair>& declaredArrays, + const std::map>& arrayLinksByFuncCall, + const std::vector& parallelRegions); diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index 8ba8b92..a78cb70 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1264,6 +1264,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne moveAllocatesInterproc(arrayLinksByFuncCalls); + propagateRegionInfo(declaredArrays, arrayLinksByFuncCalls, subs_parallelRegions); + removeDistrStateFromDeadFunctions(allFuncInfo, declaredArrays); propagateArrayFlags(arrayLinksByFuncCalls, declaredArrays, SPF_messages); } @@ -1681,30 +1683,11 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne findDeadFunctionsAndFillCalls(allFuncInfo_IR, SPF_messages, true); else if (curr_regime == GET_ALL_ARRAY_DECL) { - bool hasNonDefaultReg = false; - for (auto &elem : subs_parallelRegions) - if (elem->GetName() != "DEFAULT") - hasNonDefaultReg = true; - - if (hasNonDefaultReg) + if (ignoreArrayDistributeState) { - for (auto array : declaredArrays) - { - if (array.second.first->GetRegionsName().size() == 0) - array.second.first->SetDistributeFlag(DIST::NO_DISTR); - else if (array.second.first->GetRegionsName().size() == 1) - { - string regName = *array.second.first->GetRegionsName().begin(); - convertToLower(regName); - if (regName == "default") - array.second.first->SetDistributeFlag(DIST::NO_DISTR); - } - } - } - - if (ignoreArrayDistributeState) for (auto array : declaredArrays) array.second.first->SetDistributeFlag(DIST::NO_DISTR); + } } else if (curr_regime == GCOV_PARSER) { diff --git a/src/Utils/version.h b/src/Utils/version.h index b895678..c4c9c11 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2478" +#define VERSION_SPF "2479" From d0712d1241854fa6571732202c99e3979910fedd Mon Sep 17 00:00:00 2001 From: xnpster Date: Sun, 19 Apr 2026 18:32:49 +0300 Subject: [PATCH 13/32] draft of parallel regions merging pass --- CMakeLists.txt | 4 + .../parse_merge_dirs.cpp | 567 ++++++++++++++++++ src/ParallelizationRegions/parse_merge_dirs.h | 8 + src/Sapfor.cpp | 6 + src/Sapfor.h | 3 + src/Utils/PassManager.h | 1 + 6 files changed, 589 insertions(+) create mode 100644 src/ParallelizationRegions/parse_merge_dirs.cpp create mode 100644 src/ParallelizationRegions/parse_merge_dirs.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 12e61a7..1af5c52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,6 +166,8 @@ set(PARALLEL_REG src/ParallelizationRegions/ParRegions.cpp set(ARRAY_PROP src/ArrayConstantPropagation/propagation.cpp src/ArrayConstantPropagation/propagation.h ) +set(MERGE_COPY_ARRAYS src/ParallelizationRegions/parse_merge_dirs.cpp + src/ParallelizationRegions/parse_merge_dirs.h) set(TR_DEAD_CODE src/Transformations/DeadCodeRemoving/dead_code.cpp src/Transformations/DeadCodeRemoving/dead_code.h) @@ -426,6 +428,7 @@ set(SOURCE_EXE ${LOOP_ANALYZER} ${TRANSFORMS} ${PARALLEL_REG} + ${MERGE_COPY_ARRAYS} ${PRIV} ${ARRAY_PROP} ${FDVM} @@ -479,6 +482,7 @@ source_group (GraphCall FILES ${GR_CALL}) source_group (GraphLoop FILES ${GR_LOOP}) source_group (LoopAnalyzer FILES ${LOOP_ANALYZER}) source_group (ParallelizationRegions FILES ${PARALLEL_REG}) +source_group (MergeCopyArrays FILES ${MERGE_COPY_ARRAYS}) source_group (PrivateAnalyzer FILES ${PRIV}) source_group (ArrayConstantPropagation FILES ${ARRAY_PROP}) source_group (FDVM_Compiler FILES ${FDVM}) diff --git a/src/ParallelizationRegions/parse_merge_dirs.cpp b/src/ParallelizationRegions/parse_merge_dirs.cpp new file mode 100644 index 0000000..1701427 --- /dev/null +++ b/src/ParallelizationRegions/parse_merge_dirs.cpp @@ -0,0 +1,567 @@ +#include "parse_merge_dirs.h" + +#include + +using std::map; +using std::pair; +using std::string; +using std::unordered_map; +using std::unordered_set; +using std::vector; + +static void parseMergeDirective(const char *comment, + vector> &parsed_mapping) +{ + while (comment) + { + auto *line_end = strchr(comment, '\n'); + + static const char prefix[] = "!!SPF TRANSFORM(MERGE_ARRAYS("; + static const auto compare_chars = sizeof(prefix) - 1; + + if (strncasecmp(comment, prefix, compare_chars) == 0) + { + auto *pair_start = comment + compare_chars; + auto *comma = strchr(pair_start, ','); + if (comma) + { + auto *close_br = strchr(comma + 1, ')'); + if (close_br) + { + parsed_mapping.emplace_back( + string(pair_start, comma - pair_start), + string(comma + 1, close_br - comma - 1)); + } + } + } + + comment = line_end; + + if (comment) + comment++; + } +} + +static string getNonDefaultRegion(DIST::Array *a) +{ + string result; + + if (!a) + return result; + + for (const auto ®_name : a->GetRegionsName()) + { + if (reg_name != "default") + { + if (!result.empty()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + result = reg_name; + } + } + + return result; +} + +static bool hasSameSizes(DIST::Array *a, DIST::Array *b) +{ + for (auto *array : {a, b}) + { + for (const auto &p : array->GetSizes()) + { + if (p.first < 0 || p.second < 0) + return false; + } + } + + return a->GetSizes() == b->GetSizes() && a->GetTypeSize() == b->GetTypeSize(); +} + +static bool checkSimilarTemplates(vector ®ions, + const unordered_map &new_region_mapping) +{ + // new region -> old regions + unordered_map> new_region_inverse_mapping; + for (const auto &p : new_region_mapping) + new_region_inverse_mapping[p.second].insert(p.first); + + for (const auto &new_reg : new_region_inverse_mapping) + { + DIST::Array *template_array = nullptr; + string first_reg_name; + + for (const auto &old_region_name : new_reg.second) + { + auto *old_reg = getRegionByName(regions, old_region_name); + + if (!old_reg) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + const auto &distr_rules = old_reg->GetDataDir().GetDistrRules(); + if (distr_rules.size() != 1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + auto *current_template = distr_rules.front().first; + + if (template_array) + { + if (!hasSameSizes(template_array, current_template)) + { + __spf_print(1, "Templates of %s and %s has different sizes\n", + first_reg_name.c_str(), + old_region_name.c_str()); + + return false; + } + // else everything OK + } + else + { + template_array = current_template; + first_reg_name = old_region_name; + } + } + } + + return true; +} + +static bool hasSameAlignment(const std::unordered_set &align_a, + const std::unordered_set &align_b) +{ + if (align_a.size() != 1 || align_b.size() != 1) + return false; + + const auto *rule_a = *align_a.begin(); + const auto *rule_b = *align_b.begin(); + + if (rule_a->alignRule != rule_b->alignRule) + return false; + + return true; +} + +static void printExpr(SgExpression *e, string pad) +{ + if (!e) + return; + + __spf_print(1, "%s%d: %s\n", pad.c_str(), e->variant(), e->unparse()); + + printExpr(e->lhs(), pad + " "); + printExpr(e->rhs(), pad + " "); +} + +static pair, SgSymbol *> generateDeclaration(const string &array_name, const string &common_block_name, + const vector> &sizes, SgType *type, SgStatement *scope) +{ + auto *array_symbol = new SgSymbol(VARIABLE_NAME, array_name.c_str(), new SgType(T_ARRAY), scope); + + auto *decl = new SgDeclarationStatement(VAR_DECL); + + decl->setExpression(1, new SgTypeExp(*type)); + + SgExpression *subs = new SgExprListExp(); + + auto *array_ref = new SgArrayRefExp(*array_symbol, *subs); + + for (int i = 0; i < sizes.size(); i++) + { + const auto &p = sizes[i]; + auto *d = new SgExpression(DDOT, new SgValueExp(p.first), new SgValueExp(p.second)); + subs->setLhs(d); + + if (i + 1 < sizes.size()) + { + subs->setRhs(new SgExprListExp()); + subs = subs->rhs(); + } + } + + decl->setExpression(0, array_ref); + + auto comm = new SgStatement(COMM_STAT); + + comm->setExpression(0, new SgExpression(COMM_LIST, + new SgVarRefExp(array_symbol), + NULL, + new SgSymbol(COMMON_NAME, common_block_name.c_str()))); + + return {{decl, comm}, array_symbol}; +} + +SgSymbol *insertDeclIfNeeded(const string &array_name, + const string &common_block_name, + DIST::Array *example_array, + FuncInfo *dest, + unordered_map> &inserted_arrays) +{ + if (SgFile::switchToFile(dest->fileName) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + auto &by_func = inserted_arrays[dest]; + auto it = by_func.find(array_name); + + if (it != by_func.end()) + return it->second; + + SgStatement *st = dest->funcPointer; + + auto *end = st->lastNodeOfStmt(); + + st = st->lexNext(); + + while (st != end && !isSgExecutableStatement(st)) + { + st = st->lexNext(); + } + + auto generated = generateDeclaration(array_name, common_block_name, + example_array->GetSizes(), + SgTypeInt(), dest->funcPointer); + for (auto *new_stmt : generated.first) + st->insertStmtBefore(*new_stmt, *dest->funcPointer); + + by_func[array_name] = generated.second; + + return generated.second; +} + +static pair createNewArray(DIST::Array *example_array, const string &base_name, + const map> &allFuncInfo, + unordered_map> &inserted_arrays) +{ + auto common_block_name = base_name + "_merge_cb"; + auto array_name = base_name; + + for (const auto &by_file : allFuncInfo) + { + for (auto *func_info : by_file.second) + { + if (func_info->isMain) + { + insertDeclIfNeeded( + array_name, + common_block_name, + example_array, + func_info, + inserted_arrays); + } + } + } + + return std::make_pair(array_name, common_block_name); +} + +static void replaceArrayRec(SgExpression *e, + const unordered_set &arrays_to_replace, + SgSymbol **func_symbol_hint, + const pair &replace_by, + DIST::Array *example_array, + FuncInfo *func, + unordered_map> &inserted_arrays) +{ + if (!e) + return; + + if (isArrayRef(e) && arrays_to_replace.find(e->symbol()->identifier()) != arrays_to_replace.end()) + { + if (!(*func_symbol_hint)) + { + *func_symbol_hint = insertDeclIfNeeded( + replace_by.first, replace_by.second, + example_array, + func, + inserted_arrays); + } + + e->setSymbol(*func_symbol_hint); + } + + replaceArrayRec( + e->lhs(), + arrays_to_replace, + func_symbol_hint, + replace_by, + example_array, + func, + inserted_arrays); + + replaceArrayRec( + e->rhs(), + arrays_to_replace, + func_symbol_hint, + replace_by, + example_array, + func, + inserted_arrays); +} + +static void replaceRegion(SgStatement* st, const unordered_map &new_region_mapping) +{ + if (!st) + return; + + if(isSPF_stat(st) && st->variant() == SPF_PARALLEL_REG_DIR) + { + auto it = new_region_mapping.find(st->symbol()->identifier()); + + if (it != new_region_mapping.end()) + st->setSymbol(*(new SgSymbol(CONST_NAME, it->second.c_str()))); + } +} + +void mergeCopyArrays(vector ®ions, const map> &allFuncInfo) +{ + for (const auto *region : regions) + { + __spf_print(1, "region %s\n", region->GetName().c_str()); + + const auto &dirs = region->GetDataDir(); + + __spf_print(1, " distr rules: %d\n", dirs.distrRules.size()); + + const auto ¤tVariant = region->GetCurrentVariant(); + + int distr_idx = 0; + for (const auto &distr : dirs.distrRules) + { + const auto &dist_rule = distr.second.back().distRule; + + string sizes; + for (const auto &p : distr.first->GetSizes()) + { + if (!sizes.empty()) + sizes.push_back(','); + + sizes += std::to_string(p.first) + ":" + std::to_string(p.second); + } + + __spf_print(1, " DIST %s(%s)", distr.first->GetName().c_str(), sizes.c_str()); + for (const auto &dim : dist_rule) + __spf_print(1, " %c", dim == dist::BLOCK ? 'B' : '*'); + + __spf_print(1, "\n"); + distr_idx++; + } + + __spf_print(1, " align rules: %d\n", dirs.alignRules.size()); + + for (const auto &align : dirs.alignRules) + { + string sub_a, sub_b; + + int i = 0; + for (const auto coefs : align.alignRule) + { + if (!sub_a.empty()) + sub_a.push_back(','); + + sub_a += std::to_string(coefs.first) + "*i" + + std::to_string(i) + "+" + std::to_string(coefs.second); + + i++; + } + + for (const auto coefs : align.alignRuleWith) + { + if (!sub_b.empty()) + sub_b.push_back(','); + + sub_b += std::to_string(coefs.second.first) + "*i" + + std::to_string(coefs.first) + "+" + std::to_string(coefs.second.second); + } + + __spf_print(1, " ALIGN %s(%s) WITH %s(%s)\n", + align.alignArray->GetName().c_str(), sub_a.c_str(), + align.alignWith->GetName().c_str(), sub_b.c_str()); + } + } + + // parse directives + + // new array name -> current arrays + unordered_map> arrays_to_merge; + unordered_map> array_alignment; + + for (const auto &by_file : allFuncInfo) + { + const auto current_file_name = by_file.first; + + if (SgFile::switchToFile(current_file_name) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + for (auto *func_info : by_file.second) + { + SgStatement *curr_stmt = func_info->funcPointer; + if (!curr_stmt) + continue; + + auto *stmt_end = curr_stmt->lastDeclaration(); + if (!stmt_end) + continue; + + stmt_end = stmt_end->lexNext(); + + for (; curr_stmt && curr_stmt != stmt_end; curr_stmt = curr_stmt->lexNext()) + { + if (curr_stmt->comments()) + { + vector> parsed_mapping; + parseMergeDirective(curr_stmt->comments(), parsed_mapping); + + for (const auto &p : parsed_mapping) + { + auto *found_array = getArrayFromDeclarated(curr_stmt, p.first); + if (found_array) + { + arrays_to_merge[p.second].insert(found_array); + array_alignment[found_array] = {}; + } + } + } + } + } + } + + // find alignment rules for array + + for (const auto *region : regions) + { + const auto &dirs = region->GetDataDir(); + + for (const auto &align : dirs.alignRules) + { + auto it = array_alignment.find(align.alignArray); + + if (it != array_alignment.end()) + it->second.insert(&align); + } + } + + // old region -> new region + unordered_map new_region_mapping; + + // new array -> new region + unordered_map arrays_new_region_mapping; + vector created_region_names; + + for (const auto &by_new_array : arrays_to_merge) + { + string new_region_name; + for (auto *current_array : by_new_array.second) + { + auto current_array_region = getNonDefaultRegion(current_array); + auto it = new_region_mapping.find(current_array_region); + if (it != new_region_mapping.end()) + { + if (new_region_name.empty()) + new_region_name = it->second; + else if (new_region_name != it->second) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + } + + if (new_region_name.empty()) + { + new_region_name = "merged_reg_" + std::to_string(created_region_names.size()); + created_region_names.push_back(new_region_name); + } + + for (auto *current_array : by_new_array.second) + { + auto current_array_region = getNonDefaultRegion(current_array); + new_region_mapping[current_array_region] = new_region_name; + } + + arrays_new_region_mapping[by_new_array.first] = new_region_name; + } + + if (!checkSimilarTemplates(regions, new_region_mapping)) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + unordered_map> inserted_arrays; + + for (const auto &by_dest_array : arrays_to_merge) + { + const auto ©_arrays = by_dest_array.second; + + if (copy_arrays.empty()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + auto *first_element = *copy_arrays.begin(); + auto first_elem_rules_it = array_alignment.find(first_element); + + if (first_elem_rules_it == array_alignment.end()) + continue; + + const auto &first_elem_rules = first_elem_rules_it->second; + + for (auto *array_to_merge : copy_arrays) + { + auto array_rules_it = array_alignment.find(array_to_merge); + + if (array_rules_it == array_alignment.end()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + const auto &array_rules = array_rules_it->second; + + if (!hasSameSizes(array_to_merge, first_element) || !hasSameAlignment(first_elem_rules, array_rules)) + { + __spf_print(1, "Arrays %s and %s has different sizes or align rules\n", + array_to_merge->GetName().c_str(), + first_element->GetName().c_str()); + + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + } + + __spf_print(1, "merge into %s (%s):\n", by_dest_array.first.c_str(), arrays_new_region_mapping[by_dest_array.first].c_str()); + for (auto *array_to_merge : copy_arrays) + __spf_print(1, "%s\n", array_to_merge->GetName().c_str()); + + auto created_array_info = createNewArray(first_element, by_dest_array.first, allFuncInfo, inserted_arrays); + + unordered_set arrays_to_replace; + for (auto *array_to_merge : copy_arrays) + arrays_to_replace.insert(array_to_merge->GetShortName()); + + for (const auto &by_file : allFuncInfo) + { + if (SgFile::switchToFile(by_file.first) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + for (auto *func_info : by_file.second) + { + SgSymbol *func_symbol_hint = nullptr; + SgStatement *st = func_info->funcPointer; + + auto *func_end = st->lastNodeOfStmt(); + + st = st->lexNext(); + + while (st && !isSgExecutableStatement(st) && st != func_end) + st = st->lexNext(); + + while (st && st != func_end) + { + for (int i = 0; i < 3; i++) + { + replaceArrayRec( + st->expr(i), + arrays_to_replace, + &func_symbol_hint, + created_array_info, + first_element, + func_info, + inserted_arrays); + } + + replaceRegion(st, new_region_mapping); + + st = st->lexNext(); + } + } + } + } +} \ No newline at end of file diff --git a/src/ParallelizationRegions/parse_merge_dirs.h b/src/ParallelizationRegions/parse_merge_dirs.h new file mode 100644 index 0000000..54c2287 --- /dev/null +++ b/src/ParallelizationRegions/parse_merge_dirs.h @@ -0,0 +1,8 @@ +#include "../GraphCall/graph_calls.h" +#include "ParRegions.h" + +#include +#include +#include + +void mergeCopyArrays(std::vector ®ions, const std::map> &allFuncInfo); \ No newline at end of file diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index a78cb70..1fda4b0 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -23,6 +23,7 @@ #include "ParallelizationRegions/ParRegions_func.h" #include "ParallelizationRegions/resolve_par_reg_conflicts.h" #include "ParallelizationRegions/expand_extract_reg.h" +#include "ParallelizationRegions/parse_merge_dirs.h" #include "Distribution/Distribution.h" #include "Distribution/GraphCSR.h" @@ -1905,6 +1906,10 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne transformAssumedSizeParameters(allFuncInfo); else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS) FindPrivateArrays(loopGraph, fullIR, insertedPrivates); + else if (curr_regime == MERGE_COPY_ARRAYS) + { + mergeCopyArrays(parallelRegions, allFuncInfo); + } else if (curr_regime == ARRAY_PROPAGATION) ArrayConstantPropagation(project); @@ -2362,6 +2367,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam case FIX_COMMON_BLOCKS: case TEST_PASS: case SET_IMPLICIT_NONE: + case MERGE_COPY_ARRAYS: runAnalysis(*project, curr_regime, false); case SUBST_EXPR_RD_AND_UNPARSE: case SUBST_EXPR_AND_UNPARSE: diff --git a/src/Sapfor.h b/src/Sapfor.h index f5dadd1..3ad7cb8 100644 --- a/src/Sapfor.h +++ b/src/Sapfor.h @@ -88,6 +88,8 @@ enum passes { REMOVE_DVM_INTERVALS, VERIFY_DVM_DIRS, + MERGE_COPY_ARRAYS, + REMOVE_DIST_ARRAYS_FROM_IO, SUBST_EXPR, @@ -273,6 +275,7 @@ static void setPassValues() passNames[VERIFY_DVM_DIRS] = "VERIFY_DVM_DIRS"; passNames[REMOVE_DVM_DIRS_TO_COMMENTS] = "REMOVE_DVM_DIRS_TO_COMMENTS"; passNames[REMOVE_SPF_DIRS] = "REMOVE_SPF_DIRS"; + passNames[MERGE_COPY_ARRAYS] = "MERGE_COPY_ARRAYS"; passNames[REMOVE_DIST_ARRAYS_FROM_IO] = "REMOVE_DIST_ARRAYS_FROM_IO"; passNames[SUBST_EXPR] = "SUBST_EXPR"; passNames[SUBST_EXPR_RD] = "SUBST_EXPR_RD"; diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index cd69c2f..caefa14 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -322,6 +322,7 @@ void InitPassesDependencies(map> &passDepsIn, set list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS); list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS); + Pass(CREATE_TEMPLATE_LINKS) <= Pass(MERGE_COPY_ARRAYS); passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS, EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW, From bafd8a8f486a53cede8c3c52c3de44d522070765 Mon Sep 17 00:00:00 2001 From: xnpster Date: Sun, 19 Apr 2026 18:32:50 +0300 Subject: [PATCH 14/32] region merging: derive array types --- .../parse_merge_dirs.cpp | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/ParallelizationRegions/parse_merge_dirs.cpp b/src/ParallelizationRegions/parse_merge_dirs.cpp index 1701427..512a8a2 100644 --- a/src/ParallelizationRegions/parse_merge_dirs.cpp +++ b/src/ParallelizationRegions/parse_merge_dirs.cpp @@ -190,12 +190,61 @@ static pair, SgSymbol *> generateDeclaration(const string return {{decl, comm}, array_symbol}; } +static SgExpression* findExprWithVariant(SgExpression* exp, int variant) +{ + if (exp) + { + if (exp->variant() == variant) + return exp; + + auto *l = findExprWithVariant(exp->lhs(), variant); + if (l) + return l; + + auto *r = findExprWithVariant(exp->rhs(), variant); + if (r) + return r; + } + + return NULL; +} + +SgType* GetArrayType(DIST::Array *array) +{ + if (!array) + return NULL; + + for (const auto& decl_place : array->GetDeclInfo()) + { + if (SgFile::switchToFile(decl_place.first) != -1) + { + auto* decl = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second); + if (decl) + { + for (int i = 0; i < 3; i++) + { + auto* found_type = isSgTypeExp(findExprWithVariant(decl->expr(i), TYPE_OP)); + if (found_type) + return found_type->type(); + } + } + } + } + + return NULL; +} + SgSymbol *insertDeclIfNeeded(const string &array_name, const string &common_block_name, DIST::Array *example_array, FuncInfo *dest, unordered_map> &inserted_arrays) { + auto *type = GetArrayType(example_array); + + if (!type) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + if (SgFile::switchToFile(dest->fileName) == -1) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); @@ -218,7 +267,7 @@ SgSymbol *insertDeclIfNeeded(const string &array_name, auto generated = generateDeclaration(array_name, common_block_name, example_array->GetSizes(), - SgTypeInt(), dest->funcPointer); + type, dest->funcPointer); for (auto *new_stmt : generated.first) st->insertStmtBefore(*new_stmt, *dest->funcPointer); From f43247b6da66bba9b346d078dad03e4d469b130d Mon Sep 17 00:00:00 2001 From: xnpster Date: Sun, 19 Apr 2026 18:32:50 +0300 Subject: [PATCH 15/32] resolve_par_reg_conflicts: generate unique names, region merging: generate common blocks with _c suffix --- .../parse_merge_dirs.cpp | 2 +- .../resolve_par_reg_conflicts.cpp | 145 +++++++++++++++--- 2 files changed, 126 insertions(+), 21 deletions(-) diff --git a/src/ParallelizationRegions/parse_merge_dirs.cpp b/src/ParallelizationRegions/parse_merge_dirs.cpp index 512a8a2..b7cae96 100644 --- a/src/ParallelizationRegions/parse_merge_dirs.cpp +++ b/src/ParallelizationRegions/parse_merge_dirs.cpp @@ -280,7 +280,7 @@ static pair createNewArray(DIST::Array *example_array, const str const map> &allFuncInfo, unordered_map> &inserted_arrays) { - auto common_block_name = base_name + "_merge_cb"; + auto common_block_name = base_name + "_merge_r"; auto array_name = base_name; for (const auto &by_file : allFuncInfo) diff --git a/src/ParallelizationRegions/resolve_par_reg_conflicts.cpp b/src/ParallelizationRegions/resolve_par_reg_conflicts.cpp index 0f2e922..87b3e19 100644 --- a/src/ParallelizationRegions/resolve_par_reg_conflicts.cpp +++ b/src/ParallelizationRegions/resolve_par_reg_conflicts.cpp @@ -4,7 +4,9 @@ #include #include #include +#include #include +#include #include #include @@ -23,6 +25,8 @@ using std::map; using std::pair; using std::set; +using std::unordered_set; +using std::unordered_map; using std::vector; using std::stack; using std::string; @@ -30,6 +34,9 @@ using std::wstring; using std::to_string; using std::make_pair; +static const string COMMON_ARRAY_SUFFIX = "_c"; +static const string COMMON_BLOCK_SUFFIX = "_r"; + static inline int getRegionExplicitLine(SgStatement *startR) { checkNull(startR, convertFileName(__FILE__).c_str(), __LINE__); @@ -106,6 +113,103 @@ static const vector getArraySynonyms(DIST::Array *array) return arrayBlock->second->getVariables(pos); } +class UniqueNameCreator +{ + map> func_info; + unordered_set all_declarations; + bool declarations_analyzed = false; + unordered_map> generated_names; + + static void GetSymbolsRec(SgExpression* exp, unordered_set& add_to) + { + if (!exp) + return; + + if (isArrayRef(exp) && exp->symbol() && exp->symbol()->identifier()) + add_to.emplace(exp->symbol()->identifier()); + + GetSymbolsRec(exp->lhs(), add_to); + GetSymbolsRec(exp->rhs(), add_to); + } + + void FillDeclarations() + { + all_declarations.clear(); + + auto* file_before = current_file; + + for (const auto& by_file : func_info) + { + if (SgFile::switchToFile(by_file.first) != -1) + { + for (const auto* by_func : by_file.second) + { + SgStatement* st = by_func->funcPointer; + + if (st) + st = st->lexNext(); + + while (st) + { + for (int i = 0; i < 3; i++) + GetSymbolsRec(st->expr(i), all_declarations); + + st = st->lexNext(); + } + } + } + } + + SgFile::switchToFile(file_before->filename()); + declarations_analyzed = true; + } +public: + UniqueNameCreator(const map> &allFuncInfo) + { + declarations_analyzed = false; + func_info = allFuncInfo; + } + + void GetUniqueName(DIST::Array* array, string& array_name, string& common_block_name) + { + auto varsOnPos = getArraySynonyms(array); + if (!varsOnPos.size()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + auto array_plain_name = varsOnPos[0]->getName(); + + auto it = generated_names.find(array); + if (it != generated_names.end()) + { + array_name.assign(it->second.first); + common_block_name.assign(it->second.second); + return; + } + + if (!declarations_analyzed) + FillDeclarations(); + + int v = 1; + auto created_array_name = array_plain_name + COMMON_ARRAY_SUFFIX; + auto created_common_name = array_plain_name + COMMON_BLOCK_SUFFIX; + + while (all_declarations.find(created_array_name) != all_declarations.end() || + all_declarations.find(created_common_name) != all_declarations.end()) + { + created_array_name = array_plain_name + "_v" + std::to_string(v) + COMMON_ARRAY_SUFFIX; + created_common_name = array_plain_name + "_v" + std::to_string(v) + COMMON_BLOCK_SUFFIX; + v++; + } + + all_declarations.insert(created_array_name); + all_declarations.insert(created_common_name); + generated_names.emplace(array, std::make_pair(created_array_name, created_common_name)); + + array_name.assign(created_array_name); + common_block_name.assign(created_common_name); + } +}; + static string getStringDeclaration(SgSymbol *symb) { string decl; @@ -127,15 +231,16 @@ static string getStringDeclaration(SgSymbol *symb) return decl; } -static void insertStringDeclarations(SgStatement *insertPlace, DIST::Array *array) +static void insertStringDeclarations(SgStatement *insertPlace, DIST::Array *array, UniqueNameCreator& unique_name_creator) { auto varsOnPos = getArraySynonyms(array); if (varsOnPos.size() && varsOnPos[0]->getName() == array->GetShortName()) { + string newArrName, commName; + unique_name_creator.GetUniqueName(array, newArrName, commName); SgSymbol *varSymb = varsOnPos[0]->getSymbol(); string varName = varSymb->identifier(); - string newName = varName + "_c"; - varSymb->changeName(newName.c_str()); + varSymb->changeName(newArrName.c_str()); string decl = getStringDeclaration(varsOnPos[0]->getSymbol()); varSymb->changeName(varName.c_str()); insertPlace->addComment(decl.c_str()); @@ -662,12 +767,11 @@ static void replaceFuncCalls(const ParallelRegionLines &lines, const map> createdCommonBlocks; // file -> array -> new common statement static map>> createdCommonArrays; // file -> array -> (orig, copy) -static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array) +static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array, UniqueNameCreator& unique_name_creator) { - auto varsOnPos = getArraySynonyms(array); - if (!varsOnPos.size()) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + string newArrName, commBlockName; + unique_name_creator.GetUniqueName(array, newArrName, commBlockName); string fileName = file->filename(); if (SgFile::switchToFile(fileName) != -1) @@ -683,7 +787,6 @@ static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array) // creating new common-block statement //TODO: consistence with declaration //string commBlockName = checkSymbNameAndCorrect(array->GetShortName() + "_r"); - string commBlockName = array->GetShortName() + "_r"; SgStatement *commDecl = new SgStatement(COMM_STAT); SgSymbol *commSymb = new SgSymbol(VARIABLE_NAME, commBlockName.c_str()); @@ -705,7 +808,6 @@ static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array) { //TODO: consistence with declaration //string newArrName = checkSymbNameAndCorrect(varsOnPos[0]->getName() + "_c"); - string newArrName = varsOnPos[0]->getName() + "_c"; newArrSymb = new SgSymbol(VARIABLE_NAME, newArrName.c_str(), file->firstStatement()); SgType *type = new SgType(T_ARRAY); @@ -751,7 +853,7 @@ static SgStatement* createCommonBlock(SgFile *file, DIST::Array *array) // func -> arrays; funcs where new common statement inserted static map> insertedCommonBlocks; -static void insertCommonBlock(FuncInfo *func, DIST::Array *array) +static void insertCommonBlock(FuncInfo *func, DIST::Array *array, UniqueNameCreator& unique_name_creator) { SgFile *file = func->funcPointer->GetOriginal()->getFile(); SgStatement *insertPlace = NULL; @@ -767,7 +869,7 @@ static void insertCommonBlock(FuncInfo *func, DIST::Array *array) if (!insertPlace) insertPlace = func->funcPointer->GetOriginal(); - SgStatement *commDecl = createCommonBlock(file, array); + SgStatement *commDecl = createCommonBlock(file, array, unique_name_creator); SgStatement *copyDecl = commDecl->copyPtr(); auto st = insertPlace->controlParent(); @@ -779,7 +881,7 @@ static void insertCommonBlock(FuncInfo *func, DIST::Array *array) insertPlace->lexNext()->setlineNumber(nextLine); // create declaration via comment - insertStringDeclarations(insertPlace->lexNext(), array); + insertStringDeclarations(insertPlace->lexNext(), array, unique_name_creator); } // file -> lines -> arrays; lines where arrays copying is inserted @@ -1097,6 +1199,7 @@ pair copyArray(const pair &place, static void copyFunction(ParallelRegion *region, FuncInfo *func, const map &funcMap, + UniqueNameCreator& unique_name_creator, const string &suffix = "") { if (SgFile::switchToFile(func->fileName) != -1) @@ -1146,14 +1249,14 @@ static void copyFunction(ParallelRegion *region, if (origStat->variant() == COMM_STAT) { for (auto &arrayBlock : allUsedCommonArrays) - createCommonBlock(file, arrayBlock.first); + createCommonBlock(file, arrayBlock.first, unique_name_creator); auto usedCommonArrays = region->GetUsedCommonArrays().find(func); if (usedCommonArrays != region->GetUsedCommonArrays().end()) { for (auto &arrayLines : usedCommonArrays->second) { - SgStatement *commDecl = createCommonBlock(file, arrayLines.first); + SgStatement *commDecl = createCommonBlock(file, arrayLines.first, unique_name_creator); SgStatement *copyDecl = commDecl->copyPtr(); while (!isSgExecutableStatement(copyStat) || isSPF_stat(copyStat)) @@ -1163,7 +1266,7 @@ static void copyFunction(ParallelRegion *region, copyStat->insertStmtAfter(*copyDecl, *copyStat->controlParent()); // making declaration of new common array symbol via comment through files - insertStringDeclarations(copyStat->lexNext(), arrayLines.first); + insertStringDeclarations(copyStat->lexNext(), arrayLines.first, unique_name_creator); } auto it = createdCommonArrays.find(file->filename()); @@ -1619,6 +1722,8 @@ int resolveParRegions(vector ®ions, const map funcMap; createMapOfFunc(allFuncInfo, funcMap); + UniqueNameCreator unique_name_creator(allFuncInfo); + if (sharedMemoryParallelization == 0) { map>> copied; @@ -1688,7 +1793,7 @@ int resolveParRegions(vector ®ions, const mapsecond.end() && arrayBlock.first->GetShortName() == varsOnPos[0]->getName()) { // need to insert common-block - insertCommonBlock(func, arrayBlock.first); + insertCommonBlock(func, arrayBlock.first, unique_name_creator); it->second.insert(arrayBlock.first); } } @@ -1781,7 +1886,7 @@ int resolveParRegions(vector ®ions, const mapsecond.end() && arrayBlock.first->GetShortName() == varsOnPos[0]->getName()) { // need to insert common-block - insertCommonBlock(func, arrayBlock.first); + insertCommonBlock(func, arrayBlock.first, unique_name_creator); it->second.insert(arrayBlock.first); } } @@ -1813,7 +1918,7 @@ int resolveParRegions(vector ®ions, const mapGetUsedCommonArrays().end()) { for (auto &arrayBlock : allUsedCommonArrays) - createCommonBlock(file, arrayBlock.first); + createCommonBlock(file, arrayBlock.first, unique_name_creator); auto it = insertedCommonBlocks.find(func); if (it == insertedCommonBlocks.end()) @@ -1825,7 +1930,7 @@ int resolveParRegions(vector ®ions, const mapsecond.end()) { // need to insert common-block - insertCommonBlock(func, arrayLines.first); + insertCommonBlock(func, arrayLines.first, unique_name_creator); it->second.insert(arrayLines.first); // replace common arrays to new common arrays in executable code section @@ -1858,7 +1963,7 @@ int resolveParRegions(vector ®ions, const mapcallRegions) if (regionId) - copyFunction(getRegionById(regions, regionId), func, funcMap, string("_r") + to_string(regionId)); + copyFunction(getRegionById(regions, regionId), func, funcMap, unique_name_creator, string("_r") + to_string(regionId)); } } } From 7d45f5babc8905327b82891f0bd3ca652487f6e2 Mon Sep 17 00:00:00 2001 From: xnpster Date: Sun, 19 Apr 2026 19:17:14 +0300 Subject: [PATCH 16/32] marge_regions: rename --- CMakeLists.txt | 8 ++++---- .../{parse_merge_dirs.cpp => merge_regions.cpp} | 4 ++-- src/ParallelizationRegions/merge_regions.h | 8 ++++++++ src/ParallelizationRegions/parse_merge_dirs.h | 8 -------- src/Sapfor.cpp | 10 +++++----- src/Sapfor.h | 4 ++-- src/Utils/PassManager.h | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) rename src/ParallelizationRegions/{parse_merge_dirs.cpp => merge_regions.cpp} (99%) create mode 100644 src/ParallelizationRegions/merge_regions.h delete mode 100644 src/ParallelizationRegions/parse_merge_dirs.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1af5c52..c679fca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,8 +166,8 @@ set(PARALLEL_REG src/ParallelizationRegions/ParRegions.cpp set(ARRAY_PROP src/ArrayConstantPropagation/propagation.cpp src/ArrayConstantPropagation/propagation.h ) -set(MERGE_COPY_ARRAYS src/ParallelizationRegions/parse_merge_dirs.cpp - src/ParallelizationRegions/parse_merge_dirs.h) +set(MERGE_REGIONS src/ParallelizationRegions/merge_regions.cpp + src/ParallelizationRegions/merge_regions.h) set(TR_DEAD_CODE src/Transformations/DeadCodeRemoving/dead_code.cpp src/Transformations/DeadCodeRemoving/dead_code.h) @@ -428,7 +428,7 @@ set(SOURCE_EXE ${LOOP_ANALYZER} ${TRANSFORMS} ${PARALLEL_REG} - ${MERGE_COPY_ARRAYS} + ${MERGE_REGIONS} ${PRIV} ${ARRAY_PROP} ${FDVM} @@ -482,7 +482,7 @@ source_group (GraphCall FILES ${GR_CALL}) source_group (GraphLoop FILES ${GR_LOOP}) source_group (LoopAnalyzer FILES ${LOOP_ANALYZER}) source_group (ParallelizationRegions FILES ${PARALLEL_REG}) -source_group (MergeCopyArrays FILES ${MERGE_COPY_ARRAYS}) +source_group (MergeRegions FILES ${MERGE_REGIONS}) source_group (PrivateAnalyzer FILES ${PRIV}) source_group (ArrayConstantPropagation FILES ${ARRAY_PROP}) source_group (FDVM_Compiler FILES ${FDVM}) diff --git a/src/ParallelizationRegions/parse_merge_dirs.cpp b/src/ParallelizationRegions/merge_regions.cpp similarity index 99% rename from src/ParallelizationRegions/parse_merge_dirs.cpp rename to src/ParallelizationRegions/merge_regions.cpp index b7cae96..f047085 100644 --- a/src/ParallelizationRegions/parse_merge_dirs.cpp +++ b/src/ParallelizationRegions/merge_regions.cpp @@ -1,4 +1,4 @@ -#include "parse_merge_dirs.h" +#include "merge_regions.h" #include @@ -360,7 +360,7 @@ static void replaceRegion(SgStatement* st, const unordered_map & } } -void mergeCopyArrays(vector ®ions, const map> &allFuncInfo) +void mergeRegions(vector ®ions, const map> &allFuncInfo) { for (const auto *region : regions) { diff --git a/src/ParallelizationRegions/merge_regions.h b/src/ParallelizationRegions/merge_regions.h new file mode 100644 index 0000000..6ecee53 --- /dev/null +++ b/src/ParallelizationRegions/merge_regions.h @@ -0,0 +1,8 @@ +#include "../GraphCall/graph_calls.h" +#include "ParRegions.h" + +#include +#include +#include + +void mergeRegions(std::vector ®ions, const std::map> &allFuncInfo); \ No newline at end of file diff --git a/src/ParallelizationRegions/parse_merge_dirs.h b/src/ParallelizationRegions/parse_merge_dirs.h deleted file mode 100644 index 54c2287..0000000 --- a/src/ParallelizationRegions/parse_merge_dirs.h +++ /dev/null @@ -1,8 +0,0 @@ -#include "../GraphCall/graph_calls.h" -#include "ParRegions.h" - -#include -#include -#include - -void mergeCopyArrays(std::vector ®ions, const std::map> &allFuncInfo); \ No newline at end of file diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index 1fda4b0..f3eaa52 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1,4 +1,4 @@ -#include "Utils/leak_detector.h" +#include "Utils/leak_detector.h" #pragma comment(linker, "/STACK:536870912") // 512 МБ @@ -23,7 +23,7 @@ #include "ParallelizationRegions/ParRegions_func.h" #include "ParallelizationRegions/resolve_par_reg_conflicts.h" #include "ParallelizationRegions/expand_extract_reg.h" -#include "ParallelizationRegions/parse_merge_dirs.h" +#include "ParallelizationRegions/merge_regions.h" #include "Distribution/Distribution.h" #include "Distribution/GraphCSR.h" @@ -1906,9 +1906,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne transformAssumedSizeParameters(allFuncInfo); else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS) FindPrivateArrays(loopGraph, fullIR, insertedPrivates); - else if (curr_regime == MERGE_COPY_ARRAYS) + else if (curr_regime == MERGE_REGIONS) { - mergeCopyArrays(parallelRegions, allFuncInfo); + mergeRegions(parallelRegions, allFuncInfo); } else if (curr_regime == ARRAY_PROPAGATION) @@ -2367,7 +2367,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam case FIX_COMMON_BLOCKS: case TEST_PASS: case SET_IMPLICIT_NONE: - case MERGE_COPY_ARRAYS: + case MERGE_REGIONS: runAnalysis(*project, curr_regime, false); case SUBST_EXPR_RD_AND_UNPARSE: case SUBST_EXPR_AND_UNPARSE: diff --git a/src/Sapfor.h b/src/Sapfor.h index 3ad7cb8..bae94fb 100644 --- a/src/Sapfor.h +++ b/src/Sapfor.h @@ -88,7 +88,7 @@ enum passes { REMOVE_DVM_INTERVALS, VERIFY_DVM_DIRS, - MERGE_COPY_ARRAYS, + MERGE_REGIONS, REMOVE_DIST_ARRAYS_FROM_IO, @@ -275,7 +275,7 @@ static void setPassValues() passNames[VERIFY_DVM_DIRS] = "VERIFY_DVM_DIRS"; passNames[REMOVE_DVM_DIRS_TO_COMMENTS] = "REMOVE_DVM_DIRS_TO_COMMENTS"; passNames[REMOVE_SPF_DIRS] = "REMOVE_SPF_DIRS"; - passNames[MERGE_COPY_ARRAYS] = "MERGE_COPY_ARRAYS"; + passNames[MERGE_REGIONS] = "MERGE_REGIONS"; passNames[REMOVE_DIST_ARRAYS_FROM_IO] = "REMOVE_DIST_ARRAYS_FROM_IO"; passNames[SUBST_EXPR] = "SUBST_EXPR"; passNames[SUBST_EXPR_RD] = "SUBST_EXPR_RD"; diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index caefa14..68a6f6b 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -322,7 +322,7 @@ void InitPassesDependencies(map> &passDepsIn, set list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS); list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS); - Pass(CREATE_TEMPLATE_LINKS) <= Pass(MERGE_COPY_ARRAYS); + Pass(CREATE_TEMPLATE_LINKS) <= Pass(MERGE_REGIONS); passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS, EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW, From 8fdf7e7063bc4a0c334e949813aa01f3d0cbcda1 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Sun, 19 Apr 2026 19:56:35 +0300 Subject: [PATCH 17/32] removed unn --- src/CFGraph/RD_subst.h | 2 +- src/GraphLoop/graph_loops_base.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/CFGraph/RD_subst.h b/src/CFGraph/RD_subst.h index e51c51b..d6bda94 100644 --- a/src/CFGraph/RD_subst.h +++ b/src/CFGraph/RD_subst.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "SgUtils.h" #include "CommonBlock.h" diff --git a/src/GraphLoop/graph_loops_base.cpp b/src/GraphLoop/graph_loops_base.cpp index 7a871bb..a6c06d4 100644 --- a/src/GraphLoop/graph_loops_base.cpp +++ b/src/GraphLoop/graph_loops_base.cpp @@ -6,14 +6,12 @@ #include #include -#include #include #include #include using std::vector; using std::map; -using std::unordered_map; using std::tuple; using std::set; using std::string; From d77b6d52882e5e87c2cae8231965be40d7b9405b Mon Sep 17 00:00:00 2001 From: ALEXks Date: Sun, 19 Apr 2026 20:25:20 +0300 Subject: [PATCH 18/32] refactored --- CMakeLists.txt | 4 +- src/ParallelizationRegions/merge_regions.cpp | 66 ++++++----- .../resolve_par_reg_conflicts.cpp | 107 +----------------- .../resolve_par_reg_conflicts.h | 4 +- .../uniq_name_creator.cpp | 98 ++++++++++++++++ .../uniq_name_creator.h | 26 +++++ src/Utils/version.h | 2 +- 7 files changed, 170 insertions(+), 137 deletions(-) create mode 100644 src/ParallelizationRegions/uniq_name_creator.cpp create mode 100644 src/ParallelizationRegions/uniq_name_creator.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c679fca..012efa1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,7 +161,9 @@ set(PARALLEL_REG src/ParallelizationRegions/ParRegions.cpp src/ParallelizationRegions/expand_extract_reg.cpp src/ParallelizationRegions/expand_extract_reg.h src/ParallelizationRegions/resolve_par_reg_conflicts.cpp - src/ParallelizationRegions/resolve_par_reg_conflicts.h) + src/ParallelizationRegions/resolve_par_reg_conflicts.h + src/ParallelizationRegions/uniq_name_creator.cpp + src/ParallelizationRegions/uniq_name_creator.h) set(ARRAY_PROP src/ArrayConstantPropagation/propagation.cpp src/ArrayConstantPropagation/propagation.h diff --git a/src/ParallelizationRegions/merge_regions.cpp b/src/ParallelizationRegions/merge_regions.cpp index f047085..4c68fb2 100644 --- a/src/ParallelizationRegions/merge_regions.cpp +++ b/src/ParallelizationRegions/merge_regions.cpp @@ -1,14 +1,16 @@ +#include "leak_detector.h" + +#include +#include #include "merge_regions.h" -#include - using std::map; +using std::set; using std::pair; using std::string; -using std::unordered_map; -using std::unordered_set; using std::vector; +//TODO: need to create new clause!! static void parseMergeDirective(const char *comment, vector> &parsed_mapping) { @@ -16,21 +18,27 @@ static void parseMergeDirective(const char *comment, { auto *line_end = strchr(comment, '\n'); - static const char prefix[] = "!!SPF TRANSFORM(MERGE_ARRAYS("; + static const char prefix[] = "!!spf transform(merge_arrays("; static const auto compare_chars = sizeof(prefix) - 1; - if (strncasecmp(comment, prefix, compare_chars) == 0) + if (strlen(comment) >= compare_chars) { - auto *pair_start = comment + compare_chars; - auto *comma = strchr(pair_start, ','); - if (comma) + std::string comment_cmp(comment, compare_chars); + convertToLower(comment_cmp); + + if (comment_cmp == prefix) { - auto *close_br = strchr(comma + 1, ')'); - if (close_br) + auto* pair_start = comment + compare_chars; + auto* comma = strchr(pair_start, ','); + if (comma) { - parsed_mapping.emplace_back( - string(pair_start, comma - pair_start), - string(comma + 1, close_br - comma - 1)); + auto* close_br = strchr(comma + 1, ')'); + if (close_br) + { + parsed_mapping.emplace_back( + string(pair_start, comma - pair_start), + string(comma + 1, close_br - comma - 1)); + } } } } @@ -78,10 +86,10 @@ static bool hasSameSizes(DIST::Array *a, DIST::Array *b) } static bool checkSimilarTemplates(vector ®ions, - const unordered_map &new_region_mapping) + const map &new_region_mapping) { // new region -> old regions - unordered_map> new_region_inverse_mapping; + map> new_region_inverse_mapping; for (const auto &p : new_region_mapping) new_region_inverse_mapping[p.second].insert(p.first); @@ -126,8 +134,8 @@ static bool checkSimilarTemplates(vector ®ions, return true; } -static bool hasSameAlignment(const std::unordered_set &align_a, - const std::unordered_set &align_b) +static bool hasSameAlignment(const std::set &align_a, + const std::set &align_b) { if (align_a.size() != 1 || align_b.size() != 1) return false; @@ -238,7 +246,7 @@ SgSymbol *insertDeclIfNeeded(const string &array_name, const string &common_block_name, DIST::Array *example_array, FuncInfo *dest, - unordered_map> &inserted_arrays) + map> &inserted_arrays) { auto *type = GetArrayType(example_array); @@ -278,7 +286,7 @@ SgSymbol *insertDeclIfNeeded(const string &array_name, static pair createNewArray(DIST::Array *example_array, const string &base_name, const map> &allFuncInfo, - unordered_map> &inserted_arrays) + map> &inserted_arrays) { auto common_block_name = base_name + "_merge_r"; auto array_name = base_name; @@ -303,12 +311,12 @@ static pair createNewArray(DIST::Array *example_array, const str } static void replaceArrayRec(SgExpression *e, - const unordered_set &arrays_to_replace, + const set &arrays_to_replace, SgSymbol **func_symbol_hint, const pair &replace_by, DIST::Array *example_array, FuncInfo *func, - unordered_map> &inserted_arrays) + map> &inserted_arrays) { if (!e) return; @@ -346,7 +354,7 @@ static void replaceArrayRec(SgExpression *e, inserted_arrays); } -static void replaceRegion(SgStatement* st, const unordered_map &new_region_mapping) +static void replaceRegion(SgStatement* st, const map &new_region_mapping) { if (!st) return; @@ -430,8 +438,8 @@ void mergeRegions(vector ®ions, const map current arrays - unordered_map> arrays_to_merge; - unordered_map> array_alignment; + map> arrays_to_merge; + map> array_alignment; for (const auto &by_file : allFuncInfo) { @@ -489,10 +497,10 @@ void mergeRegions(vector ®ions, const map new region - unordered_map new_region_mapping; + map new_region_mapping; // new array -> new region - unordered_map arrays_new_region_mapping; + map arrays_new_region_mapping; vector created_region_names; for (const auto &by_new_array : arrays_to_merge) @@ -529,7 +537,7 @@ void mergeRegions(vector ®ions, const map> inserted_arrays; + map> inserted_arrays; for (const auto &by_dest_array : arrays_to_merge) { @@ -571,7 +579,7 @@ void mergeRegions(vector ®ions, const map arrays_to_replace; + set arrays_to_replace; for (auto *array_to_merge : copy_arrays) arrays_to_replace.insert(array_to_merge->GetShortName()); diff --git a/src/ParallelizationRegions/resolve_par_reg_conflicts.cpp b/src/ParallelizationRegions/resolve_par_reg_conflicts.cpp index 87b3e19..62b9acb 100644 --- a/src/ParallelizationRegions/resolve_par_reg_conflicts.cpp +++ b/src/ParallelizationRegions/resolve_par_reg_conflicts.cpp @@ -4,9 +4,7 @@ #include #include #include -#include #include -#include #include #include @@ -21,12 +19,11 @@ #include "SgUtils.h" #include "expr_transform.h" #include "FunctionPurifying/function_purifying.h" +#include "uniq_name_creator.h" using std::map; using std::pair; using std::set; -using std::unordered_set; -using std::unordered_map; using std::vector; using std::stack; using std::string; @@ -34,9 +31,6 @@ using std::wstring; using std::to_string; using std::make_pair; -static const string COMMON_ARRAY_SUFFIX = "_c"; -static const string COMMON_BLOCK_SUFFIX = "_r"; - static inline int getRegionExplicitLine(SgStatement *startR) { checkNull(startR, convertFileName(__FILE__).c_str(), __LINE__); @@ -78,7 +72,7 @@ static bool isSPF_reg(SgStatement *st) return st->variant() == SPF_PARALLEL_REG_DIR || st->variant() == SPF_END_PARALLEL_REG_DIR; } -static const vector getArraySynonyms(DIST::Array *array) +const vector getArraySynonyms(DIST::Array *array) { auto arrayBlock = allUsedCommonArrays.find(array); if (arrayBlock == allUsedCommonArrays.end()) @@ -113,103 +107,6 @@ static const vector getArraySynonyms(DIST::Array *array) return arrayBlock->second->getVariables(pos); } -class UniqueNameCreator -{ - map> func_info; - unordered_set all_declarations; - bool declarations_analyzed = false; - unordered_map> generated_names; - - static void GetSymbolsRec(SgExpression* exp, unordered_set& add_to) - { - if (!exp) - return; - - if (isArrayRef(exp) && exp->symbol() && exp->symbol()->identifier()) - add_to.emplace(exp->symbol()->identifier()); - - GetSymbolsRec(exp->lhs(), add_to); - GetSymbolsRec(exp->rhs(), add_to); - } - - void FillDeclarations() - { - all_declarations.clear(); - - auto* file_before = current_file; - - for (const auto& by_file : func_info) - { - if (SgFile::switchToFile(by_file.first) != -1) - { - for (const auto* by_func : by_file.second) - { - SgStatement* st = by_func->funcPointer; - - if (st) - st = st->lexNext(); - - while (st) - { - for (int i = 0; i < 3; i++) - GetSymbolsRec(st->expr(i), all_declarations); - - st = st->lexNext(); - } - } - } - } - - SgFile::switchToFile(file_before->filename()); - declarations_analyzed = true; - } -public: - UniqueNameCreator(const map> &allFuncInfo) - { - declarations_analyzed = false; - func_info = allFuncInfo; - } - - void GetUniqueName(DIST::Array* array, string& array_name, string& common_block_name) - { - auto varsOnPos = getArraySynonyms(array); - if (!varsOnPos.size()) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - auto array_plain_name = varsOnPos[0]->getName(); - - auto it = generated_names.find(array); - if (it != generated_names.end()) - { - array_name.assign(it->second.first); - common_block_name.assign(it->second.second); - return; - } - - if (!declarations_analyzed) - FillDeclarations(); - - int v = 1; - auto created_array_name = array_plain_name + COMMON_ARRAY_SUFFIX; - auto created_common_name = array_plain_name + COMMON_BLOCK_SUFFIX; - - while (all_declarations.find(created_array_name) != all_declarations.end() || - all_declarations.find(created_common_name) != all_declarations.end()) - { - created_array_name = array_plain_name + "_v" + std::to_string(v) + COMMON_ARRAY_SUFFIX; - created_common_name = array_plain_name + "_v" + std::to_string(v) + COMMON_BLOCK_SUFFIX; - v++; - } - - all_declarations.insert(created_array_name); - all_declarations.insert(created_common_name); - generated_names.emplace(array, std::make_pair(created_array_name, created_common_name)); - - array_name.assign(created_array_name); - common_block_name.assign(created_common_name); - } -}; - static string getStringDeclaration(SgSymbol *symb) { string decl; diff --git a/src/ParallelizationRegions/resolve_par_reg_conflicts.h b/src/ParallelizationRegions/resolve_par_reg_conflicts.h index cfaecbe..38e3fd7 100644 --- a/src/ParallelizationRegions/resolve_par_reg_conflicts.h +++ b/src/ParallelizationRegions/resolve_par_reg_conflicts.h @@ -21,4 +21,6 @@ std::pair copyArray(const std::pair& pla const std::string& suffix, std::string& filename, std::map>>& newDeclsToInclude, - std::map>>& copied); \ No newline at end of file + std::map>>& copied); + +const std::vector getArraySynonyms(DIST::Array* array); \ No newline at end of file diff --git a/src/ParallelizationRegions/uniq_name_creator.cpp b/src/ParallelizationRegions/uniq_name_creator.cpp new file mode 100644 index 0000000..6387d6e --- /dev/null +++ b/src/ParallelizationRegions/uniq_name_creator.cpp @@ -0,0 +1,98 @@ +#include "leak_detector.h" + +#include +#include +#include + +#include "SgUtils.h" +#include "uniq_name_creator.h" +#include "resolve_par_reg_conflicts.h" + +using namespace::std; + +static const string COMMON_ARRAY_SUFFIX = "_c"; +static const string COMMON_BLOCK_SUFFIX = "_r"; + +void UniqueNameCreator::GetSymbolsRec(SgExpression* exp, set& add_to) +{ + if (!exp) + return; + + if (isArrayRef(exp) && exp->symbol() && exp->symbol()->identifier()) + add_to.emplace(exp->symbol()->identifier()); + + GetSymbolsRec(exp->lhs(), add_to); + GetSymbolsRec(exp->rhs(), add_to); +} + +void UniqueNameCreator::FillDeclarations() +{ + allDeclarations.clear(); + auto* file_before = current_file; + + for (const auto& by_file : funcInfo) + { + if (SgFile::switchToFile(by_file.first) != -1) + { + for (const auto* by_func : by_file.second) + { + SgStatement* st = by_func->funcPointer; + + if (st) + st = st->lexNext(); + + while (st) + { + for (int i = 0; i < 3; i++) + GetSymbolsRec(st->expr(i), allDeclarations); + + st = st->lexNext(); + } + } + } + else + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + + SgFile::switchToFile(file_before->filename()); + declarationsAnalyzed = true; +} + +void UniqueNameCreator::GetUniqueName(DIST::Array* array, string& array_name, string& common_block_name) +{ + auto varsOnPos = getArraySynonyms(array); + if (!varsOnPos.size()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + auto array_plain_name = varsOnPos[0]->getName(); + + auto it = generatedNames.find(array); + if (it != generatedNames.end()) + { + array_name.assign(it->second.first); + common_block_name.assign(it->second.second); + return; + } + + if (!declarationsAnalyzed) + FillDeclarations(); + + int v = 1; + auto created_array_name = array_plain_name + COMMON_ARRAY_SUFFIX; + auto created_common_name = array_plain_name + COMMON_BLOCK_SUFFIX; + + while (allDeclarations.find(created_array_name) != allDeclarations.end() || + allDeclarations.find(created_common_name) != allDeclarations.end()) + { + created_array_name = array_plain_name + "_v" + std::to_string(v) + COMMON_ARRAY_SUFFIX; + created_common_name = array_plain_name + "_v" + std::to_string(v) + COMMON_BLOCK_SUFFIX; + v++; + } + + allDeclarations.insert(created_array_name); + allDeclarations.insert(created_common_name); + generatedNames.emplace(array, std::make_pair(created_array_name, created_common_name)); + + array_name.assign(created_array_name); + common_block_name.assign(created_common_name); +} diff --git a/src/ParallelizationRegions/uniq_name_creator.h b/src/ParallelizationRegions/uniq_name_creator.h new file mode 100644 index 0000000..d509371 --- /dev/null +++ b/src/ParallelizationRegions/uniq_name_creator.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include +#include "GraphCall/graph_calls.h" + +class UniqueNameCreator +{ + std::map> funcInfo; + std::set allDeclarations; + bool declarationsAnalyzed = false; + std::map> generatedNames; + + static void GetSymbolsRec(SgExpression* exp, std::set& add_to); + void FillDeclarations(); + +public: + UniqueNameCreator(const std::map>& allFuncInfo) + { + declarationsAnalyzed = false; + funcInfo = allFuncInfo; + } + + void GetUniqueName(DIST::Array* array, std::string& array_name, std::string& common_block_name); +}; diff --git a/src/Utils/version.h b/src/Utils/version.h index c4c9c11..11f57e0 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2479" +#define VERSION_SPF "2480" From d5919e5739f08e10e1fe62bdd50e01ba8d4b7c23 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Sun, 19 Apr 2026 20:29:23 +0300 Subject: [PATCH 19/32] refactored --- src/ArrayConstantPropagation/propagation.cpp | 2 +- src/ArrayConstantPropagation/propagation.h | 2 +- src/PrivateAnalyzer/private_arrays_search.cpp | 2 +- src/PrivateAnalyzer/private_arrays_search.h | 3 +-- src/PrivateAnalyzer/region.cpp | 2 +- src/Sapfor.cpp | 7 ++----- 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/ArrayConstantPropagation/propagation.cpp b/src/ArrayConstantPropagation/propagation.cpp index a9400fc..034c6b4 100644 --- a/src/ArrayConstantPropagation/propagation.cpp +++ b/src/ArrayConstantPropagation/propagation.cpp @@ -313,7 +313,7 @@ static void CheckVariable(SgStatement* st, SgExpression* exp, unordered_map arrayToVariable; int variableNumber = 0; diff --git a/src/ArrayConstantPropagation/propagation.h b/src/ArrayConstantPropagation/propagation.h index f33523c..65fe4ed 100644 --- a/src/ArrayConstantPropagation/propagation.h +++ b/src/ArrayConstantPropagation/propagation.h @@ -17,4 +17,4 @@ struct ExprRestoreEntry SgExpression* savedCopy; }; -void ArrayConstantPropagation(SgProject& project); \ No newline at end of file +void arrayConstantPropagation(SgProject& project); \ No newline at end of file diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index 041c2bc..b08dd5b 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -419,7 +419,7 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& } } -void FindPrivateArrays(map>& loopGraph, map>& FullIR, set& insertedPrivates) +void findPrivateArrays(map>& loopGraph, map>& FullIR, set& insertedPrivates) { map result; for (const auto& [fileName, loops] : loopGraph) diff --git a/src/PrivateAnalyzer/private_arrays_search.h b/src/PrivateAnalyzer/private_arrays_search.h index ca5da48..8b8f02c 100644 --- a/src/PrivateAnalyzer/private_arrays_search.h +++ b/src/PrivateAnalyzer/private_arrays_search.h @@ -9,5 +9,4 @@ #include "graph_loops.h" #include "CFGraph/CFGraph.h" -void FindPrivateArrays(std::map>& loopGraph, std::map>& FullIR, std::set& insertedPrivates); -std::pair> GetBasicBlocksForLoop(const LoopGraph* loop, const std::vector blocks); +void findPrivateArrays(std::map>& loopGraph, std::map>& FullIR, std::set& insertedPrivates); diff --git a/src/PrivateAnalyzer/region.cpp b/src/PrivateAnalyzer/region.cpp index 94c1815..4b38739 100644 --- a/src/PrivateAnalyzer/region.cpp +++ b/src/PrivateAnalyzer/region.cpp @@ -23,7 +23,7 @@ static bool isParentStmt(SgStatement* stmt, SgStatement* parent) } /*returns head block and loop*/ -pair> GetBasicBlocksForLoop(const LoopGraph* loop, const vector blocks) +static pair> GetBasicBlocksForLoop(const LoopGraph* loop, const vector blocks) { unordered_set block_loop; SAPFOR::BasicBlock* head_block = nullptr; diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index f3eaa52..5a89c73 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1905,14 +1905,11 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS) transformAssumedSizeParameters(allFuncInfo); else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS) - FindPrivateArrays(loopGraph, fullIR, insertedPrivates); + findPrivateArrays(loopGraph, fullIR, insertedPrivates); else if (curr_regime == MERGE_REGIONS) - { mergeRegions(parallelRegions, allFuncInfo); - } - else if (curr_regime == ARRAY_PROPAGATION) - ArrayConstantPropagation(project); + arrayConstantPropagation(project); const float elapsed = duration_cast(high_resolution_clock::now() - timeForPass).count() / 1000.; const float elapsedGlobal = duration_cast(high_resolution_clock::now() - globalTime).count() / 1000.; From 5b3716cef3cbdfb85369cae1bd5e2d752b3ecd22 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Sun, 19 Apr 2026 20:42:22 +0300 Subject: [PATCH 20/32] added to vis call --- src/Utils/version.h | 2 +- src/VisualizerCalls/get_information.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Utils/version.h b/src/Utils/version.h index 11f57e0..ff69028 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2480" +#define VERSION_SPF "2481" diff --git a/src/VisualizerCalls/get_information.cpp b/src/VisualizerCalls/get_information.cpp index b7874f1..3d95737 100644 --- a/src/VisualizerCalls/get_information.cpp +++ b/src/VisualizerCalls/get_information.cpp @@ -1809,6 +1809,13 @@ int SPF_MoveOperators(void*& context, int winHandler, short* options, short* pro return simpleTransformPass(MOVE_OPERATORS, options, projName, folderName, output, outputMessage); } +int SPF_MergeRegions(void*& context, int winHandler, short* options, short* projName, short* folderName, string& output, string& outputMessage) +{ + MessageManager::clearCache(); + MessageManager::setWinHandler(winHandler); + return simpleTransformPass(MERGE_REGIONS, options, projName, folderName, output, outputMessage); +} + static inline void convertBackSlash(char *str, int strL) { for (int z = 0; z < strL; ++z) @@ -2519,6 +2526,8 @@ const wstring Sapfor_RunTransformation(const char* transformName_c, const char* retCode = SPF_InsertPrivateArrayDirectives(context, winHandler, optSh, projSh, fold, output, outputMessage); else if (whichRun == "SPF_MoveOperators") retCode = SPF_MoveOperators(context, winHandler, optSh, projSh, fold, output, outputMessage); + else if (whichRun == "SPF_MergeRegions") + retCode = SPF_MergeRegions(context, winHandler, optSh, projSh, fold, output, outputMessage); else if (whichRun == "SPF_CreateParallelVariant") { vector splited; From daeaafd8a7ea1295272947a80a17e4a605f033c3 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Wed, 22 Apr 2026 11:10:10 +0300 Subject: [PATCH 21/32] updated dvm --- projects/dvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/dvm b/projects/dvm index ab99430..7aefb0d 160000 --- a/projects/dvm +++ b/projects/dvm @@ -1 +1 @@ -Subproject commit ab99430aeedc2ac943e7f41d38abb6e6393ed2f4 +Subproject commit 7aefb0d897fa63a495b772afc83e957aa510dfa0 From 9e2d0eacbdb6d5ce1989cfdfef5488e26fd8c279 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Wed, 22 Apr 2026 11:20:15 +0300 Subject: [PATCH 22/32] added MERGED_ARRAYS operation --- src/DirectiveProcessing/spf_directive_preproc.cpp | 11 +++++++++++ src/Utils/version.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/DirectiveProcessing/spf_directive_preproc.cpp b/src/DirectiveProcessing/spf_directive_preproc.cpp index 6039de6..48bb8ad 100644 --- a/src/DirectiveProcessing/spf_directive_preproc.cpp +++ b/src/DirectiveProcessing/spf_directive_preproc.cpp @@ -1933,6 +1933,17 @@ static inline bool processStat(SgStatement *st, const string &currFile, retVal = false; } } + + //MERGE_ARRAYS + if (isSPF_OP(attributeStatement, SPF_MERGE_ARRAYS_OP)) + { + attributeStatement->setLocalLineNumber(-1); + /*if (st->variant() != FOR_NODE) + { + BAD_POSITION_FULL(ERROR, "", "", "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber()); + retVal = false; + }*/ + } } else if (type == SPF_CHECKPOINT_DIR) { diff --git a/src/Utils/version.h b/src/Utils/version.h index ff69028..0646b65 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2481" +#define VERSION_SPF "2482" From fe7e3449e8807c4b341d119ed349694f2e88bba1 Mon Sep 17 00:00:00 2001 From: Oleg Nikitin Date: Mon, 27 Apr 2026 16:12:26 +0300 Subject: [PATCH 23/32] move files --- .../ArrayConstantPropagation/propagation.cpp | 0 src/{ => Transformations}/ArrayConstantPropagation/propagation.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{ => Transformations}/ArrayConstantPropagation/propagation.cpp (100%) rename src/{ => Transformations}/ArrayConstantPropagation/propagation.h (100%) diff --git a/src/ArrayConstantPropagation/propagation.cpp b/src/Transformations/ArrayConstantPropagation/propagation.cpp similarity index 100% rename from src/ArrayConstantPropagation/propagation.cpp rename to src/Transformations/ArrayConstantPropagation/propagation.cpp diff --git a/src/ArrayConstantPropagation/propagation.h b/src/Transformations/ArrayConstantPropagation/propagation.h similarity index 100% rename from src/ArrayConstantPropagation/propagation.h rename to src/Transformations/ArrayConstantPropagation/propagation.h From 5f25567a14ce3d97613ee829571c56fa0f8a9692 Mon Sep 17 00:00:00 2001 From: Oleg Nikitin Date: Mon, 27 Apr 2026 16:18:43 +0300 Subject: [PATCH 24/32] add restore pass --- CMakeLists.txt | 11 +- src/PrivateAnalyzer/private_arrays_search.cpp | 121 ++--- src/PrivateAnalyzer/private_arrays_search.h | 2 +- src/PrivateAnalyzer/range_structures.cpp | 2 +- src/PrivateAnalyzer/range_structures.h | 2 +- src/PrivateAnalyzer/region.cpp | 86 ++-- src/PrivateAnalyzer/region.h | 16 +- src/Sapfor.cpp | 2 + src/Sapfor.h | 3 +- .../ArrayConstantPropagation/propagation.cpp | 486 +++++++++++++----- .../ArrayConstantPropagation/propagation.h | 13 +- src/Utils/PassManager.h | 2 +- src/Utils/version.h | 2 +- 13 files changed, 470 insertions(+), 278 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 012efa1..724026f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,9 +165,6 @@ set(PARALLEL_REG src/ParallelizationRegions/ParRegions.cpp src/ParallelizationRegions/uniq_name_creator.cpp src/ParallelizationRegions/uniq_name_creator.h) -set(ARRAY_PROP src/ArrayConstantPropagation/propagation.cpp - src/ArrayConstantPropagation/propagation.h -) set(MERGE_REGIONS src/ParallelizationRegions/merge_regions.cpp src/ParallelizationRegions/merge_regions.h) @@ -214,6 +211,8 @@ set(TR_RENAME_SYMBOLS src/Transformations/RenameSymbols/rename_symbols.cpp src/Transformations/RenameSymbols/rename_symbols.h) SET(TR_MOVE_OPERATORS src/Transformations/MoveOperators/move_operators.cpp src/Transformations/MoveOperators/move_operators.h) +SET(TR_ARR_PROP src/Transformations/ArrayConstantPropagation/propagation.cpp + src/Transformations/ArrayConstantPropagation/propagation.h) set(TRANSFORMS ${TR_DEAD_CODE} @@ -237,7 +236,8 @@ set(TRANSFORMS ${TR_EXPR_TRANSFORM} ${TR_INLINER} ${TR_RENAME_SYMBOLS} - ${TR_MOVE_OPERATORS}) + ${TR_MOVE_OPERATORS} + ${TR_ARR_PROP}) set(CFG src/CFGraph/IR.cpp src/CFGraph/IR.h @@ -432,7 +432,6 @@ set(SOURCE_EXE ${PARALLEL_REG} ${MERGE_REGIONS} ${PRIV} - ${ARRAY_PROP} ${FDVM} ${OMEGA} ${UTILS} @@ -473,6 +472,7 @@ source_group (Transformations\\ConvertToC FILES ${TR_CONV}) source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE}) source_group (Transformations\\ReplaceArraysInIO FILES ${TR_REPLACE_ARRAYS_IN_IO}) source_group (Transformations\\MoveOperators FILES ${TR_MOVE_OPERATORS}) +source_group (Transformations\\ArrayConstantPropagation FILES ${TR_ARR_PROP}) source_group (CreateIntervals FILES ${CREATE_INTER_T}) @@ -486,7 +486,6 @@ source_group (LoopAnalyzer FILES ${LOOP_ANALYZER}) source_group (ParallelizationRegions FILES ${PARALLEL_REG}) source_group (MergeRegions FILES ${MERGE_REGIONS}) source_group (PrivateAnalyzer FILES ${PRIV}) -source_group (ArrayConstantPropagation FILES ${ARRAY_PROP}) source_group (FDVM_Compiler FILES ${FDVM}) source_group (SageExtension FILES ${OMEGA}) source_group (Utils FILES ${UTILS}) diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index b08dd5b..e070d17 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -1,36 +1,34 @@ #include #include -#include -#include +#include #include #include #include #include -#include "ArrayConstantPropagation/propagation.h" #include "CFGraph/CFGraph.h" #include "Distribution/Array.h" +#include "errors.h" #include "graph_loops.h" #include "private_arrays_search.h" #include "range_structures.h" #include "region.h" #include "SgUtils.h" +#include "Transformations/ArrayConstantPropagation/propagation.h" #include "utils.h" #include "Utils/AstWrapper.h" using namespace std; extern std::map, std::pair> declaredArrays; +extern map> SPF_messages; -extern unordered_set statementsToRemove; -extern unordered_map>> expToChange; - -static unordered_set collapsed; +static set collapsed; static void RemoveEmptyPoints(ArrayAccessingIndexes& container) { ArrayAccessingIndexes resultContainer; - unordered_set toRemove; + set toRemove; for (auto& [arrayName, accessingSet] : container) { @@ -60,6 +58,7 @@ static void Collapse(Region* region) return; bool firstRegion = true; + int blockCount = 0; for (Region* basickBlock : region->getBasickBlocks()) { if (basickBlock->getNextRegions().empty()) @@ -71,7 +70,7 @@ static void Collapse(Region* region) } else { - unordered_set toErease; + set toErease; for (auto& [arrayName, arrayRanges] : region->array_def) { if (basickBlock->array_out.find(arrayName) != basickBlock->array_out.end()) @@ -91,11 +90,15 @@ static void Collapse(Region* region) RegionInstruction instruction; instruction.def = move(region->array_def); - + ArrayAccessingIndexes recursivePriv; for (auto& byBlock : region->getBasickBlocks()) { + if (!byBlock->array_priv.empty()) + recursivePriv = byBlock->array_priv; for (auto& instruction : byBlock->instructions) { + if (!instruction.def.empty() || !instruction.use.empty()) + blockCount++; for (auto& [arrayName, _] : instruction.use) { AccessingSet diff = instruction.use[arrayName].Diff(instruction.in[arrayName]); @@ -127,67 +130,8 @@ static void Collapse(Region* region) region->addNextRegion(nextBlock); } region->instructions.push_back(instruction); - -} - -static void SolveDataFlowIteratively(Region* DFG) -{ - auto blocks = DFG->getBasickBlocks(); - std::unordered_set worklist(blocks.begin(), blocks.end()); - do - { - Region* b = *worklist.begin(); - ArrayAccessingIndexes newIn; - bool flagFirst = true; - for (Region* prevBlock : b->getPrevRegions()) - { - if (flagFirst) - { - newIn = prevBlock->array_out; - flagFirst = false; - } - else - { - if (prevBlock->array_out.empty()) - { - newIn.clear(); - break; - } - - for (const auto& [arrayName, accessSet] : prevBlock->array_out) - { - if (newIn.find(arrayName) != newIn.end()) - newIn[arrayName] = newIn[arrayName].Intersect(accessSet); - else - newIn[arrayName] = AccessingSet(); - } - } - } - - b->array_in = move(newIn); - ArrayAccessingIndexes newOut; - - if (b->array_def.empty()) - newOut = b->array_in; - else if (b->array_in.empty()) - newOut = b->array_def; - else - { - for (auto& [arrayName, accessSet] : b->array_def) - { - if (newOut.find(arrayName) != newOut.end()) - newOut[arrayName] = b->array_def[arrayName].Union(b->array_in[arrayName]); - else - newOut[arrayName] = accessSet; - } - } - - /* can not differ */ - if (newOut != b->array_out) - b->array_out = newOut; - else - worklist.erase(b); - } while (!worklist.empty()); + if (blockCount == 1 && !recursivePriv.empty()) + region->array_priv = move(recursivePriv); } static void SolveForBasickBlock(Region* block) @@ -380,11 +324,26 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& spfStat->setFileName(loop->loop->fileName()); SgExpression* toAdd = new SgExpression(EXPR_LIST, new SgExpression(ACC_PRIVATE_OP), NULL, NULL); set arraysToInsert; - std::cout << "First bp\n"; - for (const auto& [_, accessingSet] : privates) + for (const auto& [arrayName, accessingSet] : privates) { + int idx = arrayName.find('%'); + string name = (idx != -1 ? arrayName.substr(idx+1) : arrayName); if (!CheckDimensionLength(accessingSet)) + { + wstring messageE, messageR; + __spf_printToLongBuf( + messageE, + L"Private array '%s' was skipped because dimension lengths are inconsistent", + to_wstring(name).c_str()); + __spf_printToLongBuf( + messageR, + R159, + to_wstring("array " + name + " has inconsistent dimension lengths").c_str()); + SPF_messages[loop->loop->fileName()].push_back( + Messages(WARR, loop->loop->lineNumber(), messageR, messageE, 1029)); continue; + } + for (const auto& arrayElement : accessingSet.GetElements()) { if (arrayElement.empty()) @@ -462,20 +421,4 @@ void findPrivateArrays(map>& loopGraph, mapfileName()); - st->deleteStmt(); - } - - for (auto& [filename, statements] : expToChange) - { - SgFile::switchToFile(filename); - for (auto& [statement, statementCopy] : statements) - { - statement->insertStmtBefore(*statementCopy, *statement->controlParent()); - statement->deleteStmt(); - } - } } \ No newline at end of file diff --git a/src/PrivateAnalyzer/private_arrays_search.h b/src/PrivateAnalyzer/private_arrays_search.h index 8b8f02c..cb14a24 100644 --- a/src/PrivateAnalyzer/private_arrays_search.h +++ b/src/PrivateAnalyzer/private_arrays_search.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "range_structures.h" #include "graph_loops.h" diff --git a/src/PrivateAnalyzer/range_structures.cpp b/src/PrivateAnalyzer/range_structures.cpp index f8be53d..340a9e8 100644 --- a/src/PrivateAnalyzer/range_structures.cpp +++ b/src/PrivateAnalyzer/range_structures.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include "utils.h" diff --git a/src/PrivateAnalyzer/range_structures.h b/src/PrivateAnalyzer/range_structures.h index 6a609fc..196cb89 100644 --- a/src/PrivateAnalyzer/range_structures.h +++ b/src/PrivateAnalyzer/range_structures.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/PrivateAnalyzer/region.cpp b/src/PrivateAnalyzer/region.cpp index 4b38739..26fb1b7 100644 --- a/src/PrivateAnalyzer/region.cpp +++ b/src/PrivateAnalyzer/region.cpp @@ -1,8 +1,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -23,9 +23,9 @@ static bool isParentStmt(SgStatement* stmt, SgStatement* parent) } /*returns head block and loop*/ -static pair> GetBasicBlocksForLoop(const LoopGraph* loop, const vector blocks) +pair> GetBasicBlocksForLoop(const LoopGraph* loop, const vector blocks) { - unordered_set block_loop; + set block_loop; SAPFOR::BasicBlock* head_block = nullptr; auto loop_operator = loop->loop->GetOriginal(); for (const auto& block : blocks) @@ -51,16 +51,16 @@ static pair> GetBasicBlo return { head_block, block_loop }; } -static void BuildLoopIndex(map& loopForIndex, LoopGraph* loop) { +static void BuildLoopIndex(map& loopForIndex, LoopGraph* loop) { string index = loop->loopSymbol(); - loopForIndex[index] = loop; + loopForIndex[loop->loop->GetOriginal()] = loop; for (const auto& childLoop : loop->children) BuildLoopIndex(loopForIndex, childLoop); } static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map& loopForIndex) { - unordered_set args = { block->getInstructions()[pos]->getInstruction()->getArg1() }; + set args = { block->getInstructions()[pos]->getInstruction()->getArg1() }; for (int i = pos - 1; i >= 0; i--) { @@ -95,7 +95,7 @@ static string FindIndexName(int pos, SAPFOR::BasicBlock* block, mapgetInstructions(); - map loopForIndex; + map loopForIndex; BuildLoopIndex(loopForIndex, loop); for (int i = 0; i < instructions.size(); i++) { @@ -136,7 +136,6 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces vector index_vars; vector refPos; string array_name = instruction->getInstruction()->getArg1()->getValue(); - int j = i - 1; while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF) { @@ -180,25 +179,16 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces string name, full_name = var->getValue(); int pos = full_name.find('%'); LoopGraph* currentLoop; - if (pos != -1) - { - name = full_name.substr(pos + 1); - if (loopForIndex.find(name) != loopForIndex.end()) - currentLoop = loopForIndex[name]; - else - return -1; - } - else - { - name = FindIndexName(currentVarPos, block, loopForIndex); - if (name == "") - return -1; - if (loopForIndex.find(name) != loopForIndex.end()) - currentLoop = loopForIndex[name]; - else - return -1; - } + auto serachInstr = instruction->getInstruction()->getOperator(); + while (serachInstr && serachInstr->variant() != FOR_NODE) + serachInstr = serachInstr->controlParent(); + + name = full_name.substr(pos + 1); + if (loopForIndex.find(serachInstr) != loopForIndex.end()) + currentLoop = loopForIndex[serachInstr]; + else + return -1; uint64_t start = coeffsForDims.back().second * currentLoop->startVal + coeffsForDims.back().first; uint64_t step = currentLoop->stepVal; @@ -243,7 +233,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces } -static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const unordered_set& blockSet, unordered_map& bbToRegion) +static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const set& blockSet, map& bbToRegion) { for (SAPFOR::BasicBlock* block : blockSet) { @@ -259,18 +249,35 @@ static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const unordered_s } } -static void DFS(Region* block, vector& result, unordered_set cycleBlocks) +static bool DFS(Region* block, + vector& result, + const set& cycleBlocks, + map& color) { + auto it = color.find(block); + if (it != color.end()) + { + if (it->second == 0) + return false; + if (it->second == 1) + return true; + } + color[block] = 0; for (Region* nextBlock : block->getNextRegions()) { - if (cycleBlocks.find(nextBlock) != cycleBlocks.end()) - DFS(nextBlock, result, cycleBlocks); + if (cycleBlocks.find(nextBlock) == cycleBlocks.end()) + continue; + if (!DFS(nextBlock, result, cycleBlocks, color)) + return false; } + color[block] = 1; result.push_back(block); + return true; } -bool HasCycle(Region* block, const std::unordered_set& cycleBlocks, std::unordered_set& visitedBlocks) +bool HasCycle(Region* block, const std::set& cycleBlocks, std::set& visitedBlocks) { + return false; if (visitedBlocks.find(block) != visitedBlocks.end()) return true; visitedBlocks.insert(block); @@ -284,18 +291,17 @@ bool HasCycle(Region* block, const std::unordered_set& cycleBlocks, std bool TopologySort(std::vector& basikBlocks, Region* header) { - unordered_set cycleBlocks(basikBlocks.begin(), basikBlocks.end()); - unordered_set visitedBlocks; - if (HasCycle(header, cycleBlocks, visitedBlocks)) - return false; + set cycleBlocks(basikBlocks.begin(), basikBlocks.end()); vector result; - DFS(header, result, cycleBlocks); + map color; + if (!DFS(header, result, cycleBlocks, color)) + return false; reverse(result.begin(), result.end()); basikBlocks = move(result); return true; } -static void SetConnections(unordered_map& bbToRegion, const unordered_set& blockSet) +static void SetConnections(map& bbToRegion, const set& blockSet) { for (SAPFOR::BasicBlock* block : blockSet) { @@ -309,7 +315,7 @@ static void SetConnections(unordered_map& bbToRegi } } -static Region* CreateSubRegion(LoopGraph* loop, const vector& Blocks, unordered_map& bbToRegion) +static Region* CreateSubRegion(LoopGraph* loop, const vector& Blocks, map& bbToRegion) { Region* region = new Region; auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); @@ -340,7 +346,7 @@ static Region* CreateSubRegion(LoopGraph* loop, const vector& Blocks) { auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); - unordered_map bbToRegion; + map bbToRegion; for (auto poiner : blockSet) { bbToRegion[poiner] = new Region(*poiner); diff --git a/src/PrivateAnalyzer/region.h b/src/PrivateAnalyzer/region.h index 2b39af2..adecfe6 100644 --- a/src/PrivateAnalyzer/region.h +++ b/src/PrivateAnalyzer/region.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include "graph_loops.h" @@ -29,9 +29,9 @@ public: void addBasickBlocks(Region* region) { basickBlocks.push_back(region); } - const std::unordered_set& getPrevRegions() { return prevRegions; } + const std::set& getPrevRegions() { return prevRegions; } - std::unordered_set& getNextRegions() { return nextRegions; } + std::set& getNextRegions() { return nextRegions; } void removeNextRegion(Region* region) { @@ -61,7 +61,7 @@ public: nextRegions.insert(source); } - std::unordered_set getSubRegions() { return subRegions; } + std::set getSubRegions() { return subRegions; } void addSubRegions(Region* region) { subRegions.insert(region); } @@ -71,14 +71,14 @@ public: private: std::vector basickBlocks; - std::unordered_set subRegions; + std::set subRegions; /*next Region which is BB for current BB Region*/ - std::unordered_set nextRegions; + std::set nextRegions; /*prev Regions which is BBs for current BB Region*/ - std::unordered_set prevRegions; + std::set prevRegions; Region* header; }; -bool HasCycle(Region* block, const std::unordered_set& cycleBlocks, std::unordered_set& visitedBlocks); +bool HasCycle(Region* block, const std::set& cycleBlocks, std::set& visitedBlocks); bool TopologySort(std::vector& basikBlocks, Region* header); \ No newline at end of file diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index 5a89c73..eb60e0b 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1910,6 +1910,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne mergeRegions(parallelRegions, allFuncInfo); else if (curr_regime == ARRAY_PROPAGATION) arrayConstantPropagation(project); + else if (curr_regime == ARRAY_PROPAGATION_RESTORE) + restoreArrays(); const float elapsed = duration_cast(high_resolution_clock::now() - timeForPass).count() / 1000.; const float elapsedGlobal = duration_cast(high_resolution_clock::now() - globalTime).count() / 1000.; diff --git a/src/Sapfor.h b/src/Sapfor.h index bae94fb..a10a2d0 100644 --- a/src/Sapfor.h +++ b/src/Sapfor.h @@ -192,6 +192,7 @@ enum passes { TRANSFORM_ASSUMED_SIZE_PARAMETERS, ARRAY_PROPAGATION, + ARRAY_PROPAGATION_RESTORE, TEST_PASS, EMPTY_PASS @@ -384,7 +385,7 @@ static void setPassValues() passNames[TRANSFORM_ASSUMED_SIZE_PARAMETERS] = "TRANSFORM_ASSUMED_SIZE_PARAMETERS"; passNames[ARRAY_PROPAGATION] = "ARRAY_PROPAGATION"; - + passNames[ARRAY_PROPAGATION_RESTORE] = "ARRAY_PROPAGATION_RESTORE"; passNames[TEST_PASS] = "TEST_PASS"; } diff --git a/src/Transformations/ArrayConstantPropagation/propagation.cpp b/src/Transformations/ArrayConstantPropagation/propagation.cpp index 034c6b4..356bd59 100644 --- a/src/Transformations/ArrayConstantPropagation/propagation.cpp +++ b/src/Transformations/ArrayConstantPropagation/propagation.cpp @@ -2,48 +2,33 @@ #include "../Utils/SgUtils.h" -#include #include -#include -#include +#include +#include +#include #include using namespace std; -namespace { - - struct MyHash { - size_t operator()(const SgSymbol* s) const { - return std::hash{}(s->identifier()); - } - }; - - struct MyEq { - bool operator()(const SgSymbol* a, const SgSymbol* b) const { - return std::strcmp(a->identifier(), b->identifier()) == 0; - } - }; - -} - -SgStatement* declPlace = NULL; -unordered_set changed; -unordered_set variablesToAdd; -unordered_set positionsToAdd; -unordered_set statementsToRemove; -unordered_map>> expToChange; +static SgStatement* declPlace = NULL; +static set changed; +static map variablesToAdd; +static map> positionsToAdd; +static map arrayToName; +static set statementsToRemove; +static map> expToChange; static bool CheckConstIndexes(SgExpression* exp) { if (!exp) { - return true; + return false; } SgExpression* lhs = exp->lhs(); SgExpression* rhs = exp->rhs(); do { - if (lhs->variant() != INT_VAL) + if (lhs && lhs->variant() != INT_VAL) { return false; } @@ -58,21 +43,23 @@ static bool CheckConstIndexes(SgExpression* exp) static SgExpression* CreateVar(int& variableNumber, SgType* type) { - string varName = "__tmp_prop_var"; + string varName = "tmp_prop_var"; string name = varName + std::to_string(variableNumber) + "__"; variableNumber++; SgStatement* funcStart = declPlace->controlParent(); - SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *funcStart); + SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), SgTypeInt(), funcStart); - variablesToAdd.insert(varSymbol); - positionsToAdd.insert(declPlace); + variablesToAdd[name] = varSymbol; + positionsToAdd[string(declPlace->fileName())].insert(declPlace); return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr()); } static SgStatement* FindLastDeclStatement(SgStatement* funcStart) { + if (!funcStart) + return NULL; SgStatement* endSt = funcStart->lastNodeOfStmt(); SgStatement* cur = funcStart->lexNext(); SgStatement* lastDecl = funcStart; @@ -95,19 +82,22 @@ static SgStatement* FindLastDeclStatement(SgStatement* funcStart) return lastDecl; } -static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unordered_set& symbols) +static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map& symbols) { if (symbols.empty()) return; - const string commonBlockName = "__propagation_common__"; + if (!funcStart) + return; + + const string commonBlockName = "propagation_common__"; SgStatement* funcEnd = funcStart->lastNodeOfStmt(); SgStatement* commonStat = NULL; SgExpression* commonList = NULL; for (SgStatement* cur = funcStart->lexNext(); - cur && cur != funcEnd; cur = cur->lexNext()) + cur && cur != funcEnd; cur = cur->lexNext()) { if (cur->variant() != COMM_STAT) continue; @@ -131,18 +121,20 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unorde } vector varRefs; - for (SgSymbol* sym : symbols) + for (const auto& [name, sym] : symbols) { if (!sym || sym->variant() != VARIABLE_NAME || string(sym->identifier()) == commonBlockName) continue; - SgSymbol* symToAdd = new SgSymbol(VARIABLE_NAME, sym->identifier(), *sym->type(), *funcStart); + SgSymbol* symToAdd = new SgSymbol(VARIABLE_NAME, name.c_str(), SgTypeInt(), funcStart); varRefs.push_back(new SgVarRefExp(symToAdd)); } SgExpression* varList = makeExprList(varRefs, false); SgStatement* insertAfter = FindLastDeclStatement(funcStart); - for (SgSymbol* sym : symbols) + for (const auto& [name, sym] : symbols) { + if (!sym) + continue; SgStatement* declStmt = sym->makeVarDeclStmt(); if (!declStmt) continue; @@ -183,63 +175,89 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unorde } -static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) +static void copyStatement(SgStatement* st) +{ + if (!st) + return; + if (expToChange[st->fileName()].find(st) == expToChange[st->fileName()].end()) + { + SgStatement* boundCopy = st->copyPtr(); + + for (int i = 0; i < 3; i++) + { + SgExpression* expCopy = st->expr(i); + if (expCopy) + boundCopy->setExpression(i, expCopy->copyPtr()); + else + boundCopy->setExpression(i, NULL); + } + expToChange[st->fileName()][st] = boundCopy; + } +} + +static bool TransformRightPart(SgStatement* st, SgExpression* exp, map& arrayToVariable, int& variableNumber) { if (!exp) - return; + return false; + bool isChanged = false; vector subnodes = { exp->lhs(), exp->rhs() }; string expUnparsed; SgExpression* toAdd = NULL; - if (exp->variant() == ARRAY_REF && CheckConstIndexes(exp->lhs())) + if (isArrayRef(exp) && CheckConstIndexes(exp->lhs())) { expUnparsed = exp->unparse(); - if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) + if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp && exp->symbol() && + exp->symbol()->type() && exp->symbol()->type()->baseType()) { - arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); + arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); + arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); } - positionsToAdd.insert(declPlace); - SgSymbol* builder = arrayToVariable[expUnparsed]->symbol(); - auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent()); + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + auto* sym = new SgSymbol(VARIABLE_NAME, arrayToName[expUnparsed].c_str(), SgTypeInt(), declPlace->controlParent()); auto* newVarExp = new SgVarRefExp(sym); - expToChange[st->fileName()].push_back({ st , st->copyPtr() }); + copyStatement(st); st->setExpression(1, newVarExp); - return; + return true; } for (int i = 0; i < 2; i++) { - if (subnodes[i] && subnodes[i]->variant() == ARRAY_REF && subnodes[i]->symbol()->type()->baseType() && CheckConstIndexes(subnodes[i]->lhs())) + if (subnodes[i] && isArrayRef(subnodes[i]) && subnodes[i]->symbol() && subnodes[i]->symbol()->type() && + subnodes[i]->symbol()->type()->baseType() && CheckConstIndexes(subnodes[i]->lhs())) { + isChanged = true; expUnparsed = subnodes[i]->unparse(); - if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) + if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) + { arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType()); - - positionsToAdd.insert(declPlace); + arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); + } + positionsToAdd[string(declPlace->fileName())].insert(declPlace); SgSymbol* builder = arrayToVariable[expUnparsed]->symbol(); - auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent()); + auto* sym = new SgSymbol(VARIABLE_NAME, arrayToName[expUnparsed].c_str(), SgTypeInt(), declPlace->controlParent()); toAdd = new SgVarRefExp(sym); if (toAdd) { + copyStatement(st); if (i == 0) - { - expToChange[st->fileName()].push_back({ st , st->copyPtr() });; exp->setLhs(toAdd); - } else - { - expToChange[st->fileName()].push_back({ st , st->copyPtr() });; exp->setRhs(toAdd); - } } } else - TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber); - + isChanged = isChanged || TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber); + } + return isChanged; } -static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) +static void TransformLeftPart(SgStatement* st, SgExpression* exp, map& arrayToVariable, int& variableNumber) { + if (!st || !st->expr(1)) + return; + if (!exp || !exp->symbol() || !exp->symbol()->type() || !exp->symbol()->type()->baseType()) + return; if (exp->symbol()->type()->variant() == T_STRING) return; if (changed.find(st) != changed.end()) @@ -248,76 +266,278 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map< if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) { arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); + arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); } - positionsToAdd.insert(declPlace); - SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, arrayToVariable[expUnparsed]->copyPtr(), st->expr(1)->copyPtr(), NULL); + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + auto* sym = new SgSymbol(VARIABLE_NAME, arrayToName[expUnparsed].c_str(), SgTypeInt(), declPlace->controlParent()); + auto* newVarExp = new SgVarRefExp(sym); + SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, newVarExp, st->expr(1)->copyPtr(), NULL); newStatement->setFileId(st->getFileId()); - newStatement->setProject(st->getProject()); + newStatement->setProject(st->getProject()); + + st->insertStmtBefore(*newStatement, *st->controlParent()); newStatement->setlineNumber(getNextNegativeLineNumber()); newStatement->setLocalLineNumber(st->lineNumber()); - st->insertStmtBefore(*newStatement, *st->controlParent()); + changed.insert(st); statementsToRemove.insert(newStatement); } -static void TransformBorder(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) +static void TransformBorder(SgStatement* st, SgExpression* exp, map& arrayToVariable, int& variableNumber) { + if (!st || !exp) + return; SgStatement* firstStatement = declPlace->lexPrev(); + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + TransformRightPart(st, exp, arrayToVariable, variableNumber); st = st->lexPrev(); - string array = exp->unparse(); - if (arrayToVariable.find(array) == arrayToVariable.end()) - arrayToVariable[array] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); - while (st != firstStatement) + while (st &&st != firstStatement) { - if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) + if (st->variant() == ASSIGN_STAT) { if (st->expr(1)) { TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); } - if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) + if (st->expr(0) && isArrayRef(st->expr(0)) && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); } st = st->lexPrev(); } } -static void CheckVariable(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) +static void CheckVariable(SgStatement* st, SgExpression* exp, map& arrayToVariable, int& variableNumber) { SgStatement* firstStatement = declPlace->lexPrev(); st = st->lexPrev(); - string varName = exp->unparse(); while (st != firstStatement) { if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol()) { - TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); - positionsToAdd.insert(declPlace); + if (TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber)) + { + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + } } if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) { if (st->expr(1)) { - TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); - positionsToAdd.insert(declPlace); + if(TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber)) + { + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + } } - if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) + if (st->expr(0) && isArrayRef(st->expr(0)) && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) { TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); - positionsToAdd.insert(declPlace); + positionsToAdd[string(declPlace->fileName())].insert(declPlace); } } st = st->lexPrev(); } } -void arrayConstantPropagation(SgProject& project) +static void findConstValues( + SgProject& project, + const map>& borderVars, + const map& arrayToVariable, + map& hitCount, + map>>>& result) { - unordered_map arrayToVariable; + for (int i = 0; i < project.numberOfFiles(); i++) + { + SgFile* file = &(project.file(i)); + if (!file) + continue; + + SgFile::switchToFile(file->filename()); + const int funcNum = file->numberOfFunctions(); + for (int i = 0; i < funcNum; ++i) + { + SgStatement* st = file->functions(i); + SgStatement* lastNode = st->lastNodeOfStmt(); + if (!st) + continue; + for (; st != lastNode; st = st->lexNext()) + { + if (st && st->variant() == ASSIGN_STAT) + { + if (!st->expr(0) || !st->expr(1)) + continue; + SgExpression* lhs = st->expr(0); + SgExpression* rhs = st->expr(1); + auto varIt = arrayToVariable.find(lhs->unparse()); + string varName = (varIt != arrayToVariable.end()) ? varIt->second->unparse() : lhs->unparse(); + if (rhs->variant() == INT_VAL) + hitCount[string(lhs->unparse())]++; + for (const auto& [filename, names] : borderVars) + { + if(names.find(string(lhs->unparse())) != names.end() && rhs->variant() == INT_VAL) + result[filename][names.at(lhs->unparse())].push_back({ varName, rhs->unparse()}); + } + } + } + } + } +} + +static void insertDefinition(map>>>& definitions, map& hitCount) +{ + for (const auto& [filename, variables] : definitions) + { + if (SgFile::switchToFile(filename) == -1) + continue; + + for (const auto& [statement, values] : variables) + { + if (!statement) + continue; + + SgStatement* insertBefore = statement, *st = statement; + + while (st && !isSgExecutableStatement(st)) + { + st = st->lexNext(); + insertBefore = st; + } + + for (const auto& [varName, value] : values) + { + if (hitCount.find(varName) == hitCount.end() || hitCount[varName] > 1) + continue; + SgSymbol* sym = new SgSymbol(VARIABLE_NAME, varName.c_str(), SgTypeInt(), statement); + SgExpression* lhs = new SgVarRefExp(sym); + + SgExpression* rhs = new SgValueExp(stoi(value)); + + SgStatement* asg = new SgStatement(ASSIGN_STAT, NULL, NULL, lhs, rhs, NULL); + asg->setFileName(statement->fileName()); + asg->setFileId(statement->getFileId()); + asg->setProject(statement->getProject()); + asg->setlineNumber(getNextNegativeLineNumber()); + + if (insertBefore && insertBefore->controlParent()) + { + insertBefore->insertStmtBefore(*asg, *insertBefore->controlParent()); + statementsToRemove.insert(asg); + } + } + } + } +} + +static void applyLeftPartForUnchangedAssignments(SgProject& project, map& arrayToVariable, int& variableNumber) +{ + for (int fi = 0; fi < project.numberOfFiles(); ++fi) + { + SgFile* file = &(project.file(fi)); + if (!file) + continue; + + const string fileName = file->filename(); + if (SgFile::switchToFile(fileName) == -1) + continue; + + const int funcNum = file->numberOfFunctions(); + for (int fni = 0; fni < funcNum; ++fni) + { + SgStatement* funcStart = file->functions(fni); + if (!funcStart) + continue; + + declPlace = funcStart; + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + SgStatement* endSt = funcStart->lastNodeOfStmt(); + + for (SgStatement* st = funcStart; st && st != endSt; st = st->lexNext()) + { + if (st->variant() != ASSIGN_STAT) + continue; + if (!st->expr(0) || !st->expr(1)) + continue; + if (changed.find(st) != changed.end()) + continue; + + SgExpression* lhs = st->expr(0); + if (!isArrayRef(lhs)) + continue; + if (!lhs->symbol() || !lhs->symbol()->type()) + continue; + if (!lhs->symbol()->type()->baseType()) + continue; + if (!CheckConstIndexes(lhs->lhs())) + continue; + + const string lhsUnparsed = lhs->unparse(); + if (arrayToVariable.find(lhsUnparsed) == arrayToVariable.end()) + continue; + + TransformLeftPart(st, lhs, arrayToVariable, variableNumber); + } + } + } +} + +static bool ContainsArrayRefRecursive(SgExpression* exp) +{ + if (!exp) + return false; + + if (isArrayRef(exp) && CheckConstIndexes(exp->lhs())) + return true; + + return ContainsArrayRefRecursive(exp->lhs()) || ContainsArrayRefRecursive(exp->rhs()); +} + +static void getBorderVars(SgExpression* exp, const string& filename, map>& borderVars) +{ + if (!exp) + return; + + if ((isArrayRef(exp) && CheckConstIndexes(exp->lhs())) || exp->variant() == VAR_REF) + borderVars[filename][string(exp->unparse())] = declPlace; + + getBorderVars(exp->lhs(), filename, borderVars); + getBorderVars(exp->rhs(), filename, borderVars); +} + +static void processLoopBound( + SgStatement* st, + SgExpression* bound, + const string& boundUnparsed, + bool isUpperBound, + map& arrayToVariable, + map>& borderVars, + int& variableNumber) +{ + if (!bound || !st) + return; + + SgExpression* exp = isUpperBound ? bound->rhs() : bound->lhs(); + + getBorderVars(exp, st->fileName(), borderVars); + + if (ContainsArrayRefRecursive(exp), borderVars, st->fileName()) + { + copyStatement(st); + + TransformBorder(st, bound, arrayToVariable, variableNumber); + + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + } + else if (bound->variant() == VAR_REF) + CheckVariable(st, bound, arrayToVariable, variableNumber); +} + +void arrayConstantPropagation(SgProject& project) +{ + map arrayToVariable; + map> borderVars; int variableNumber = 0; - for (int i = 0; i < project.numberOfFiles(); i++) + for (int i = 0; i < project.numberOfFiles(); i++) { SgFile* file = &(project.file(i)); @@ -328,53 +548,83 @@ void arrayConstantPropagation(SgProject& project) for (int i = 0; i < funcNum; ++i) { SgStatement* st = file->functions(i); - declPlace = st->lexNext(); + if (!st) + continue; + declPlace = st; SgStatement* lastNode = st->lastNodeOfStmt(); for (; st != lastNode; st = st->lexNext()) { - if (st->variant() == FOR_NODE) + if (st && st->variant() == FOR_NODE) { + if (!st->expr(0)) + continue; + if (!st->expr(0)->lhs() || !st->expr(0)->rhs()) + continue; SgExpression* lowerBound = st->expr(0)->lhs(); SgExpression* upperBound = st->expr(0)->rhs(); - SgStatement* boundCopy = NULL; - string lowerBoundUnparsed = lowerBound->unparse(), upperBoundUnparsed = upperBound->unparse(); - if (upperBound->variant() == ARRAY_REF && upperBound->symbol()->type()->baseType() && CheckConstIndexes(upperBound->lhs())) - { - boundCopy = st->copyPtr(); - TransformBorder(st, upperBound, arrayToVariable, variableNumber); - st->expr(0)->setRhs(arrayToVariable[upperBoundUnparsed]->copyPtr()); - expToChange[st->fileName()].push_back({ st ,boundCopy });; - positionsToAdd.insert(declPlace); - } - else if (upperBound->variant() == VAR_REF) - CheckVariable(st, upperBound, arrayToVariable, variableNumber); + - if (lowerBound->variant() == ARRAY_REF && lowerBound->symbol()->type()->baseType() && CheckConstIndexes(lowerBound->lhs())) - { - boundCopy = st->copyPtr(); - TransformBorder(st, lowerBound, arrayToVariable, variableNumber); - st->expr(0)->setLhs(arrayToVariable[lowerBoundUnparsed]->copyPtr()); - expToChange[st->fileName()].push_back({ st , boundCopy });; - positionsToAdd.insert(declPlace); - } - else if (lowerBound->variant() == VAR_REF) - CheckVariable(st, lowerBound, arrayToVariable, variableNumber); + string lowerBoundUnparsed = lowerBound->unparse(); + string upperBoundUnparsed = upperBound->unparse(); + + processLoopBound(st, st->expr(0), upperBoundUnparsed, true, arrayToVariable, borderVars, variableNumber); + processLoopBound(st, st->expr(0), lowerBoundUnparsed, false, arrayToVariable, borderVars, variableNumber); + } } } } - unordered_set funcStarts; - for (SgStatement* st : positionsToAdd) + applyLeftPartForUnchangedAssignments(project, arrayToVariable, variableNumber); + map> funcStarts; + for (const auto& [fileName, statements] : positionsToAdd) + { + int res = SgFile::switchToFile(fileName); + if (res == -1) + continue; + for (SgStatement* st : statements) + { + SgStatement* scope = isSgProgHedrStmt(st) ? st : st->controlParent(); + if (scope) + funcStarts[fileName].insert(scope); + } + } + for (const auto& [fileName, statements] : funcStarts) + { + SgFile::switchToFile(fileName); + for (SgStatement* st : statements) + { + InsertCommonAndDeclsForFunction(st, variablesToAdd); + } + } + map>>> result; + map hitCount; + findConstValues(project, borderVars, arrayToVariable, hitCount, result); + insertDefinition(result, hitCount); +} + +void restoreArrays() +{ + for (auto& [filename, statements] : expToChange) + { + if (SgFile::switchToFile(filename) == -1) + continue; + for (auto& [statement, statementCopy] : statements) + { + if (statement && statementCopy) + { + for (int i = 0; i < 3; i++) + { + statement->setExpression(i, statementCopy->expr(i)); + } + + } + } + } + + for (SgStatement* st : statementsToRemove) { SgFile::switchToFile(st->fileName()); - SgStatement* scope = st->controlParent(); - if (scope) - funcStarts.insert(scope); + st->deleteStmt(); } - for (const auto& st : funcStarts) - { - SgFile::switchToFile(st->fileName()); - InsertCommonAndDeclsForFunction(st, variablesToAdd); - } -} \ No newline at end of file +} diff --git a/src/Transformations/ArrayConstantPropagation/propagation.h b/src/Transformations/ArrayConstantPropagation/propagation.h index 65fe4ed..190bd03 100644 --- a/src/Transformations/ArrayConstantPropagation/propagation.h +++ b/src/Transformations/ArrayConstantPropagation/propagation.h @@ -6,15 +6,6 @@ using namespace std; -struct ExprRestoreEntry -{ - enum Kind { kStatementExpr, kExprChild }; - Kind kind; - SgStatement* stmt; - int stmtExprIndex; - SgExpression* parent; - bool childIsRhs; - SgExpression* savedCopy; -}; -void arrayConstantPropagation(SgProject& project); \ No newline at end of file +void arrayConstantPropagation(SgProject& project); +void restoreArrays(); diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index 68a6f6b..cca9f91 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -319,7 +319,7 @@ void InitPassesDependencies(map> &passDepsIn, set list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE); list({ ARRAY_PROPAGATION, CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS); - list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS); + list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD, ARRAY_PROPAGATION_RESTORE }) <= Pass(FIND_PRIVATE_ARRAYS); list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS); Pass(CREATE_TEMPLATE_LINKS) <= Pass(MERGE_REGIONS); diff --git a/src/Utils/version.h b/src/Utils/version.h index 0646b65..e649f40 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2482" +#define VERSION_SPF "2483" From 357f961d68fc598af8fd1e5188d530981be057e3 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Fri, 1 May 2026 12:03:41 +0300 Subject: [PATCH 25/32] refactored arrays propagation pass --- src/Sapfor.cpp | 2 +- .../ArrayConstantPropagation/propagation.cpp | 161 +++++++++--------- .../ArrayConstantPropagation/propagation.h | 2 +- src/Utils/version.h | 2 +- 4 files changed, 88 insertions(+), 79 deletions(-) diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index eb60e0b..fcb4294 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1911,7 +1911,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne else if (curr_regime == ARRAY_PROPAGATION) arrayConstantPropagation(project); else if (curr_regime == ARRAY_PROPAGATION_RESTORE) - restoreArrays(); + arrayConstantPropagationRrestore(); const float elapsed = duration_cast(high_resolution_clock::now() - timeForPass).count() / 1000.; const float elapsedGlobal = duration_cast(high_resolution_clock::now() - globalTime).count() / 1000.; diff --git a/src/Transformations/ArrayConstantPropagation/propagation.cpp b/src/Transformations/ArrayConstantPropagation/propagation.cpp index 356bd59..81c48cc 100644 --- a/src/Transformations/ArrayConstantPropagation/propagation.cpp +++ b/src/Transformations/ArrayConstantPropagation/propagation.cpp @@ -15,10 +15,11 @@ static set changed; static map variablesToAdd; static map> positionsToAdd; static map arrayToName; -static set statementsToRemove; +static map> statementsToRemove; static map> expToChange; +static int variableNumber = 0; -static bool CheckConstIndexes(SgExpression* exp) +static bool checkConstIndexes(SgExpression* exp) { if (!exp) { @@ -41,7 +42,7 @@ static bool CheckConstIndexes(SgExpression* exp) return true; } -static SgExpression* CreateVar(int& variableNumber, SgType* type) +static SgExpression* createVar(SgType* type) { string varName = "tmp_prop_var"; string name = varName + std::to_string(variableNumber) + "__"; @@ -56,10 +57,11 @@ static SgExpression* CreateVar(int& variableNumber, SgType* type) return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr()); } -static SgStatement* FindLastDeclStatement(SgStatement* funcStart) +static SgStatement* findLastDeclStatement(SgStatement* funcStart) { if (!funcStart) return NULL; + SgStatement* endSt = funcStart->lastNodeOfStmt(); SgStatement* cur = funcStart->lexNext(); SgStatement* lastDecl = funcStart; @@ -82,7 +84,7 @@ static SgStatement* FindLastDeclStatement(SgStatement* funcStart) return lastDecl; } -static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map& symbols) +static void insertCommonAndDeclsForFunction(SgStatement* funcStart, const map& symbols) { if (symbols.empty()) return; @@ -90,7 +92,7 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const maplastNodeOfStmt(); SgStatement* commonStat = NULL; @@ -130,7 +132,7 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const mapinsertStmtAfter(*declStmt, *funcStart); insertAfter = declStmt; - statementsToRemove.insert(declStmt); + statementsToRemove[declStmt->fileName()].insert(declStmt); } if (!commonList) @@ -164,14 +166,12 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const mapsetlineNumber(getNextNegativeLineNumber()); commonStat->setExpression(0, commonList); - SgStatement* lastDecl = FindLastDeclStatement(funcStart); + SgStatement* lastDecl = findLastDeclStatement(funcStart); lastDecl->insertStmtAfter(*commonStat, *funcStart); - statementsToRemove.insert(commonStat); + statementsToRemove[commonStat->fileName()].insert(commonStat); } else - { commonList->setLhs(varList); - } } @@ -179,6 +179,7 @@ static void copyStatement(SgStatement* st) { if (!st) return; + if (expToChange[st->fileName()].find(st) == expToChange[st->fileName()].end()) { SgStatement* boundCopy = st->copyPtr(); @@ -195,7 +196,7 @@ static void copyStatement(SgStatement* st) } } -static bool TransformRightPart(SgStatement* st, SgExpression* exp, map& arrayToVariable, int& variableNumber) +static bool transformRightPart(SgStatement* st, SgExpression* exp, map& arrayToVariable) { if (!exp) return false; @@ -204,13 +205,13 @@ static bool TransformRightPart(SgStatement* st, SgExpression* exp, maplhs())) + if (isArrayRef(exp) && checkConstIndexes(exp->lhs())) { expUnparsed = exp->unparse(); if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp && exp->symbol() && exp->symbol()->type() && exp->symbol()->type()->baseType()) { - arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); + arrayToVariable[expUnparsed] = createVar(exp->symbol()->type()->baseType()); arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); } positionsToAdd[string(declPlace->fileName())].insert(declPlace); @@ -220,16 +221,17 @@ static bool TransformRightPart(SgStatement* st, SgExpression* exp, mapsetExpression(1, newVarExp); return true; } + for (int i = 0; i < 2; i++) { if (subnodes[i] && isArrayRef(subnodes[i]) && subnodes[i]->symbol() && subnodes[i]->symbol()->type() && - subnodes[i]->symbol()->type()->baseType() && CheckConstIndexes(subnodes[i]->lhs())) + subnodes[i]->symbol()->type()->baseType() && checkConstIndexes(subnodes[i]->lhs())) { isChanged = true; expUnparsed = subnodes[i]->unparse(); if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) { - arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType()); + arrayToVariable[expUnparsed] = createVar(subnodes[i]->symbol()->type()->baseType()); arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); } positionsToAdd[string(declPlace->fileName())].insert(declPlace); @@ -246,13 +248,13 @@ static bool TransformRightPart(SgStatement* st, SgExpression* exp, map& arrayToVariable, int& variableNumber) +static void transformLeftPart(SgStatement* st, SgExpression* exp, map& arrayToVariable) { if (!st || !st->expr(1)) return; @@ -262,10 +264,11 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, mapunparse(); if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) { - arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); + arrayToVariable[expUnparsed] = createVar(exp->symbol()->type()->baseType()); arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); } positionsToAdd[string(declPlace->fileName())].insert(declPlace); @@ -282,16 +285,16 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, mapsetLocalLineNumber(st->lineNumber()); changed.insert(st); - statementsToRemove.insert(newStatement); + statementsToRemove[newStatement->fileName()].insert(newStatement); } -static void TransformBorder(SgStatement* st, SgExpression* exp, map& arrayToVariable, int& variableNumber) +static void transformBorder(SgStatement* st, SgExpression* exp, map& arrayToVariable) { if (!st || !exp) return; SgStatement* firstStatement = declPlace->lexPrev(); positionsToAdd[string(declPlace->fileName())].insert(declPlace); - TransformRightPart(st, exp, arrayToVariable, variableNumber); + transformRightPart(st, exp, arrayToVariable); st = st->lexPrev(); while (st &&st != firstStatement) { @@ -299,16 +302,16 @@ static void TransformBorder(SgStatement* st, SgExpression* exp, mapexpr(1)) { - TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); + transformRightPart(st, st->expr(1), arrayToVariable); } - if (st->expr(0) && isArrayRef(st->expr(0)) && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) - TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); + if (st->expr(0) && isArrayRef(st->expr(0)) && checkConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) + transformLeftPart(st, st->expr(0), arrayToVariable); } st = st->lexPrev(); } } -static void CheckVariable(SgStatement* st, SgExpression* exp, map& arrayToVariable, int& variableNumber) +static void checkVariable(SgStatement* st, SgExpression* exp, map& arrayToVariable) { SgStatement* firstStatement = declPlace->lexPrev(); st = st->lexPrev(); @@ -316,23 +319,24 @@ static void CheckVariable(SgStatement* st, SgExpression* exp, mapvariant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol()) { - if (TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber)) + if (transformRightPart(st, st->expr(1), arrayToVariable)) { positionsToAdd[string(declPlace->fileName())].insert(declPlace); } } + if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) { if (st->expr(1)) { - if(TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber)) + if(transformRightPart(st, st->expr(1), arrayToVariable)) { positionsToAdd[string(declPlace->fileName())].insert(declPlace); } } - if (st->expr(0) && isArrayRef(st->expr(0)) && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) + if (st->expr(0) && isArrayRef(st->expr(0)) && checkConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) { - TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); + transformLeftPart(st, st->expr(0), arrayToVariable); positionsToAdd[string(declPlace->fileName())].insert(declPlace); } } @@ -340,12 +344,11 @@ static void CheckVariable(SgStatement* st, SgExpression* exp, map>& borderVars, - const map& arrayToVariable, - map& hitCount, - map>>>& result) +static void findConstValues(SgProject& project, + const map>& borderVars, + const map& arrayToVariable, + map& hitCount, + map>>>& result) { for (int i = 0; i < project.numberOfFiles(); i++) { @@ -422,14 +425,14 @@ static void insertDefinition(mapcontrolParent()) { insertBefore->insertStmtBefore(*asg, *insertBefore->controlParent()); - statementsToRemove.insert(asg); + statementsToRemove[asg->fileName()].insert(asg); } } } } } -static void applyLeftPartForUnchangedAssignments(SgProject& project, map& arrayToVariable, int& variableNumber) +static void applyLeftPartForUnchangedAssignments(SgProject& project, map& arrayToVariable) { for (int fi = 0; fi < project.numberOfFiles(); ++fi) { @@ -468,28 +471,28 @@ static void applyLeftPartForUnchangedAssignments(SgProject& project, mapsymbol()->type()->baseType()) continue; - if (!CheckConstIndexes(lhs->lhs())) + if (!checkConstIndexes(lhs->lhs())) continue; const string lhsUnparsed = lhs->unparse(); if (arrayToVariable.find(lhsUnparsed) == arrayToVariable.end()) continue; - TransformLeftPart(st, lhs, arrayToVariable, variableNumber); + transformLeftPart(st, lhs, arrayToVariable); } } } } -static bool ContainsArrayRefRecursive(SgExpression* exp) +static bool containsArrayRefRecursive(SgExpression* exp) { if (!exp) return false; - if (isArrayRef(exp) && CheckConstIndexes(exp->lhs())) + if (isArrayRef(exp) && checkConstIndexes(exp->lhs())) return true; - return ContainsArrayRefRecursive(exp->lhs()) || ContainsArrayRefRecursive(exp->rhs()); + return containsArrayRefRecursive(exp->lhs()) || containsArrayRefRecursive(exp->rhs()); } static void getBorderVars(SgExpression* exp, const string& filename, map>& borderVars) @@ -497,21 +500,19 @@ static void getBorderVars(SgExpression* exp, const string& filename, maplhs())) || exp->variant() == VAR_REF) + if ((isArrayRef(exp) && checkConstIndexes(exp->lhs())) || exp->variant() == VAR_REF) borderVars[filename][string(exp->unparse())] = declPlace; getBorderVars(exp->lhs(), filename, borderVars); getBorderVars(exp->rhs(), filename, borderVars); } -static void processLoopBound( - SgStatement* st, - SgExpression* bound, - const string& boundUnparsed, - bool isUpperBound, - map& arrayToVariable, - map>& borderVars, - int& variableNumber) +static void processLoopBound(SgStatement* st, + SgExpression* bound, + const string& boundUnparsed, + bool isUpperBound, + map& arrayToVariable, + map>& borderVars) { if (!bound || !st) return; @@ -520,36 +521,40 @@ static void processLoopBound( getBorderVars(exp, st->fileName(), borderVars); - if (ContainsArrayRefRecursive(exp), borderVars, st->fileName()) + if (containsArrayRefRecursive(exp), borderVars, st->fileName()) { copyStatement(st); - TransformBorder(st, bound, arrayToVariable, variableNumber); + transformBorder(st, bound, arrayToVariable); positionsToAdd[string(declPlace->fileName())].insert(declPlace); } else if (bound->variant() == VAR_REF) - CheckVariable(st, bound, arrayToVariable, variableNumber); + checkVariable(st, bound, arrayToVariable); } void arrayConstantPropagation(SgProject& project) { map arrayToVariable; map> borderVars; - int variableNumber = 0; + for (int i = 0; i < project.numberOfFiles(); i++) { - SgFile* file = &(project.file(i)); + SgFile *file = &(project.file(i)); if (!file) - continue; - SgFile::switchToFile(file->filename()); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + if (SgFile::switchToFile(file->filename()) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + const int funcNum = file->numberOfFunctions(); for (int i = 0; i < funcNum; ++i) { SgStatement* st = file->functions(i); if (!st) - continue; + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + declPlace = st; SgStatement* lastNode = st->lastNodeOfStmt(); @@ -568,20 +573,22 @@ void arrayConstantPropagation(SgProject& project) string lowerBoundUnparsed = lowerBound->unparse(); string upperBoundUnparsed = upperBound->unparse(); - processLoopBound(st, st->expr(0), upperBoundUnparsed, true, arrayToVariable, borderVars, variableNumber); - processLoopBound(st, st->expr(0), lowerBoundUnparsed, false, arrayToVariable, borderVars, variableNumber); + processLoopBound(st, st->expr(0), upperBoundUnparsed, true, arrayToVariable, borderVars); + processLoopBound(st, st->expr(0), lowerBoundUnparsed, false, arrayToVariable, borderVars); } } } } - applyLeftPartForUnchangedAssignments(project, arrayToVariable, variableNumber); + + applyLeftPartForUnchangedAssignments(project, arrayToVariable); map> funcStarts; for (const auto& [fileName, statements] : positionsToAdd) { int res = SgFile::switchToFile(fileName); if (res == -1) - continue; + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + for (SgStatement* st : statements) { SgStatement* scope = isSgProgHedrStmt(st) ? st : st->controlParent(); @@ -589,42 +596,44 @@ void arrayConstantPropagation(SgProject& project) funcStarts[fileName].insert(scope); } } + for (const auto& [fileName, statements] : funcStarts) { SgFile::switchToFile(fileName); for (SgStatement* st : statements) { - InsertCommonAndDeclsForFunction(st, variablesToAdd); + insertCommonAndDeclsForFunction(st, variablesToAdd); } } + map>>> result; map hitCount; + findConstValues(project, borderVars, arrayToVariable, hitCount, result); insertDefinition(result, hitCount); } -void restoreArrays() +void arrayConstantPropagationRrestore() { for (auto& [filename, statements] : expToChange) { if (SgFile::switchToFile(filename) == -1) - continue; + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + for (auto& [statement, statementCopy] : statements) { if (statement && statementCopy) - { for (int i = 0; i < 3; i++) - { statement->setExpression(i, statementCopy->expr(i)); - } - - } } } - for (SgStatement* st : statementsToRemove) + for (auto& [filename, statements] : statementsToRemove) { - SgFile::switchToFile(st->fileName()); - st->deleteStmt(); + if (SgFile::switchToFile(filename) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + for (auto& st : statements) + st->deleteStmt(); } } diff --git a/src/Transformations/ArrayConstantPropagation/propagation.h b/src/Transformations/ArrayConstantPropagation/propagation.h index 190bd03..547d96c 100644 --- a/src/Transformations/ArrayConstantPropagation/propagation.h +++ b/src/Transformations/ArrayConstantPropagation/propagation.h @@ -8,4 +8,4 @@ using namespace std; void arrayConstantPropagation(SgProject& project); -void restoreArrays(); +void arrayConstantPropagationRrestore(); diff --git a/src/Utils/version.h b/src/Utils/version.h index e649f40..89bea68 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2483" +#define VERSION_SPF "2484" From e1bcaeba5c11cea1314dde7e679c2ec23c3e4691 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Fri, 1 May 2026 12:23:51 +0300 Subject: [PATCH 26/32] refactored private arrays analysis --- src/PrivateAnalyzer/private_arrays_search.cpp | 96 +++++++++---------- src/PrivateAnalyzer/private_arrays_search.h | 6 +- src/PrivateAnalyzer/range_structures.cpp | 46 ++++----- src/PrivateAnalyzer/range_structures.h | 4 +- src/PrivateAnalyzer/region.cpp | 49 +++++----- src/PrivateAnalyzer/region.h | 8 +- src/Sapfor.cpp | 2 +- 7 files changed, 104 insertions(+), 107 deletions(-) diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index e070d17..c7e89b7 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -20,14 +20,11 @@ using namespace std; -extern std::map, std::pair> declaredArrays; -extern map> SPF_messages; - static set collapsed; -static void RemoveEmptyPoints(ArrayAccessingIndexes& container) +static void removeEmptyPoints(arrayAccessingIndexes& container) { - ArrayAccessingIndexes resultContainer; + arrayAccessingIndexes resultContainer; set toRemove; for (auto& [arrayName, accessingSet] : container) @@ -52,7 +49,7 @@ static void RemoveEmptyPoints(ArrayAccessingIndexes& container) container[arrayName] = accessingSet; } -static void Collapse(Region* region) +static void collapse(Region* region) { if (region->getBasickBlocks().empty()) return; @@ -90,7 +87,7 @@ static void Collapse(Region* region) RegionInstruction instruction; instruction.def = move(region->array_def); - ArrayAccessingIndexes recursivePriv; + arrayAccessingIndexes recursivePriv; for (auto& byBlock : region->getBasickBlocks()) { if (!byBlock->array_priv.empty()) @@ -107,7 +104,7 @@ static void Collapse(Region* region) } } - ArrayAccessingIndexes useUnionB; + arrayAccessingIndexes useUnionB; for (auto& byBlock : region->getBasickBlocks()) for (auto& instruction : byBlock->instructions) for (auto& [arrayName, _] : instruction.use) @@ -134,9 +131,9 @@ static void Collapse(Region* region) region->array_priv = move(recursivePriv); } -static void SolveForBasickBlock(Region* block) +static void solveForBasickBlock(Region* block) { - ArrayAccessingIndexes newIn; + arrayAccessingIndexes newIn; bool flagFirst = true; for (Region* prevBlock : block->getPrevRegions()) { @@ -175,7 +172,7 @@ static void SolveForBasickBlock(Region* block) if (i > 0) instruction.in = block->instructions[i - 1].out; - ArrayAccessingIndexes newOut; + arrayAccessingIndexes newOut; if (instruction.def.empty()) newOut = instruction.in; else if (instruction.in.empty()) @@ -192,9 +189,7 @@ static void SolveForBasickBlock(Region* block) for (auto& [arrayName, accessSet] : instruction.in) { if (newOut.find(arrayName) == newOut.end()) - { newOut[arrayName] = accessSet; - } } } @@ -204,30 +199,31 @@ static void SolveForBasickBlock(Region* block) block->array_out = block->instructions.back().out; } -static void SolveDataFlowTopologically(Region* DFG) +static void solveDataFlowTopologically(Region* DFG) { for (Region* b : DFG->getBasickBlocks()) { collapsed.insert(b); - SolveForBasickBlock(b); + solveForBasickBlock(b); } } -static void SolveDataFlow(Region* DFG) +static void solveDataFlow(Region* DFG) { if (!DFG) return; + for (Region* subRegion : DFG->getSubRegions()) { - SolveDataFlow(subRegion); + solveDataFlow(subRegion); DFG->addBasickBlocks(subRegion); } vector& blocks = DFG->getBasickBlocks(); auto pos = remove_if(blocks.begin(), blocks.end(), [](Region* r) { return collapsed.find(r) != collapsed.end(); }); blocks.erase(pos, blocks.end()); - TopologySort(DFG->getBasickBlocks(), DFG->getHeader()); - SolveDataFlowTopologically(DFG); - Collapse(DFG); + topologySort(DFG->getBasickBlocks(), DFG->getHeader()); + solveDataFlowTopologically(DFG); + collapse(DFG); } static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector& declaredDims) @@ -247,9 +243,7 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector else if (constValSymb) dimLength = stol(constValSymb->constantValue()->unparse()); else if (subscriptExpr) - { dimLength = stol(subscriptExpr->rhs()->unparse()) - stol(subscriptExpr->lhs()->unparse()); - } else return false; @@ -260,7 +254,7 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector return true; } -static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym) +static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym, const map, pair>& declaredArrays) { if (!arrSym) return nullptr; @@ -268,10 +262,10 @@ static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym) { DIST::Array* distArr = val.first; if (!distArr) - continue; + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); Symbol* declSym = distArr->GetDeclSymbol(); if (!declSym) - continue; + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); SgSymbol* sgDecl = declSym->GetOriginal(); if (sgDecl && isEqSymbols(sgDecl, arrSym)) return distArr; @@ -279,7 +273,7 @@ static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym) return nullptr; } -static bool CheckDimensionLength(const AccessingSet& array) +static bool checkDimensionLength(const AccessingSet& array, const map, pair>& declaredArrays) { if (array.GetElements().empty()) return false; @@ -291,7 +285,7 @@ static bool CheckDimensionLength(const AccessingSet& array) vector declaredDims; declaredDims.reserve(dimCount); - DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol()); + DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol(), declaredArrays); if (distArr && distArr->GetDimSize() == (int)dimCount) { const auto& sizes = distArr->GetSizes(); @@ -317,7 +311,9 @@ static bool CheckDimensionLength(const AccessingSet& array) return false; } -static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set& insertedPrivates) +static void addPrivateArraysToLoop(LoopGraph* loop, const arrayAccessingIndexes& privates, set& insertedPrivates, + map>& SPF_messages, + const map, pair>& declaredArrays) { SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR); spfStat->setlineNumber(loop->loop->lineNumber()); @@ -328,19 +324,12 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& { int idx = arrayName.find('%'); string name = (idx != -1 ? arrayName.substr(idx+1) : arrayName); - if (!CheckDimensionLength(accessingSet)) + if (!checkDimensionLength(accessingSet, declaredArrays)) { wstring messageE, messageR; - __spf_printToLongBuf( - messageE, - L"Private array '%s' was skipped because dimension lengths are inconsistent", - to_wstring(name).c_str()); - __spf_printToLongBuf( - messageR, - R159, - to_wstring("array " + name + " has inconsistent dimension lengths").c_str()); - SPF_messages[loop->loop->fileName()].push_back( - Messages(WARR, loop->loop->lineNumber(), messageR, messageE, 1029)); + __spf_printToLongBuf(messageE, L"Private array '%s' was skipped because dimension lengths are inconsistent", to_wstring(name).c_str()); + __spf_printToLongBuf(messageR, R159, to_wstring("array " + name + " has inconsistent dimension lengths").c_str()); + SPF_messages[loop->loop->fileName()].push_back(Messages(WARR, loop->loop->lineNumber(), messageR, messageE, 1029)); continue; } @@ -378,12 +367,18 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& } } -void findPrivateArrays(map>& loopGraph, map>& FullIR, set& insertedPrivates) +void findPrivateArrays(map>& loopGraph, map>& FullIR, + set& insertedPrivates, + map>& SPF_messages, + const map, pair>& declaredArrays) { - map result; + map result; for (const auto& [fileName, loops] : loopGraph) { - SgFile::switchToFile(fileName); + if (SgFile::switchToFile(fileName) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + for (const auto& loop : loops) { if (!loop->isFor()) @@ -397,28 +392,31 @@ void findPrivateArrays(map>& loopGraph, mapfileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func) { - Region* loopRegion; + Region* loopRegion = nullptr; try { loopRegion = new Region(loop, blocks); } catch (...) { - continue; + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); } + if (loopRegion->getBasickBlocks().size() <= 1) { - delete(loopRegion); + delete loopRegion; continue; } - SolveDataFlow(loopRegion); - RemoveEmptyPoints(loopRegion->array_priv); + + solveDataFlow(loopRegion); + removeEmptyPoints(loopRegion->array_priv); result[loop] = loopRegion->array_priv; - delete(loopRegion); + delete loopRegion; } } + if (result.find(loop) != result.end() && !result[loop].empty()) - AddPrivateArraysToLoop(loop, result[loop], insertedPrivates); + addPrivateArraysToLoop(loop, result[loop], insertedPrivates, SPF_messages, declaredArrays); } } } \ No newline at end of file diff --git a/src/PrivateAnalyzer/private_arrays_search.h b/src/PrivateAnalyzer/private_arrays_search.h index cb14a24..06fa7c4 100644 --- a/src/PrivateAnalyzer/private_arrays_search.h +++ b/src/PrivateAnalyzer/private_arrays_search.h @@ -3,10 +3,12 @@ #include #include #include -#include #include "range_structures.h" #include "graph_loops.h" #include "CFGraph/CFGraph.h" -void findPrivateArrays(std::map>& loopGraph, std::map>& FullIR, std::set& insertedPrivates); +void findPrivateArrays(std::map>& loopGraph, std::map>& FullIR, std::set& insertedPrivates, + std::map>& SPF_messages, + const std::map, std::pair>& declaredArrays); diff --git a/src/PrivateAnalyzer/range_structures.cpp b/src/PrivateAnalyzer/range_structures.cpp index 340a9e8..a93d5bb 100644 --- a/src/PrivateAnalyzer/range_structures.cpp +++ b/src/PrivateAnalyzer/range_structures.cpp @@ -8,7 +8,7 @@ using namespace std; -static vector FindParticularSolution(const ArrayDimension& dim1, const ArrayDimension& dim2) +static vector findParticularSolution(const ArrayDimension& dim1, const ArrayDimension& dim2) { for (uint64_t i = 0; i < dim1.tripCount; i++) { @@ -24,9 +24,9 @@ static vector FindParticularSolution(const ArrayDimension& dim1, const } /* dim1 /\ dim2 */ -static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const ArrayDimension& dim2) +static ArrayDimension* dimensionIntersection(const ArrayDimension& dim1, const ArrayDimension& dim2) { - vector partSolution = FindParticularSolution(dim1, dim2); + vector partSolution = findParticularSolution(dim1, dim2); if (partSolution.empty()) return NULL; @@ -52,9 +52,9 @@ static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const A } /* dim1 / dim2 */ -static vector DimensionDifference(const ArrayDimension& dim1, const ArrayDimension& dim2) +static vector dimensionDifference(const ArrayDimension& dim1, const ArrayDimension& dim2) { - ArrayDimension* intersection = DimensionIntersection(dim1, dim2); + ArrayDimension* intersection = dimensionIntersection(dim1, dim2); if (!intersection) return { dim1 }; @@ -87,10 +87,10 @@ static vector DimensionDifference(const ArrayDimension& dim1, co } -static vector DimensionUnion(const ArrayDimension& dim1, const ArrayDimension& dim2) +static vector dimensionUnion(const ArrayDimension& dim1, const ArrayDimension& dim2) { vector res; - ArrayDimension* inter = DimensionIntersection(dim1, dim2); + ArrayDimension* inter = dimensionIntersection(dim1, dim2); if (!inter) return { dim1, dim2 }; @@ -98,14 +98,14 @@ static vector DimensionUnion(const ArrayDimension& dim1, const A delete(inter); vector diff1, diff2; - diff1 = DimensionDifference(dim1, dim2); - diff2 = DimensionDifference(dim2, dim1); + diff1 = dimensionDifference(dim1, dim2); + diff2 = dimensionDifference(dim2, dim1); res.insert(res.end(), diff1.begin(), diff1.end()); res.insert(res.end(), diff2.begin(), diff2.end()); return res; } -static vector ElementsIntersection(const vector& firstElement, const vector& secondElement) +static vector elementsIntersection(const vector& firstElement, const vector& secondElement) { if (firstElement.empty() || secondElement.empty()) return {}; @@ -113,13 +113,13 @@ static vector ElementsIntersection(const vector& size_t dimAmount = firstElement.size(); /* check if there is no intersecction */ for (size_t i = 0; i < dimAmount; i++) - if (FindParticularSolution(firstElement[i], secondElement[i]).empty()) + if (findParticularSolution(firstElement[i], secondElement[i]).empty()) return {}; vector result(dimAmount); for (size_t i = 0; i < dimAmount; i++) { - ArrayDimension* resPtr = DimensionIntersection(firstElement[i], secondElement[i]); + ArrayDimension* resPtr = dimensionIntersection(firstElement[i], secondElement[i]); if (resPtr) result[i] = *resPtr; else @@ -129,7 +129,7 @@ static vector ElementsIntersection(const vector& return result; } -static vector> ElementsDifference(const vector& firstElement, +static vector> elementsDifference(const vector& firstElement, const vector& secondElement) { if (firstElement.empty()) @@ -137,14 +137,14 @@ static vector> ElementsDifference(const vector intersection = ElementsIntersection(firstElement, secondElement); + vector intersection = elementsIntersection(firstElement, secondElement); vector> result; if (intersection.empty()) return { firstElement }; for (int i = 0; i < firstElement.size(); i++) { - auto dimDiff = DimensionDifference(firstElement[i], secondElement[i]); + auto dimDiff = dimensionDifference(firstElement[i], secondElement[i]); if (!dimDiff.empty()) { vector firstCopy = firstElement; @@ -158,14 +158,14 @@ static vector> ElementsDifference(const vector& firstElement, const vector& secondElement, +static void elementsUnion(const vector& firstElement, const vector& secondElement, vector>& lc, vector>& rc, vector& intersection) { /* lc(rc) is a set of ranges, which only exist in first(second) element*/ - intersection = ElementsIntersection(firstElement, secondElement); - lc = ElementsDifference(firstElement, intersection); - rc = ElementsDifference(secondElement, intersection); + intersection = elementsIntersection(firstElement, secondElement); + lc = elementsDifference(firstElement, intersection); + rc = elementsDifference(secondElement, intersection); } void AccessingSet::FindUncovered(const vector& element, vector>& result) const { @@ -175,8 +175,8 @@ void AccessingSet::FindUncovered(const vector& element, vector& element, vector; +using arrayAccessingIndexes = std::map; bool operator!=(const ArrayDimension& lhs, const ArrayDimension& rhs); bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs); -bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs); \ No newline at end of file +bool operator!=(const arrayAccessingIndexes& lhs, const arrayAccessingIndexes& rhs); \ No newline at end of file diff --git a/src/PrivateAnalyzer/region.cpp b/src/PrivateAnalyzer/region.cpp index 26fb1b7..8b226bf 100644 --- a/src/PrivateAnalyzer/region.cpp +++ b/src/PrivateAnalyzer/region.cpp @@ -23,7 +23,7 @@ static bool isParentStmt(SgStatement* stmt, SgStatement* parent) } /*returns head block and loop*/ -pair> GetBasicBlocksForLoop(const LoopGraph* loop, const vector blocks) +pair> getBasicBlocksForLoop(const LoopGraph* loop, const vector blocks) { set block_loop; SAPFOR::BasicBlock* head_block = nullptr; @@ -51,15 +51,15 @@ pair> GetBasicBlocksForLoop(const return { head_block, block_loop }; } -static void BuildLoopIndex(map& loopForIndex, LoopGraph* loop) { +static void buildLoopIndex(map& loopForIndex, LoopGraph* loop) { string index = loop->loopSymbol(); loopForIndex[loop->loop->GetOriginal()] = loop; for (const auto& childLoop : loop->children) - BuildLoopIndex(loopForIndex, childLoop); + buildLoopIndex(loopForIndex, childLoop); } -static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map& loopForIndex) { +static string findIndexName(int pos, SAPFOR::BasicBlock* block, map& loopForIndex) { set args = { block->getInstructions()[pos]->getInstruction()->getArg1() }; for (int i = pos - 1; i >= 0; i--) @@ -93,10 +93,10 @@ static string FindIndexName(int pos, SAPFOR::BasicBlock* block, mapgetInstructions(); map loopForIndex; - BuildLoopIndex(loopForIndex, loop); + buildLoopIndex(loopForIndex, loop); for (int i = 0; i < instructions.size(); i++) { auto instruction = instructions[i]; @@ -233,7 +233,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces } -static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const set& blockSet, map& bbToRegion) +static void removeHeaderConnection(SAPFOR::BasicBlock* header, const set& blockSet, map& bbToRegion) { for (SAPFOR::BasicBlock* block : blockSet) { @@ -249,10 +249,7 @@ static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const set& result, - const set& cycleBlocks, - map& color) +static bool DFS(Region* block, vector& result, const set& cycleBlocks, map& color) { auto it = color.find(block); if (it != color.end()) @@ -275,7 +272,7 @@ static bool DFS(Region* block, return true; } -bool HasCycle(Region* block, const std::set& cycleBlocks, std::set& visitedBlocks) +bool hasCycle(Region* block, const std::set& cycleBlocks, std::set& visitedBlocks) { return false; if (visitedBlocks.find(block) != visitedBlocks.end()) @@ -283,13 +280,13 @@ bool HasCycle(Region* block, const std::set& cycleBlocks, std::setgetNextRegions()) { - if (cycleBlocks.find(nextBlock) != cycleBlocks.end() && HasCycle(nextBlock, cycleBlocks, visitedBlocks)) + if (cycleBlocks.find(nextBlock) != cycleBlocks.end() && hasCycle(nextBlock, cycleBlocks, visitedBlocks)) return true; } return false; } -bool TopologySort(std::vector& basikBlocks, Region* header) +bool topologySort(std::vector& basikBlocks, Region* header) { set cycleBlocks(basikBlocks.begin(), basikBlocks.end()); vector result; @@ -301,7 +298,7 @@ bool TopologySort(std::vector& basikBlocks, Region* header) return true; } -static void SetConnections(map& bbToRegion, const set& blockSet) +static void setConnections(map& bbToRegion, const set& blockSet) { for (SAPFOR::BasicBlock* block : blockSet) { @@ -315,11 +312,11 @@ static void SetConnections(map& bbToRegion, const } } -static Region* CreateSubRegion(LoopGraph* loop, const vector& Blocks, map& bbToRegion) +static Region* createSubRegion(LoopGraph* loop, const vector& Blocks, map& bbToRegion) { Region* region = new Region; - auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); - RemoveHeaderConnection(header, blockSet, bbToRegion); + auto [header, blockSet] = getBasicBlocksForLoop(loop, Blocks); + removeHeaderConnection(header, blockSet, bbToRegion); if (bbToRegion.find(header) != bbToRegion.end()) region->setHeader(bbToRegion.at(header)); else @@ -336,34 +333,34 @@ static Region* CreateSubRegion(LoopGraph* loop, const vectorisFor()) continue; - region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); + region->addSubRegions(createSubRegion(childLoop, Blocks, bbToRegion)); } - if (!TopologySort(region->getBasickBlocks(), region->getHeader())) + if (!topologySort(region->getBasickBlocks(), region->getHeader())) throw std::runtime_error("Unnoticed cycle"); return region; } Region::Region(LoopGraph* loop, const vector& Blocks) { - auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); + auto [header, blockSet] = getBasicBlocksForLoop(loop, Blocks); map bbToRegion; for (auto poiner : blockSet) { bbToRegion[poiner] = new Region(*poiner); this->basickBlocks.push_back(bbToRegion[poiner]); - GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use, bbToRegion[poiner]); + getDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use, bbToRegion[poiner]); } this->header = bbToRegion[header]; - SetConnections(bbToRegion, blockSet); - RemoveHeaderConnection(header, blockSet, bbToRegion); + setConnections(bbToRegion, blockSet); + removeHeaderConnection(header, blockSet, bbToRegion); //create subRegions for (LoopGraph* childLoop : loop->children) { if (!childLoop->isFor()) continue; - subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); + subRegions.insert(createSubRegion(childLoop, Blocks, bbToRegion)); } - if (!TopologySort(basickBlocks, this->header)) + if (!topologySort(basickBlocks, this->header)) throw std::runtime_error("Unnoticed cycle"); } \ No newline at end of file diff --git a/src/PrivateAnalyzer/region.h b/src/PrivateAnalyzer/region.h index adecfe6..26d4a06 100644 --- a/src/PrivateAnalyzer/region.h +++ b/src/PrivateAnalyzer/region.h @@ -10,7 +10,7 @@ struct RegionInstruction { - ArrayAccessingIndexes def, use, in, out; + arrayAccessingIndexes def, use, in, out; }; class Region : public SAPFOR::BasicBlock { @@ -67,7 +67,7 @@ public: std::vector instructions; - ArrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv; + arrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv; private: std::vector basickBlocks; @@ -79,6 +79,6 @@ private: Region* header; }; -bool HasCycle(Region* block, const std::set& cycleBlocks, std::set& visitedBlocks); +bool hasCycle(Region* block, const std::set& cycleBlocks, std::set& visitedBlocks); -bool TopologySort(std::vector& basikBlocks, Region* header); \ No newline at end of file +bool topologySort(std::vector& basikBlocks, Region* header); \ No newline at end of file diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index fcb4294..9a28e34 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1905,7 +1905,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS) transformAssumedSizeParameters(allFuncInfo); else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS) - findPrivateArrays(loopGraph, fullIR, insertedPrivates); + findPrivateArrays(loopGraph, fullIR, insertedPrivates, SPF_messages, declaredArrays); else if (curr_regime == MERGE_REGIONS) mergeRegions(parallelRegions, allFuncInfo); else if (curr_regime == ARRAY_PROPAGATION) From 51f97e2be9a2405681fa580eab4d9716cad42ab9 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Fri, 1 May 2026 12:56:32 +0300 Subject: [PATCH 27/32] improved private arrays analysis --- src/PrivateAnalyzer/private_arrays_search.cpp | 26 +++++++++++- src/PrivateAnalyzer/private_arrays_search.h | 8 ++-- src/PrivateAnalyzer/range_structures.cpp | 2 +- src/PrivateAnalyzer/range_structures.h | 2 +- src/Sapfor.cpp | 41 ++++++++++--------- src/Utils/version.h | 2 +- 6 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index c7e89b7..1cb044e 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -311,7 +311,7 @@ static bool checkDimensionLength(const AccessingSet& array, const map& insertedPrivates, +static int addPrivateArraysToLoop(LoopGraph* loop, const arrayAccessingIndexes& privates, set& insertedPrivates, map>& SPF_messages, const map, pair>& declaredArrays) { @@ -367,7 +367,7 @@ static void addPrivateArraysToLoop(LoopGraph* loop, const arrayAccessingIndexes& } } -void findPrivateArrays(map>& loopGraph, map>& loopGraph, map>& FullIR, set& insertedPrivates, map>& SPF_messages, @@ -419,4 +419,26 @@ void findPrivateArrays(map>& loopGraph, maplineNum, loop->fileName.c_str()); + for (const auto& [name, accesingSet] : accesing) + { + const auto& byDimention = accesingSet.GetElements(); + __spf_print(1, " for array %s with dimention %d\n", name.c_str(), byDimention.size()); + + for (int z = 0; z < byDimention.size(); ++z) + { + __spf_print(1, " dim %d (start, step, tripCount):\n", z); + for (auto& elem : byDimention[z]) + __spf_print(1, " [%ld %ld %ld]\n", elem.start, elem.step, elem.tripCount); + } + } + } + } + + return insertedPrivates.size(); } \ No newline at end of file diff --git a/src/PrivateAnalyzer/private_arrays_search.h b/src/PrivateAnalyzer/private_arrays_search.h index 06fa7c4..f784fe0 100644 --- a/src/PrivateAnalyzer/private_arrays_search.h +++ b/src/PrivateAnalyzer/private_arrays_search.h @@ -8,7 +8,7 @@ #include "graph_loops.h" #include "CFGraph/CFGraph.h" -void findPrivateArrays(std::map>& loopGraph, std::map>& FullIR, std::set& insertedPrivates, - std::map>& SPF_messages, - const std::map, std::pair>& declaredArrays); +int findPrivateArrays(std::map>& loopGraph, std::map>& FullIR, std::set& insertedPrivates, + std::map>& SPF_messages, + const std::map, std::pair>& declaredArrays); diff --git a/src/PrivateAnalyzer/range_structures.cpp b/src/PrivateAnalyzer/range_structures.cpp index a93d5bb..eeb0085 100644 --- a/src/PrivateAnalyzer/range_structures.cpp +++ b/src/PrivateAnalyzer/range_structures.cpp @@ -203,7 +203,7 @@ void AccessingSet::FindCoveredBy(const vector& element, vector> AccessingSet::GetElements() const { return allElements; } +const vector>& AccessingSet::GetElements() const { return allElements; } void AccessingSet::Insert(const vector& element) { diff --git a/src/PrivateAnalyzer/range_structures.h b/src/PrivateAnalyzer/range_structures.h index 28ab7c3..4f58728 100644 --- a/src/PrivateAnalyzer/range_structures.h +++ b/src/PrivateAnalyzer/range_structures.h @@ -22,7 +22,7 @@ public: AccessingSet(std::vector> input) : allElements(input) {}; AccessingSet() {}; AccessingSet(const AccessingSet& a) { allElements = a.GetElements(); }; - std::vector> GetElements() const; + const std::vector>& GetElements() const; void Insert(const std::vector& element); AccessingSet Union(const AccessingSet& source); AccessingSet Intersect(const AccessingSet& secondSet) const; diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index 9a28e34..96c129f 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1036,24 +1036,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne if (internalExit < 0) throw -1; - set applyFor = { LOOPS_SPLITTER, - LOOPS_COMBINER, - PRIVATE_REMOVING, - PRIVATE_ARRAYS_EXPANSION, - PRIVATE_ARRAYS_SHRINKING, - REMOVE_DEAD_CODE, - MOVE_OPERATORS }; - - if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end()) - { - SgStatement* mainUnit = findMainUnit(&project, SPF_messages); - checkNull(mainUnit, convertFileName(__FILE__).c_str(), __LINE__); - - getObjectForFileFromMap(mainUnit->fileName(), SPF_messages).push_back(Messages(ERROR, mainUnit->lineNumber(), R197, L"Transformation cannot be performed - nothing to change", 2023)); - __spf_print(1, "%d Transformation cannot be performed - nothing to change, count of transform %d, err %d\n", mainUnit->lineNumber(), countOfTransform, internalExit); - throw -11; - } - sendMessage_2lvl(2); // ********************************** /// /// SECOND AGGREGATION STEP /// @@ -1904,8 +1886,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne } else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS) transformAssumedSizeParameters(allFuncInfo); - else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS) - findPrivateArrays(loopGraph, fullIR, insertedPrivates, SPF_messages, declaredArrays); + else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS) + countOfTransform = findPrivateArrays(loopGraph, fullIR, insertedPrivates, SPF_messages, declaredArrays); else if (curr_regime == MERGE_REGIONS) mergeRegions(parallelRegions, allFuncInfo); else if (curr_regime == ARRAY_PROPAGATION) @@ -1921,6 +1903,25 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne if (internalExit != 0) throw -1; + set applyFor = { LOOPS_SPLITTER, + LOOPS_COMBINER, + PRIVATE_REMOVING, + PRIVATE_ARRAYS_EXPANSION, + PRIVATE_ARRAYS_SHRINKING, + REMOVE_DEAD_CODE, + MOVE_OPERATORS, + FIND_PRIVATE_ARRAYS_ANALYSIS }; + + if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end()) + { + SgStatement* mainUnit = findMainUnit(&project, SPF_messages); + checkNull(mainUnit, convertFileName(__FILE__).c_str(), __LINE__); + + getObjectForFileFromMap(mainUnit->fileName(), SPF_messages).push_back(Messages(ERROR, mainUnit->lineNumber(), R197, L"Transformation cannot be performed - nothing to change", 2023)); + __spf_print(1, "%d Transformation cannot be performed - nothing to change, count of transform %d, err %d\n", mainUnit->lineNumber(), countOfTransform, internalExit); + throw - 11; + } + return true; } diff --git a/src/Utils/version.h b/src/Utils/version.h index 89bea68..24f80ed 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2484" +#define VERSION_SPF "2485" From 5a3c936b5c5c1de9a5e35f0a97f2f31b8ebf3785 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Sun, 3 May 2026 21:00:07 +0300 Subject: [PATCH 28/32] improved MERGE_ARRAYS --- CMakeLists.txt | 9 +-- src/DirectiveProcessing/directive_parser.cpp | 32 ++++++++- src/DirectiveProcessing/directive_parser.h | 3 + .../spf_directive_preproc.cpp | 32 ++++++--- src/ParallelizationRegions/merge_regions.cpp | 68 +++++-------------- .../ArrayConstantPropagation/propagation.cpp | 5 +- src/Utils/errors.h | 1 + src/Utils/version.h | 2 +- 8 files changed, 77 insertions(+), 75 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 724026f..02022ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,10 +163,9 @@ set(PARALLEL_REG src/ParallelizationRegions/ParRegions.cpp src/ParallelizationRegions/resolve_par_reg_conflicts.cpp src/ParallelizationRegions/resolve_par_reg_conflicts.h src/ParallelizationRegions/uniq_name_creator.cpp - src/ParallelizationRegions/uniq_name_creator.h) - -set(MERGE_REGIONS src/ParallelizationRegions/merge_regions.cpp - src/ParallelizationRegions/merge_regions.h) + src/ParallelizationRegions/uniq_name_creator.h + src/ParallelizationRegions/merge_regions.h + src/ParallelizationRegions/merge_regions.cpp) set(TR_DEAD_CODE src/Transformations/DeadCodeRemoving/dead_code.cpp src/Transformations/DeadCodeRemoving/dead_code.h) @@ -430,7 +429,6 @@ set(SOURCE_EXE ${LOOP_ANALYZER} ${TRANSFORMS} ${PARALLEL_REG} - ${MERGE_REGIONS} ${PRIV} ${FDVM} ${OMEGA} @@ -484,7 +482,6 @@ source_group (GraphCall FILES ${GR_CALL}) source_group (GraphLoop FILES ${GR_LOOP}) source_group (LoopAnalyzer FILES ${LOOP_ANALYZER}) source_group (ParallelizationRegions FILES ${PARALLEL_REG}) -source_group (MergeRegions FILES ${MERGE_REGIONS}) source_group (PrivateAnalyzer FILES ${PRIV}) source_group (FDVM_Compiler FILES ${FDVM}) source_group (SageExtension FILES ${OMEGA}) diff --git a/src/DirectiveProcessing/directive_parser.cpp b/src/DirectiveProcessing/directive_parser.cpp index e653f26..5af0f02 100644 --- a/src/DirectiveProcessing/directive_parser.cpp +++ b/src/DirectiveProcessing/directive_parser.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -584,6 +583,37 @@ void fillCheckpointFromComment(Statement *stIn, map &clauses, template void fillCheckpointFromComment(Statement *stIn, map &clauses, set &vars, set &expt); template void fillCheckpointFromComment(Statement *stIn, map &clauses, set &vars, set &expt); +template +void fillMergeArraysFromComment(Statement* stIn, pair& toReplace) +{ + if (stIn) + { + SgStatement* st = stIn->GetOriginal(); + if (st->variant() == SPF_TRANSFORM_DIR) + { + SgExpression* exprList = st->expr(0); + while (exprList) + { + const int var = exprList->lhs()->variant(); + if (var == SPF_MERGE_ARRAYS_OP) + { + if (!exprList->lhs()->lhs() || !exprList->lhs()->rhs()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + fillType *dummy = NULL; + toReplace = std::make_pair(getData(exprList->lhs()->lhs(), dummy), + getData(exprList->lhs()->rhs(), dummy)); + break; + } + exprList = exprList->rhs(); + } + } + } +} + +template void fillMergeArraysFromComment(Statement* st, pair& toReplace); +template void fillMergeArraysFromComment(Statement* st, pair& toReplace); + void fillInfoFromDirectives(const LoopGraph *loopInfo, ParallelDirective *directive) { SgForStmt *currentLoop = (SgForStmt*)loopInfo->loop; diff --git a/src/DirectiveProcessing/directive_parser.h b/src/DirectiveProcessing/directive_parser.h index f632940..3e5d954 100644 --- a/src/DirectiveProcessing/directive_parser.h +++ b/src/DirectiveProcessing/directive_parser.h @@ -52,4 +52,7 @@ void fillShrinkFromComment(Statement *stIn, std::vector void fillCheckpointFromComment(Statement *stIn, std::map &clauses, std::set &vars, std::set &expt); +template +void fillMergeArraysFromComment(Statement* stIn, std::pair& toReplace); + int getCoverPropertyFromComment(Statement* stIn); diff --git a/src/DirectiveProcessing/spf_directive_preproc.cpp b/src/DirectiveProcessing/spf_directive_preproc.cpp index 48bb8ad..191fd8f 100644 --- a/src/DirectiveProcessing/spf_directive_preproc.cpp +++ b/src/DirectiveProcessing/spf_directive_preproc.cpp @@ -186,12 +186,13 @@ static bool checkCover(SgStatement* st, return retVal; } -static bool checkProcessPrivate(SgStatement* st, - SgStatement* attributeStatement, - const set& privates, - vector& messagesForFile) +static bool checkDeclaration(SgStatement* st, + SgStatement* attributeStatement, + const set& variables, + vector& messagesForFile) { // PROCESS_PRIVATE(VAR) + // MERGE_ARRAYS(ARR1, ARR2) const int var = st->variant(); bool retVal = true; @@ -203,12 +204,12 @@ static bool checkProcessPrivate(SgStatement* st, set varDef, varUse; fillVarsSets(iterator, end, varDef, varUse); - for (auto& privElemS : privates) + for (auto& var : variables) { - const string privElem = privElemS->GetOriginal()->identifier(); + const string varElem = var->GetOriginal()->identifier(); bool defCond = true; - if (varDef.find(privElem) == varDef.end()) + if (varDef.find(varElem) == varDef.end()) defCond = false; if (!defCond) @@ -1784,7 +1785,7 @@ static inline bool processStat(SgStatement *st, const string &currFile, fillPrivatesFromComment(new Statement(attributeStatement), privates, SPF_PROCESS_PRIVATE_OP); if (privates.size()) { - bool result = checkProcessPrivate(st, attributeStatement, privates, messagesForFile); + bool result = checkDeclaration(st, attributeStatement, privates, messagesForFile); retVal = retVal && result; } @@ -1938,11 +1939,20 @@ static inline bool processStat(SgStatement *st, const string &currFile, if (isSPF_OP(attributeStatement, SPF_MERGE_ARRAYS_OP)) { attributeStatement->setLocalLineNumber(-1); - /*if (st->variant() != FOR_NODE) + if (!isSgDeclarationStatement(st)) { - BAD_POSITION_FULL(ERROR, "", "", "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber()); + BAD_POSITION_FULL(ERROR, "", "", "before", RR1_1, "declataion statement", RR1_9, attributeStatement->lineNumber()); retVal = false; - }*/ + } + else + { + pair toReplacePair; + fillMergeArraysFromComment(new Statement(attributeStatement), toReplacePair); + + set toCheckDecl = { toReplacePair.first }; + bool result = checkDeclaration(st, attributeStatement, toCheckDecl, messagesForFile); + retVal = retVal && result; + } } } else if (type == SPF_CHECKPOINT_DIR) diff --git a/src/ParallelizationRegions/merge_regions.cpp b/src/ParallelizationRegions/merge_regions.cpp index 4c68fb2..ed3a5dc 100644 --- a/src/ParallelizationRegions/merge_regions.cpp +++ b/src/ParallelizationRegions/merge_regions.cpp @@ -3,6 +3,7 @@ #include #include #include "merge_regions.h" +#include "../DirectiveProcessing/directive_parser.h" using std::map; using std::set; @@ -10,46 +11,6 @@ using std::pair; using std::string; using std::vector; -//TODO: need to create new clause!! -static void parseMergeDirective(const char *comment, - vector> &parsed_mapping) -{ - while (comment) - { - auto *line_end = strchr(comment, '\n'); - - static const char prefix[] = "!!spf transform(merge_arrays("; - static const auto compare_chars = sizeof(prefix) - 1; - - if (strlen(comment) >= compare_chars) - { - std::string comment_cmp(comment, compare_chars); - convertToLower(comment_cmp); - - if (comment_cmp == prefix) - { - auto* pair_start = comment + compare_chars; - auto* comma = strchr(pair_start, ','); - if (comma) - { - auto* close_br = strchr(comma + 1, ')'); - if (close_br) - { - parsed_mapping.emplace_back( - string(pair_start, comma - pair_start), - string(comma + 1, close_br - comma - 1)); - } - } - } - } - - comment = line_end; - - if (comment) - comment++; - } -} - static string getNonDefaultRegion(DIST::Array *a) { string result; @@ -217,7 +178,7 @@ static SgExpression* findExprWithVariant(SgExpression* exp, int variant) return NULL; } -SgType* GetArrayType(DIST::Array *array) +static SgType* GetArrayType(DIST::Array *array) { if (!array) return NULL; @@ -242,11 +203,11 @@ SgType* GetArrayType(DIST::Array *array) return NULL; } -SgSymbol *insertDeclIfNeeded(const string &array_name, - const string &common_block_name, - DIST::Array *example_array, - FuncInfo *dest, - map> &inserted_arrays) +static SgSymbol *insertDeclIfNeeded(const string &array_name, + const string &common_block_name, + DIST::Array *example_array, + FuncInfo *dest, + map> &inserted_arrays) { auto *type = GetArrayType(example_array); @@ -462,17 +423,20 @@ void mergeRegions(vector ®ions, const maplexNext()) { - if (curr_stmt->comments()) + auto attributes = getAttributes(curr_stmt, set{SPF_TRANSFORM_DIR}); + + for (auto& attr : attributes) { - vector> parsed_mapping; - parseMergeDirective(curr_stmt->comments(), parsed_mapping); + pair parsed_mapping = { "", "" }; + const auto empty = parsed_mapping; + fillMergeArraysFromComment(new Statement(attr), parsed_mapping); - for (const auto &p : parsed_mapping) + if (parsed_mapping != empty) { - auto *found_array = getArrayFromDeclarated(curr_stmt, p.first); + auto* found_array = getArrayFromDeclarated(curr_stmt, parsed_mapping.first); if (found_array) { - arrays_to_merge[p.second].insert(found_array); + arrays_to_merge[parsed_mapping.second].insert(found_array); array_alignment[found_array] = {}; } } diff --git a/src/Transformations/ArrayConstantPropagation/propagation.cpp b/src/Transformations/ArrayConstantPropagation/propagation.cpp index 81c48cc..0b87937 100644 --- a/src/Transformations/ArrayConstantPropagation/propagation.cpp +++ b/src/Transformations/ArrayConstantPropagation/propagation.cpp @@ -521,7 +521,7 @@ static void processLoopBound(SgStatement* st, getBorderVars(exp, st->fileName(), borderVars); - if (containsArrayRefRecursive(exp), borderVars, st->fileName()) + if (containsArrayRefRecursive(exp)) { copyStatement(st); @@ -575,7 +575,6 @@ void arrayConstantPropagation(SgProject& project) processLoopBound(st, st->expr(0), upperBoundUnparsed, true, arrayToVariable, borderVars); processLoopBound(st, st->expr(0), lowerBoundUnparsed, false, arrayToVariable, borderVars); - } } } @@ -601,9 +600,7 @@ void arrayConstantPropagation(SgProject& project) { SgFile::switchToFile(fileName); for (SgStatement* st : statements) - { insertCommonAndDeclsForFunction(st, variablesToAdd); - } } map>>> result; diff --git a/src/Utils/errors.h b/src/Utils/errors.h index 274e779..7d8abe5 100644 --- a/src/Utils/errors.h +++ b/src/Utils/errors.h @@ -322,6 +322,7 @@ static const wchar_t *RR1_5 = L"RR1_5:"; static const wchar_t *RR1_6 = L"RR1_6:"; static const wchar_t *RR1_7 = L"RR1_7:"; static const wchar_t *RR1_8 = L"RR1_8:"; +static const wchar_t *RR1_9 = L"RR1_9:"; static const wchar_t *R2 = L"R2:"; static const wchar_t *R3 = L"R3:"; diff --git a/src/Utils/version.h b/src/Utils/version.h index 24f80ed..f83fd22 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2485" +#define VERSION_SPF "2486" From f62bfc8e8bb3baa741ee3f79abd4bd480e87a4ce Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Wed, 1 Apr 2026 17:12:20 +0300 Subject: [PATCH 29/32] change reordering logic --- .../MoveOperators/move_operators.cpp | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index 0793913..c68a9c4 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -470,6 +470,8 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const // as close as possible after its last dependency (if any). const auto depsMap = analyzeBasicBlockIntraDependencies(bb); vector order = ops; + const vector originalOrder = ops; + const int nOrig = (int)originalOrder.size(); auto indexIn = [](const vector& v, SgStatement* s) -> int { @@ -479,37 +481,59 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const return -1; }; + auto indexInOriginal = [&](SgStatement* s) -> int + { + return indexIn(originalOrder, s); + }; + for (SgStatement* s : ops) { auto itDeps = depsMap.find(s); if (itDeps == depsMap.end() || itDeps->second.empty()) continue; + int lastDepOrigIdx = -1; + for (SgStatement* dep : itDeps->second) + { + const int j = indexInOriginal(dep); + if (j >= 0) + lastDepOrigIdx = max(lastDepOrigIdx, j); + } + if (lastDepOrigIdx < 0) + continue; + + SgStatement* successor = nullptr; + if (lastDepOrigIdx + 1 < nOrig) + successor = originalOrder[lastDepOrigIdx + 1]; + int posS = indexIn(order, s); if (posS < 0) continue; - int lastDepIdx = -1; - for (SgStatement* dep : itDeps->second) + if (successor == nullptr) { - const int j = indexIn(order, dep); - if (j >= 0) - lastDepIdx = max(lastDepIdx, j); + if (posS == (int)order.size() - 1) + continue; + order.erase(order.begin() + posS); + order.push_back(s); + continue; } - if (lastDepIdx < 0) + + if (successor == s) continue; - if (posS == lastDepIdx + 1) + const int posSucc = indexIn(order, successor); + if (posSucc < 0) + continue; + + if (posS + 1 == posSucc) continue; order.erase(order.begin() + posS); - - int lp = lastDepIdx; - if (posS < lastDepIdx) - lp = lastDepIdx - 1; - - const int insertAt = lp + 1; - order.insert(order.begin() + insertAt, s); + const int posSucc2 = indexIn(order, successor); + if (posSucc2 < 0) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + order.insert(order.begin() + posSucc2, s); } bool changed = false; From f02ffe45f5e756f28b7a6e81bfc9f1a77dddac56 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Thu, 23 Apr 2026 16:41:42 +0300 Subject: [PATCH 30/32] some fixes with finding dependencies between operators --- .../MoveOperators/move_operators.cpp | 537 ++++++++++++------ 1 file changed, 377 insertions(+), 160 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index c68a9c4..bc9b1e5 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include #include "../../Utils/errors.h" #include "../../Utils/SgUtils.h" @@ -21,6 +24,147 @@ set loop_tags = {FOR_NODE}; set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; set control_end_tags = {CONTROL_END}; +namespace +{ +enum class ArrayIndexCompareResult +{ + Equal, + NotEqual, + Unknown +}; + +// Structural key for array index / subscript analysis (stable across LOAD/STORE of the same access). +string buildStructuralExprKey(SgExpression* e) +{ + if (!e) + return string("_"); + + if (auto* ar = isSgArrayRefExp(e)) + { + SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr; + string key = string("A(") + (sym ? sym->identifier() : "?"); + const int n = ar->numberOfSubscripts(); + for (int i = 0; i < n; ++i) + { + key += ","; + key += buildStructuralExprKey(ar->subscript(i)); + } + key += ")"; + return key; + } + + if (e->variant() == VAR_REF || e->variant() == CONST_REF) + { + SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr; + return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")"; + } + + if (auto* v = isSgValueExp(e)) + { + if (e->variant() == INT_VAL) + return string("I(") + to_string(v->intValue()) + ")"; + if (e->variant() == BOOL_VAL) + return string("B(") + (v->boolValue() ? "1" : "0") + ")"; + if (e->variant() == CHAR_VAL) + return string("CH(") + string(1, v->charValue()) + ")"; + if (e->variant() == FLOAT_VAL) + { + char* fv = v->floatValue(); + return string("F(") + (fv ? string(fv) : string()) + ")"; + } + if (e->variant() == DOUBLE_VAL) + { + char* dv = v->doubleValue(); + if (!dv || !*dv) + return string("D()"); + char* endp = nullptr; + const double d = strtod(dv, &endp); + if (endp != dv && std::isfinite(d)) + { + const double r = std::round(d); + if (std::fabs(d - r) < 1e-12 && r >= static_cast(INT_MIN) && r <= static_cast(INT_MAX)) + return string("I(") + to_string(static_cast(r)) + ")"; + } + return string("D(") + string(dv) + ")"; + } + if (e->variant() == STRING_VAL) + return string("S(") + (v->stringValue() ? v->stringValue() : string()) + ")"; + } + + if (e->variant() == MULT_OP && e->lhs() && e->rhs()) + { + string a = buildStructuralExprKey(e->lhs()); + string b = buildStructuralExprKey(e->rhs()); + if (a > b) + swap(a, b); + return string("N(") + to_string(e->variant()) + ",L=" + a + ",R=" + b + ")"; + } + + string key = string("N(") + to_string(e->variant()); + if (e->lhs()) + key += ",L=" + buildStructuralExprKey(e->lhs()); + if (e->rhs()) + key += ",R=" + buildStructuralExprKey(e->rhs()); + key += ")"; + return key; +} + +// Prefer AST from IR instruction (same SgArrayRef for matching store/load); fallback to idxStack string. +string memexKeyForArrayLoadStore(const SAPFOR::Instruction* instr, const function& irStackKey) +{ + if (!instr) + return string(); + SgExpression* ex = instr->getExpression(); + if (ex) + { + if (isSgArrayRefExp(ex)) + return string("MEMEX#") + buildStructuralExprKey(ex); + return string("MEMEX#") + buildStructuralExprKey(ex); + } + return irStackKey(); +} + +ArrayIndexCompareResult compareIndexExpressions(SgExpression* a, SgExpression* b) +{ + if (!a && !b) + return ArrayIndexCompareResult::Equal; + if (!a || !b) + return ArrayIndexCompareResult::NotEqual; + const string ka = buildStructuralExprKey(a); + const string kb = buildStructuralExprKey(b); + if (ka.empty() || kb.empty()) + return ArrayIndexCompareResult::Unknown; + if (ka == kb) + return ArrayIndexCompareResult::Equal; + return ArrayIndexCompareResult::NotEqual; +} + +ArrayIndexCompareResult compareArrayRefExpressions(SgArrayRefExp* a, SgArrayRefExp* b) +{ + if (!a && !b) + return ArrayIndexCompareResult::Equal; + if (!a || !b) + return ArrayIndexCompareResult::NotEqual; + SgSymbol* s1 = a->symbol() ? OriginalSymbol(a->symbol()) : nullptr; + SgSymbol* s2 = b->symbol() ? OriginalSymbol(b->symbol()) : nullptr; + if (s1 && s2) + { + if (strcmp(s1->identifier(), s2->identifier()) != 0) + return ArrayIndexCompareResult::NotEqual; + } + else if (s1 != s2) + return ArrayIndexCompareResult::NotEqual; + if (a->numberOfSubscripts() != b->numberOfSubscripts()) + return ArrayIndexCompareResult::NotEqual; + for (int i = 0; i < a->numberOfSubscripts(); ++i) + { + ArrayIndexCompareResult c = compareIndexExpressions(a->subscript(i), b->subscript(i)); + if (c != ArrayIndexCompareResult::Equal) + return c; + } + return ArrayIndexCompareResult::Equal; +} +} // namespace static vector findInstructionsFromStatement(SgStatement* st, const vector& blocks) { @@ -151,83 +295,39 @@ static map> analyzeBasicBlockIntraDependencie return loop_tags.count(v) || control_tags.count(v) || control_end_tags.count(v); }; - auto isTrackable = [](const SAPFOR::Argument* a) -> bool + auto isVarArg = [](const SAPFOR::Argument* a) -> bool + { + return a && a->getType() == SAPFOR::CFG_ARG_TYPE::VAR; + }; + + auto isArrayArg = [](const SAPFOR::Argument* a) -> bool + { + return a && a->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY; + }; + + auto varKey = [&](const SAPFOR::Argument* a) -> string { if (!a) + return string(); + return a->getValue(); + }; + + auto parseIntConst = [](const SAPFOR::Argument* a, int& out) -> bool + { + if (!a || a->getType() != SAPFOR::CFG_ARG_TYPE::CONST) return false; - const auto t = a->getType(); - return t == SAPFOR::CFG_ARG_TYPE::VAR || t == SAPFOR::CFG_ARG_TYPE::REG; - }; - - auto argKey = [&](const SAPFOR::Argument* a) -> string - { - if (!a) - return string(); - return to_string((int)a->getType()) + "#" + to_string((int)a->getMemType()) + "#" + a->getValue(); - }; - - auto memKeyFromInstr = [&](const SAPFOR::Instruction* instr) -> string - { - if (!instr) - return string(); - SgExpression* ex = instr->getExpression(); - if (!ex) - return string(); - - auto exprKey = [&](auto&& self, SgExpression* e) -> string + try { - if (!e) - return string("_"); - - if (auto* ar = isSgArrayRefExp(e)) - { - SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr; - string key = string("A(") + (sym ? sym->identifier() : "?"); - const int n = ar->numberOfSubscripts(); - for (int i = 0; i < n; ++i) - { - key += ","; - key += self(self, ar->subscript(i)); - } - key += ")"; - return key; - } - - if (e->variant() == VAR_REF || e->variant() == CONST_REF) - { - SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr; - return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")"; - } - - if (auto* v = isSgValueExp(e)) - { - if (e->variant() == INT_VAL) - return string("I(") + to_string(v->intValue()) + ")"; - if (e->variant() == BOOL_VAL) - return string("B(") + (v->boolValue() ? "1" : "0") + ")"; - if (e->variant() == CHAR_VAL) - return string("CH(") + string(1, v->charValue()) + ")"; - if (e->variant() == FLOAT_VAL) - return string("F(") + (v->floatValue() ? v->floatValue() : "") + ")"; - if (e->variant() == DOUBLE_VAL) - return string("D(") + (v->doubleValue() ? v->doubleValue() : "") + ")"; - if (e->variant() == STRING_VAL) - return string("S(") + (v->stringValue() ? v->stringValue() : "") + ")"; - } - - string key = string("N(") + to_string(e->variant()); - if (e->lhs()) - key += ",L=" + self(self, e->lhs()); - if (e->rhs()) - key += ",R=" + self(self, e->rhs()); - key += ")"; - return key; - }; - - return "MEMEX#" + exprKey(exprKey, ex); + out = stoi(a->getValue()); + return true; + } + catch (...) + { + return false; + } }; - auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool + auto isBarrierInstr = [&](const SAPFOR::Instruction* instr) -> bool { if (!instr) return true; @@ -246,112 +346,229 @@ static map> analyzeBasicBlockIntraDependencie } }; - auto isDef = [&](const SAPFOR::Instruction* instr) -> bool - { - if (!instr) - return false; - SAPFOR::Argument* r = instr->getResult(); - if (!isTrackable(r)) - return false; - - const auto op = instr->getOperation(); - if (op == SAPFOR::CFG_OP::STORE || op == SAPFOR::CFG_OP::REC_REF_STORE) - return false; - - return true; - }; - - // Reaching definitions inside the BasicBlock in straight-line order: - // lastDef[var] = last operator in this block that defined it. - map> lastDef; - map> lastMemDef; + map lastDef; + map lastMemDef; map> depsSets; - for (auto* ir : bb->getInstructions()) + const auto& irs = bb->getInstructions(); + size_t i = 0; + while (i < irs.size()) { + auto* ir = irs[i]; if (!ir || !ir->getInstruction()) - continue; - - const SAPFOR::Instruction* instr = ir->getInstruction(); - SgStatement* opStmt = instr->getOperator(); - if (!opStmt) - continue; - if (isCompoundStmt(opStmt)) - continue; - - if (isBarrier(instr)) { - for (auto it = lastDef.begin(); it != lastDef.end();) - { - const SAPFOR::Argument* a = it->second.second; - if (!a || a->isMemGlobal() || a->isParameter()) - it = lastDef.erase(it); - else - ++it; - } - for (auto it = lastMemDef.begin(); it != lastMemDef.end();) - { - const SAPFOR::Argument* a = it->second.second; - if (!a || a->isMemGlobal() || a->isParameter()) - it = lastMemDef.erase(it); - else - ++it; - } + ++i; + continue; } - if (!result.count(opStmt)) - result[opStmt] = {}; - - auto addDep = [&](SAPFOR::Argument* use) + const SAPFOR::Instruction* firstInstr = ir->getInstruction(); + SgStatement* stmt = firstInstr->getOperator(); + if (!stmt || isCompoundStmt(stmt)) { - if (!isTrackable(use)) - return; - const string k = argKey(use); - auto it = lastDef.find(k); - if (it == lastDef.end()) - return; - if (it->second.first && it->second.first != opStmt) - depsSets[opStmt].insert(it->second.first); + ++i; + continue; + } + + vector group; + group.reserve(8); + bool isBarrierStmt = false; + + while (i < irs.size()) + { + auto* ir2 = irs[i]; + if (!ir2 || !ir2->getInstruction()) + { + ++i; + continue; + } + + const SAPFOR::Instruction* instr = ir2->getInstruction(); + if (instr->getOperator() != stmt) + break; + + group.push_back(instr); + if (isBarrierInstr(instr)) + isBarrierStmt = true; + ++i; + } + + if (!result.count(stmt)) + result[stmt] = {}; + + set usesVars; + set defsVars; + set usesMem; + set defsMem; + + vector idxStack; + idxStack.reserve(8); + + auto idxAtom = [&](const SAPFOR::Argument* a) -> string + { + if (!a) + return string(); + const auto t = a->getType(); + if (t == SAPFOR::CFG_ARG_TYPE::VAR || t == SAPFOR::CFG_ARG_TYPE::CONST || t == SAPFOR::CFG_ARG_TYPE::CONST_STR) + return a->getValue(); + return string("*"); }; - auto addMemDep = [&](const string& key) + auto joinIdx = [&](const vector& idx) -> string { - if (key.empty()) - return; - auto it = lastMemDef.find(key); - if (it == lastMemDef.end()) - return; - if (it->second.first && it->second.first != opStmt) - depsSets[opStmt].insert(it->second.first); + string s; + for (size_t k = 0; k < idx.size(); ++k) + { + if (k) + s += ","; + s += idx[k]; + } + return s; }; - addDep(instr->getArg1()); - addDep(instr->getArg2()); - if (instr->getOperation() == SAPFOR::CFG_OP::RANGE) - addDep(instr->getResult()); - - if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) - addDep(instr->getResult()); - - if (instr->getOperation() == SAPFOR::CFG_OP::LOAD || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD) + auto popLastIdx = [&](int cnt) -> vector { - const string memKey = memKeyFromInstr(instr); - addMemDep(memKey); - } + vector idx; + if (cnt <= 0 || (size_t)cnt > idxStack.size()) + return idx; + idx.assign(idxStack.end() - cnt, idxStack.end()); + idxStack.erase(idxStack.end() - cnt, idxStack.end()); + return idx; + }; - if (isDef(instr)) + auto memKeyFromLoadStore = [&](const SAPFOR::Instruction* instr) -> string { - const string dk = argKey(instr->getResult()); - lastDef[dk] = { opStmt, instr->getResult() }; - } - - if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) - { - const string k = memKeyFromInstr(instr); + if (!instr) + return string(); SAPFOR::Argument* base = instr->getArg1(); - if (!k.empty() && base) - lastMemDef[k] = { opStmt, base }; - addMemDep(k); + if (!isArrayArg(base)) + return string(); + + int cnt = 0; + if (!parseIntConst(instr->getArg2(), cnt)) + cnt = 0; + const auto idx = popLastIdx(cnt); + return base->getValue() + "[" + joinIdx(idx) + "]"; + }; + + string lastStoreKey; + string lastScalarDefKey; + + for (auto* instr : group) + { + if (!instr) + continue; + + if (isVarArg(instr->getArg1())) + usesVars.insert(varKey(instr->getArg1())); + if (isVarArg(instr->getArg2())) + usesVars.insert(varKey(instr->getArg2())); + + if (instr->getOperation() == SAPFOR::CFG_OP::RANGE && isVarArg(instr->getResult())) + usesVars.insert(varKey(instr->getResult())); + + if ((instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) && + isVarArg(instr->getResult())) + { + usesVars.insert(varKey(instr->getResult())); + } + + if (instr->getOperation() == SAPFOR::CFG_OP::REF) + { + idxStack.push_back(idxAtom(instr->getArg1())); + } + else if (instr->getOperation() == SAPFOR::CFG_OP::RANGE) + { + idxStack.push_back(idxAtom(instr->getArg1()) + ":" + idxAtom(instr->getArg2()) + ":" + idxAtom(instr->getResult())); + } + else if (instr->getOperation() == SAPFOR::CFG_OP::LOAD || instr->getOperation() == SAPFOR::CFG_OP::STORE) + { + int dimCnt = 0; + if (!parseIntConst(instr->getArg2(), dimCnt)) + dimCnt = 0; + + string k; + if (instr->getExpression()) + { + k = memexKeyForArrayLoadStore(instr, []() { return string(); }); + if (!k.empty()) + popLastIdx(dimCnt); + } + if (k.empty()) + k = memKeyFromLoadStore(instr); + + if (!k.empty()) + { + if (instr->getOperation() == SAPFOR::CFG_OP::LOAD) + usesMem.insert(k); + else + { + defsMem.insert(k); + lastStoreKey = k; + } + } + } + else if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) + { + SAPFOR::Argument* base = instr->getArg1(); + if (base && (base->getType() == SAPFOR::CFG_ARG_TYPE::RECORD || base->getType() == SAPFOR::CFG_ARG_TYPE::VAR)) + { + const string k = base->getValue(); + if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD) + usesMem.insert(k); + else + { + defsMem.insert(k); + lastStoreKey = k; + } + } + } + } + + if (!group.empty()) + { + const SAPFOR::Instruction* last = group.back(); + if (last && last->getOperation() == SAPFOR::CFG_OP::ASSIGN && isVarArg(last->getResult())) + { + lastScalarDefKey = varKey(last->getResult()); + defsVars.insert(lastScalarDefKey); + } + else if (last && (last->getOperation() == SAPFOR::CFG_OP::STORE || last->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)) + { + if (!lastStoreKey.empty()) + defsMem.insert(lastStoreKey); + } + } + + auto addDepFromMap = [&](const map& m, const string& k) + { + auto it = m.find(k); + if (it == m.end()) + return; + if (it->second && it->second != stmt) + depsSets[stmt].insert(it->second); + }; + + for (const auto& k : usesVars) + addDepFromMap(lastDef, k); + for (const auto& k : usesMem) + addDepFromMap(lastMemDef, k); + + if (isBarrierStmt) + { + lastDef.clear(); + lastMemDef.clear(); + continue; + } + + for (const auto& k : defsVars) + { + addDepFromMap(lastDef, k); + lastDef[k] = stmt; + } + for (const auto& k : defsMem) + { + addDepFromMap(lastMemDef, k); + lastMemDef[k] = stmt; } } From 62e996f2e21c2e27f78c85879dafb3c862c86b87 Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 5 May 2026 15:50:03 +0300 Subject: [PATCH 31/32] Fix move operators pass --- .../MoveOperators/move_operators.cpp | 871 ++++++------------ 1 file changed, 304 insertions(+), 567 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index bc9b1e5..234c3c0 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "../../Utils/errors.h" #include "../../Utils/SgUtils.h" @@ -20,254 +21,124 @@ using namespace std; -set loop_tags = {FOR_NODE}; +set loop_tags = {FOR_NODE, WHILE_NODE, DO_WHILE_NODE}; set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; set control_end_tags = {CONTROL_END}; -namespace + +static bool isParentStmt(SgStatement* stmt, SgStatement* parent) { -enum class ArrayIndexCompareResult -{ - Equal, - NotEqual, - Unknown -}; - -// Structural key for array index / subscript analysis (stable across LOAD/STORE of the same access). -string buildStructuralExprKey(SgExpression* e) -{ - if (!e) - return string("_"); - - if (auto* ar = isSgArrayRefExp(e)) - { - SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr; - string key = string("A(") + (sym ? sym->identifier() : "?"); - const int n = ar->numberOfSubscripts(); - for (int i = 0; i < n; ++i) - { - key += ","; - key += buildStructuralExprKey(ar->subscript(i)); - } - key += ")"; - return key; - } - - if (e->variant() == VAR_REF || e->variant() == CONST_REF) - { - SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr; - return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")"; - } - - if (auto* v = isSgValueExp(e)) - { - if (e->variant() == INT_VAL) - return string("I(") + to_string(v->intValue()) + ")"; - if (e->variant() == BOOL_VAL) - return string("B(") + (v->boolValue() ? "1" : "0") + ")"; - if (e->variant() == CHAR_VAL) - return string("CH(") + string(1, v->charValue()) + ")"; - if (e->variant() == FLOAT_VAL) - { - char* fv = v->floatValue(); - return string("F(") + (fv ? string(fv) : string()) + ")"; - } - if (e->variant() == DOUBLE_VAL) - { - char* dv = v->doubleValue(); - if (!dv || !*dv) - return string("D()"); - char* endp = nullptr; - const double d = strtod(dv, &endp); - if (endp != dv && std::isfinite(d)) - { - const double r = std::round(d); - if (std::fabs(d - r) < 1e-12 && r >= static_cast(INT_MIN) && r <= static_cast(INT_MAX)) - return string("I(") + to_string(static_cast(r)) + ")"; - } - return string("D(") + string(dv) + ")"; - } - if (e->variant() == STRING_VAL) - return string("S(") + (v->stringValue() ? v->stringValue() : string()) + ")"; - } - - if (e->variant() == MULT_OP && e->lhs() && e->rhs()) - { - string a = buildStructuralExprKey(e->lhs()); - string b = buildStructuralExprKey(e->rhs()); - if (a > b) - swap(a, b); - return string("N(") + to_string(e->variant()) + ",L=" + a + ",R=" + b + ")"; - } - - string key = string("N(") + to_string(e->variant()); - if (e->lhs()) - key += ",L=" + buildStructuralExprKey(e->lhs()); - if (e->rhs()) - key += ",R=" + buildStructuralExprKey(e->rhs()); - key += ")"; - return key; + for (; stmt; stmt = stmt->controlParent()) + if (stmt == parent) + return true; + return false; } -// Prefer AST from IR instruction (same SgArrayRef for matching store/load); fallback to idxStack string. -string memexKeyForArrayLoadStore(const SAPFOR::Instruction* instr, const function& irStackKey) +static bool isStatementInFile(SgStatement* st, const string& fileName) { - if (!instr) - return string(); - SgExpression* ex = instr->getExpression(); - if (ex) - { - if (isSgArrayRefExp(ex)) - return string("MEMEX#") + buildStructuralExprKey(ex); - return string("MEMEX#") + buildStructuralExprKey(ex); - } - return irStackKey(); -} - -ArrayIndexCompareResult compareIndexExpressions(SgExpression* a, SgExpression* b) -{ - if (!a && !b) - return ArrayIndexCompareResult::Equal; - if (!a || !b) - return ArrayIndexCompareResult::NotEqual; - const string ka = buildStructuralExprKey(a); - const string kb = buildStructuralExprKey(b); - if (ka.empty() || kb.empty()) - return ArrayIndexCompareResult::Unknown; - if (ka == kb) - return ArrayIndexCompareResult::Equal; - return ArrayIndexCompareResult::NotEqual; -} - -ArrayIndexCompareResult compareArrayRefExpressions(SgArrayRefExp* a, SgArrayRefExp* b) -{ - if (!a && !b) - return ArrayIndexCompareResult::Equal; - if (!a || !b) - return ArrayIndexCompareResult::NotEqual; - SgSymbol* s1 = a->symbol() ? OriginalSymbol(a->symbol()) : nullptr; - SgSymbol* s2 = b->symbol() ? OriginalSymbol(b->symbol()) : nullptr; - if (s1 && s2) - { - if (strcmp(s1->identifier(), s2->identifier()) != 0) - return ArrayIndexCompareResult::NotEqual; - } - else if (s1 != s2) - return ArrayIndexCompareResult::NotEqual; - if (a->numberOfSubscripts() != b->numberOfSubscripts()) - return ArrayIndexCompareResult::NotEqual; - for (int i = 0; i < a->numberOfSubscripts(); ++i) - { - ArrayIndexCompareResult c = compareIndexExpressions(a->subscript(i), b->subscript(i)); - if (c != ArrayIndexCompareResult::Equal) - return c; - } - return ArrayIndexCompareResult::Equal; -} -} // namespace - -static vector findInstructionsFromStatement(SgStatement* st, const vector& blocks) -{ - vector result; if (!st) - return result; + return false; - const int stmtId = st->id(); - for (auto* bb : blocks) + const char* stmtFile = st->fileName(); + return stmtFile && fileName == stmtFile; +} + +static vector findLoopStatementsInFunction(SgStatement* funcStmt, const string& fileName) +{ + vector loops; + if (!funcStmt) + return loops; + + SgStatement* lastNode = funcStmt->lastNodeOfStmt(); + for (SgStatement* st = funcStmt; st && st != lastNode; st = st->lexNext()) + if (loop_tags.count(st->variant()) && isStatementInFile(st, fileName)) + loops.push_back(st); + + return loops; +} + +static SgStatement* firstSignificantOperatorInBlock(const SAPFOR::BasicBlock* bb, const string& fileName) +{ + if (!bb) + return nullptr; + + for (auto* ir : bb->getInstructions()) { - if (!bb) + if (!ir || !ir->getInstruction()) continue; - for (auto* ir : bb->getInstructions()) - { - if (!ir || !ir->getInstruction()) - continue; - - SgStatement* op = ir->getInstruction()->getOperator(); - if (op && op->id() == stmtId) - result.push_back(ir); - } + SgStatement* st = ir->getInstruction()->getOperator(); + if (isStatementInFile(st, fileName)) + return st; } - sort(result.begin(), result.end(), - [](const SAPFOR::IR_Block* a, const SAPFOR::IR_Block* b) { return a->getNumber() < b->getNumber(); }); - return result; + return nullptr; } -vector findFuncBlocksByFuncStatement(SgStatement *st, const map>& FullIR) { - vector result; - if (!st) - return result; +static SgStatement* lastSignificantOperatorInBlock(const SAPFOR::BasicBlock* bb, const string& fileName) +{ + if (!bb) + return nullptr; - Statement* forSt = (Statement*)st; - const string stmtFile = st->fileName(); - const int stmtLine = st->lineNumber(); - - for (auto& func: FullIR) { - if (!func.first || !func.first->funcPointer) + const auto& instructions = bb->getInstructions(); + for (auto it = instructions.rbegin(); it != instructions.rend(); ++it) + { + auto* ir = *it; + if (!ir || !ir->getInstruction()) continue; - const string funcFile = func.first->fileName; - const int funcLine = func.first->funcPointer->lineNumber(); - - // Important: select CFG blocks only for the same file and function header. - if (funcFile == stmtFile && funcLine == stmtLine) - { - result = func.second; - break; - } + SgStatement* st = ir->getInstruction()->getOperator(); + if (isStatementInFile(st, fileName)) + return st; } - return result; + + return nullptr; } -map> findAndAnalyzeLoops(SgStatement *st, const vector& blocks) { - map> result; - SgStatement *lastNode = st->lastNodeOfStmt(); - - while (st && st != lastNode) { - if (loop_tags.find(st -> variant()) != loop_tags.end()) { - SgForStmt *forSt = (SgForStmt*)st; - SgStatement *loopBody = forSt -> body(); - SgStatement *lastLoopNode = st->lastNodeOfStmt(); - set blocks_nums; - - while (loopBody && loopBody != lastLoopNode) { - vector irBlocks = findInstructionsFromStatement(loopBody, blocks); - if (!irBlocks.empty()) { - SAPFOR::IR_Block* IR = irBlocks.front(); - if (IR && IR->getBasicBlock()) { - if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end()) { - result[forSt].push_back(IR -> getBasicBlock()); - blocks_nums.insert(IR -> getBasicBlock() -> getNumber()); - } - } - } - loopBody = loopBody -> lexNext(); - } - sort(result[forSt].begin(), result[forSt].end()); - } - st = st -> lexNext(); - } - return result; +static bool isBasicBlockInAnyLoop(const SAPFOR::BasicBlock* bb, const vector& loops, const string& fileName) +{ + SgStatement* first = firstSignificantOperatorInBlock(bb, fileName); + SgStatement* last = lastSignificantOperatorInBlock(bb, fileName); + if (!first || !last) + return false; + + + + for (auto* loop : loops) + if (loop && isParentStmt(first, loop) && isParentStmt(last, loop)) + return true; + + return false; } - -vector findBlocksInLoopsByFullIR( - SgStatement* funcStmt, +static vector findBlocksInLoopsByFullIR( + SgFile* file, const map>& FullIR) { vector result; - if (!funcStmt) + if (!file || !file->filename()) return result; - const vector funcBlocks = findFuncBlocksByFuncStatement(funcStmt, FullIR); - const auto loopsMapping = findAndAnalyzeLoops(funcStmt, funcBlocks); - + const string fileName = file->filename(); set uniq; - for (const auto& kv : loopsMapping) - for (auto* bb : kv.second) - if (bb) + + for (const auto& func : FullIR) + { + FuncInfo* funcInfo = func.first; + if (!funcInfo || !funcInfo->funcPointer) + continue; + + if (funcInfo->fileName != fileName) + continue; + + const vector loops = findLoopStatementsInFunction(funcInfo->funcPointer, fileName); + if (loops.empty()) + continue; + + for (auto* bb : func.second) + if (isBasicBlockInAnyLoop(bb, loops, fileName)) uniq.insert(bb); + } result.assign(uniq.begin(), uniq.end()); sort(result.begin(), result.end(), @@ -281,11 +152,10 @@ vector findBlocksInLoopsByFullIR( return result; } -static map> analyzeBasicBlockIntraDependencies(const SAPFOR::BasicBlock* bb) +static map> analyzeBasicBlockIntraDependencies(const SAPFOR::BasicBlock* bb) { - map> result; if (!bb) - return result; + return {}; auto isCompoundStmt = [](SgStatement* st) -> bool { @@ -295,306 +165,193 @@ static map> analyzeBasicBlockIntraDependencie return loop_tags.count(v) || control_tags.count(v) || control_end_tags.count(v); }; - auto isVarArg = [](const SAPFOR::Argument* a) -> bool + auto normalizeSageString = [](const string& src) -> string { - return a && a->getType() == SAPFOR::CFG_ARG_TYPE::VAR; + string normalized; + bool prevSpace = false; + + for (char ch : src) + { + const bool isSpace = std::isspace(static_cast(ch)); + if (isSpace) + { + if (!normalized.empty()) + prevSpace = true; + continue; + } + + if (prevSpace && !normalized.empty()) + normalized += ' '; + normalized += ch; + prevSpace = false; + } + + return normalized; }; - auto isArrayArg = [](const SAPFOR::Argument* a) -> bool + auto sageExprToString = [&](SgExpression* expr) -> string { - return a && a->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY; - }; - - auto varKey = [&](const SAPFOR::Argument* a) -> string - { - if (!a) + if (!expr) return string(); - return a->getValue(); + + char* raw = expr->unparse(); + return normalizeSageString(raw ? string(raw) : string()); }; - auto parseIntConst = [](const SAPFOR::Argument* a, int& out) -> bool + auto arrayElementKey = [&](SgArrayRefExp* arrayRef) -> string { - if (!a || a->getType() != SAPFOR::CFG_ARG_TYPE::CONST) - return false; - try + if (!arrayRef) + return string(); + + string key; + SgSymbol* sym = arrayRef->symbol() ? OriginalSymbol(arrayRef->symbol()) : nullptr; + if (sym && sym->identifier()) + key = sym->identifier(); + else + return sageExprToString(arrayRef); + + if (key.empty()) + return string(); + + key += "("; + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) { - out = stoi(a->getValue()); - return true; + if (i) + key += ", "; + key += sageExprToString(arrayRef->subscript(i)); } - catch (...) + key += ")"; + + return key; + }; + + function&)> collectUsedKeysFromExpression = + [&](SgExpression* expr, set& usedKeys) + { + if (!expr) + return; + + if (isSgValueExp(expr) || expr->variant() == CONST_REF) + return; + + if (auto* arrayRef = isSgArrayRefExp(expr)) { - return false; + const string key = arrayElementKey(arrayRef); + if (!key.empty()) + usedKeys.insert(key); + + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) + collectUsedKeysFromExpression(arrayRef->subscript(i), usedKeys); + return; + } + + if (auto* call = isSgFunctionCallExp(expr)) + { + for (int i = 0; i < call->numberOfArgs(); ++i) + collectUsedKeysFromExpression(call->arg(i), usedKeys); + return; + } + + if (expr->variant() == VAR_REF) + { + SgSymbol* sym = expr->symbol() ? OriginalSymbol(expr->symbol()) : nullptr; + if (sym && sym->identifier()) + usedKeys.insert(sym->identifier()); + return; + } + + collectUsedKeysFromExpression(expr->lhs(), usedKeys); + collectUsedKeysFromExpression(expr->rhs(), usedKeys); + }; + + auto collectUsedKeysFromArraySubscripts = [&](SgArrayRefExp* arrayRef, set& usedKeys) + { + if (!arrayRef) + return; + + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) + collectUsedKeysFromExpression(arrayRef->subscript(i), usedKeys); + }; + + auto addOperatorDependencies = [&](SgStatement* stmt, + const set& usedKeys, + const map& varDeclarations, + map>& operatorsDependencies) + { + if (!stmt) + return; + + for (const string& key : usedKeys) + { + auto it = varDeclarations.find(key); + if (it != varDeclarations.end() && it->second && it->second != stmt) + operatorsDependencies[stmt].insert(it->second); } }; - auto isBarrierInstr = [&](const SAPFOR::Instruction* instr) -> bool + auto declarationKeyFromLeftPart = [&](SgStatement* stmt) -> string { - if (!instr) - return true; - const auto op = instr->getOperation(); - switch (op) + if (!stmt || stmt->variant() != ASSIGN_STAT) + return string(); + + SgExpression* lhs = stmt->expr(0); + if (!lhs) + return string(); + + if (auto* arrayRef = isSgArrayRefExp(lhs)) + return arrayElementKey(arrayRef); + + if (lhs->variant() == VAR_REF) { - case SAPFOR::CFG_OP::F_CALL: - case SAPFOR::CFG_OP::IO_PARAM: - case SAPFOR::CFG_OP::DVM_DIR: - case SAPFOR::CFG_OP::SPF_DIR: - case SAPFOR::CFG_OP::POINTER_ASS: - case SAPFOR::CFG_OP::EXIT: - return true; - default: - return false; + SgSymbol* sym = lhs->symbol() ? OriginalSymbol(lhs->symbol()) : nullptr; + if (sym && sym->identifier()) + return sym->identifier(); } + + return string(); }; - map lastDef; - map lastMemDef; - map> depsSets; + vector operatorsOrder; + set seenOperators; - const auto& irs = bb->getInstructions(); - size_t i = 0; - while (i < irs.size()) + for (auto* ir : bb->getInstructions()) { - auto* ir = irs[i]; if (!ir || !ir->getInstruction()) - { - ++i; continue; - } - const SAPFOR::Instruction* firstInstr = ir->getInstruction(); - SgStatement* stmt = firstInstr->getOperator(); + const SAPFOR::Instruction* instr = ir->getInstruction(); + SgStatement* stmt = instr->getOperator(); if (!stmt || isCompoundStmt(stmt)) - { - ++i; continue; - } - vector group; - group.reserve(8); - bool isBarrierStmt = false; - - while (i < irs.size()) - { - auto* ir2 = irs[i]; - if (!ir2 || !ir2->getInstruction()) - { - ++i; - continue; - } - - const SAPFOR::Instruction* instr = ir2->getInstruction(); - if (instr->getOperator() != stmt) - break; - - group.push_back(instr); - if (isBarrierInstr(instr)) - isBarrierStmt = true; - ++i; - } - - if (!result.count(stmt)) - result[stmt] = {}; - - set usesVars; - set defsVars; - set usesMem; - set defsMem; - - vector idxStack; - idxStack.reserve(8); - - auto idxAtom = [&](const SAPFOR::Argument* a) -> string - { - if (!a) - return string(); - const auto t = a->getType(); - if (t == SAPFOR::CFG_ARG_TYPE::VAR || t == SAPFOR::CFG_ARG_TYPE::CONST || t == SAPFOR::CFG_ARG_TYPE::CONST_STR) - return a->getValue(); - return string("*"); - }; - - auto joinIdx = [&](const vector& idx) -> string - { - string s; - for (size_t k = 0; k < idx.size(); ++k) - { - if (k) - s += ","; - s += idx[k]; - } - return s; - }; - - auto popLastIdx = [&](int cnt) -> vector - { - vector idx; - if (cnt <= 0 || (size_t)cnt > idxStack.size()) - return idx; - idx.assign(idxStack.end() - cnt, idxStack.end()); - idxStack.erase(idxStack.end() - cnt, idxStack.end()); - return idx; - }; - - auto memKeyFromLoadStore = [&](const SAPFOR::Instruction* instr) -> string - { - if (!instr) - return string(); - SAPFOR::Argument* base = instr->getArg1(); - if (!isArrayArg(base)) - return string(); - - int cnt = 0; - if (!parseIntConst(instr->getArg2(), cnt)) - cnt = 0; - const auto idx = popLastIdx(cnt); - return base->getValue() + "[" + joinIdx(idx) + "]"; - }; - - string lastStoreKey; - string lastScalarDefKey; - - for (auto* instr : group) - { - if (!instr) - continue; - - if (isVarArg(instr->getArg1())) - usesVars.insert(varKey(instr->getArg1())); - if (isVarArg(instr->getArg2())) - usesVars.insert(varKey(instr->getArg2())); - - if (instr->getOperation() == SAPFOR::CFG_OP::RANGE && isVarArg(instr->getResult())) - usesVars.insert(varKey(instr->getResult())); - - if ((instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) && - isVarArg(instr->getResult())) - { - usesVars.insert(varKey(instr->getResult())); - } - - if (instr->getOperation() == SAPFOR::CFG_OP::REF) - { - idxStack.push_back(idxAtom(instr->getArg1())); - } - else if (instr->getOperation() == SAPFOR::CFG_OP::RANGE) - { - idxStack.push_back(idxAtom(instr->getArg1()) + ":" + idxAtom(instr->getArg2()) + ":" + idxAtom(instr->getResult())); - } - else if (instr->getOperation() == SAPFOR::CFG_OP::LOAD || instr->getOperation() == SAPFOR::CFG_OP::STORE) - { - int dimCnt = 0; - if (!parseIntConst(instr->getArg2(), dimCnt)) - dimCnt = 0; - - string k; - if (instr->getExpression()) - { - k = memexKeyForArrayLoadStore(instr, []() { return string(); }); - if (!k.empty()) - popLastIdx(dimCnt); - } - if (k.empty()) - k = memKeyFromLoadStore(instr); - - if (!k.empty()) - { - if (instr->getOperation() == SAPFOR::CFG_OP::LOAD) - usesMem.insert(k); - else - { - defsMem.insert(k); - lastStoreKey = k; - } - } - } - else if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) - { - SAPFOR::Argument* base = instr->getArg1(); - if (base && (base->getType() == SAPFOR::CFG_ARG_TYPE::RECORD || base->getType() == SAPFOR::CFG_ARG_TYPE::VAR)) - { - const string k = base->getValue(); - if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD) - usesMem.insert(k); - else - { - defsMem.insert(k); - lastStoreKey = k; - } - } - } - } - - if (!group.empty()) - { - const SAPFOR::Instruction* last = group.back(); - if (last && last->getOperation() == SAPFOR::CFG_OP::ASSIGN && isVarArg(last->getResult())) - { - lastScalarDefKey = varKey(last->getResult()); - defsVars.insert(lastScalarDefKey); - } - else if (last && (last->getOperation() == SAPFOR::CFG_OP::STORE || last->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)) - { - if (!lastStoreKey.empty()) - defsMem.insert(lastStoreKey); - } - } - - auto addDepFromMap = [&](const map& m, const string& k) - { - auto it = m.find(k); - if (it == m.end()) - return; - if (it->second && it->second != stmt) - depsSets[stmt].insert(it->second); - }; - - for (const auto& k : usesVars) - addDepFromMap(lastDef, k); - for (const auto& k : usesMem) - addDepFromMap(lastMemDef, k); - - if (isBarrierStmt) - { - lastDef.clear(); - lastMemDef.clear(); - continue; - } - - for (const auto& k : defsVars) - { - addDepFromMap(lastDef, k); - lastDef[k] = stmt; - } - for (const auto& k : defsMem) - { - addDepFromMap(lastMemDef, k); - lastMemDef[k] = stmt; - } + if (seenOperators.insert(stmt).second) + operatorsOrder.push_back(stmt); } - for (auto& kv : result) + map varDeclarations; + map> operatorsDependencies; + + for (SgStatement* stmt : operatorsOrder) { - SgStatement* op = kv.first; - auto it = depsSets.find(op); - if (it == depsSets.end()) - continue; + set usedKeys; + if (stmt) + { + collectUsedKeysFromExpression(stmt->expr(1), usedKeys); + collectUsedKeysFromArraySubscripts(isSgArrayRefExp(stmt->expr(0)), usedKeys); + } + addOperatorDependencies(stmt, usedKeys, varDeclarations, operatorsDependencies); - kv.second.assign(it->second.begin(), it->second.end()); - sort(kv.second.begin(), kv.second.end(), - [](SgStatement* a, SgStatement* b) - { - const int la = a ? a->lineNumber() : -1; - const int lb = b ? b->lineNumber() : -1; - if (la != lb) - return la < lb; - return a < b; - }); + const string declarationKey = declarationKeyFromLeftPart(stmt); + if (!declarationKey.empty()) + varDeclarations[declarationKey] = stmt; } - return result; + return operatorsDependencies; } -static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const char* expectedFile) +static bool reorderOperatorsInBasicBlockUsingDeps( + SAPFOR::BasicBlock* bb, + const map>& operatorsDependencies) { if (!bb) return false; @@ -624,18 +381,6 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const if (ops.size() < 2) return false; - // Check that analyzed BB is in the same file as the expected file - const char* bbFile = ops.front()->fileName(); - if (!bbFile) - bbFile = "(unknown)"; - if (expectedFile && strcmp(expectedFile, bbFile) != 0) - return false; - for (auto* st : ops) - { - if (!st || !st->fileName() || strcmp(st->fileName(), bbFile) != 0) - return false; - } - SgStatement* parent = ops.front()->controlParent(); if (!parent) return false; @@ -683,76 +428,72 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const return false; } - // Compute dependencies (inside BB) and build a new order by moving each statement - // as close as possible after its last dependency (if any). - const auto depsMap = analyzeBasicBlockIntraDependencies(bb); - vector order = ops; - const vector originalOrder = ops; - const int nOrig = (int)originalOrder.size(); + map originalIndex; + for (int i = 0; i < (int)ops.size(); ++i) + originalIndex[ops[i]] = i; - auto indexIn = [](const vector& v, SgStatement* s) -> int - { - for (int i = 0; i < (int)v.size(); ++i) - if (v[i] == s) - return i; - return -1; - }; + map> moveAfter; + set moved; - auto indexInOriginal = [&](SgStatement* s) -> int + for (SgStatement* st : ops) { - return indexIn(originalOrder, s); - }; - - for (SgStatement* s : ops) - { - auto itDeps = depsMap.find(s); - if (itDeps == depsMap.end() || itDeps->second.empty()) + auto itDeps = operatorsDependencies.find(st); + if (itDeps == operatorsDependencies.end() || itDeps->second.empty()) continue; - int lastDepOrigIdx = -1; + SgStatement* lastDep = nullptr; + int lastDepIdx = -1; for (SgStatement* dep : itDeps->second) { - const int j = indexInOriginal(dep); - if (j >= 0) - lastDepOrigIdx = max(lastDepOrigIdx, j); + auto itIdx = originalIndex.find(dep); + if (itIdx != originalIndex.end() && itIdx->second > lastDepIdx) + { + lastDep = dep; + lastDepIdx = itIdx->second; + } } - if (lastDepOrigIdx < 0) + if (!lastDep || lastDep == st) continue; - SgStatement* successor = nullptr; - if (lastDepOrigIdx + 1 < nOrig) - successor = originalOrder[lastDepOrigIdx + 1]; - - int posS = indexIn(order, s); - if (posS < 0) - continue; - - if (successor == nullptr) - { - if (posS == (int)order.size() - 1) - continue; - order.erase(order.begin() + posS); - order.push_back(s); - continue; - } - - if (successor == s) - continue; - - const int posSucc = indexIn(order, successor); - if (posSucc < 0) - continue; - - if (posS + 1 == posSucc) - continue; - - order.erase(order.begin() + posS); - const int posSucc2 = indexIn(order, successor); - if (posSucc2 < 0) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - order.insert(order.begin() + posSucc2, s); + moveAfter[lastDep].push_back(st); + moved.insert(st); } + vector order; + order.reserve(ops.size()); + set emitted; + set active; + bool invalidOrder = false; + + function emitStatement = [&](SgStatement* st) + { + if (!st || invalidOrder || emitted.count(st)) + return; + if (active.count(st)) + { + invalidOrder = true; + return; + } + + active.insert(st); + emitted.insert(st); + order.push_back(st); + + auto itMovedAfter = moveAfter.find(st); + if (itMovedAfter != moveAfter.end()) + for (SgStatement* dependent : itMovedAfter->second) + emitStatement(dependent); + + active.erase(st); + }; + + for (SgStatement* st : ops) + if (!moved.count(st)) + emitStatement(st); + + if (invalidOrder || order.size() != ops.size()) + return false; + bool changed = false; for (size_t i = 0; i < ops.size(); ++i) if (ops[i] != order[i]) @@ -826,18 +567,14 @@ void moveOperators(SgFile* file, const mapfilename()) == -1) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - const int funcNum = file->numberOfFunctions(); - for (int i = 0; i < funcNum; ++i) - { - SgStatement* st = file->functions(i); + const auto loopBlocks = findBlocksInLoopsByFullIR(file, FullIR); - const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR); - for (auto* bb : loopBlocks) - { - if (!bb) - continue; - if (reorderOperatorsInBasicBlockUsingDeps(bb, file->filename())) - countOfTransform += 1; - } + for (auto* bb : loopBlocks) + { + if (!bb) + continue; + const auto operatorsDependencies = analyzeBasicBlockIntraDependencies(bb); + if (reorderOperatorsInBasicBlockUsingDeps(bb, operatorsDependencies)) + countOfTransform += 1; } } From 3465feca351c18696a2fdd15f3272151cb15ee9d Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 5 May 2026 16:47:31 +0300 Subject: [PATCH 32/32] remove redundant --- src/Transformations/MoveOperators/move_operators.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index 234c3c0..686cbd3 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -5,18 +5,14 @@ #include #include #include -#include -#include #include #include #include "../../Utils/errors.h" #include "../../Utils/SgUtils.h" #include "../../GraphCall/graph_calls.h" -#include "../../GraphCall/graph_calls_func.h" #include "../../CFGraph/CFGraph.h" #include "../../CFGraph/IR.h" -#include "../../GraphLoop/graph_loops.h" #include "move_operators.h" using namespace std; @@ -102,8 +98,6 @@ static bool isBasicBlockInAnyLoop(const SAPFOR::BasicBlock* bb, const vector