From fe31df0ef21714d0ddef42d12dc17d3bd0664b77 Mon Sep 17 00:00:00 2001 From: xnpster Date: Sat, 13 Sep 2025 20:48:24 +0300 Subject: [PATCH 1/6] REMOVE_DIST_ARRAYS_FROM_IO: handle assumed-size and assumed-shape arrays --- .../replace_dist_arrays_in_io.cpp | 281 +++++++++++++++++- 1 file changed, 266 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 4cf9961..a6df223 100644 --- a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp +++ b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp @@ -17,6 +17,86 @@ using std::pair; #define DEBUG_TRACE 0 +static bool findAlloatableKeyword(SgExpression* exp) +{ + if (exp) + { + if (exp->variant() == ALLOCATABLE_OP) + return true; + + return findAlloatableKeyword(exp->lhs()) || findAlloatableKeyword(exp->rhs()); + } + + return false; +} + + +static bool checkDynamicArray(DIST::Array *array) +{ + for (const auto &bounds : array->GetSizes()) + if (bounds.first == -1 || bounds.second == -1) + return true; + + return false; +} + +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; +} + +static bool checkAssumedSize(SgStatement *st, const string &arrayName, const string ¤tFile) +{ + __spf_print(1, "Try array %s\n", arrayName.c_str()); + bool found = false; + + DIST::Array* array_p = getArrayFromDeclarated(st, arrayName); + + auto place = *array_p->GetDeclInfo().begin(); + auto decl_file_name = place.first; + + SgFile::switchToFile(decl_file_name); + + SgExpression* list = st->expr(0); + while (list) + { + __spf_print(1, "Try list %s\n", list->lhs()->unparse()); + + if (list->lhs() && list->lhs()->symbol()->identifier() == arrayName) + { + if(findExprWithVariant(list->lhs(), STAR_RANGE)) + found = true; + + break; + } + } + + if (!found) + { + auto *dim_expr = findExprWithVariant(st->expr(2), DIMENSION_OP); + if (dim_expr && findExprWithVariant(dim_expr, STAR_RANGE)) + found = true; + } + + SgFile::switchToFile(currentFile); + + return found; +} + static void findArrays(SgExpression* exp, set& arrays) { if (exp) @@ -29,7 +109,7 @@ static void findArrays(SgExpression* exp, set& arrays) } } -static void populateDistributedIoArrays(map>& arrays, SgStatement* stat) +static void populateDistributedIoArrays(map>& arrays, SgStatement* stat, const string& current_file) { auto var = stat->variant(); @@ -130,8 +210,14 @@ static void populateDistributedIoArrays(map>& array { string array_name = string(by_symb->identifier()); DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(by_symb), array_name); - if (array_p && array_p->GetDistributeFlagVal() == Distribution::distFlag::IO_PRIV && arrays[by_symb].insert(stat).second) + if (array_p && + array_p->GetDistributeFlagVal() == Distribution::distFlag::IO_PRIV && + !checkAssumedSize(declaratedInStmt(by_symb), array_name, current_file) && + arrays[by_symb].insert(stat).second + ) + { __spf_print(DEBUG_TRACE, "[%d]: add array %s\n", stat->lineNumber(), array_p->GetName().c_str()); + } } __spf_print(DEBUG_TRACE, "[replace]\n"); @@ -204,7 +290,12 @@ static void replaceArrayRec(SgSymbol* arr, SgSymbol* replace_by, SgStatement* st } } -static void copyArrayBetweenStatements(SgSymbol* replace_symb, SgSymbol* replace_by, SgStatement* start, SgStatement* last, bool start_is_scope) +static void copyArrayBetweenStatements(SgSymbol* replace_symb, + SgSymbol* replace_by, + SgStatement* start, + SgStatement* last, + bool start_is_scope, + FuncInfo *func_info) { while (start->lexNext() && !isSgExecutableStatement(start->lexNext())) start = start->lexNext(); @@ -227,6 +318,18 @@ static void copyArrayBetweenStatements(SgSymbol* replace_symb, SgSymbol* replace start->insertStmtAfter(*assign, *parent); } + if (has_write) + { + for (int i = 0; i < func_info->funcParams.identificators.size(); i++) + { + if (func_info->funcParams.identificators[i] == replace_symb->identifier()) + { + has_write &= func_info->funcParams.isArgOut(i); + break; + } + } + } + if (has_write) { // A = A_reg @@ -237,9 +340,15 @@ static void copyArrayBetweenStatements(SgSymbol* replace_symb, SgSymbol* replace } } -static void replaceArrayInFragment(SgSymbol* replace_symb, const set usages, SgSymbol* replace_by, SgStatement* start, SgStatement* last, const string& filename) +static void replaceArrayInFragment(SgSymbol* replace_symb, + const set usages, + SgSymbol* replace_by, + SgStatement* start, + SgStatement* last, + FuncInfo *func_info, + const string& filename) { - while (start->lexNext() && !isSgExecutableStatement(start->lexNext())) + while (start->lexNext() && (!isSgExecutableStatement(start->lexNext()) || start->lexNext()->variant() == ALLOCATE_STMT)) start = start->lexNext(); set not_opened, not_closed, copied; @@ -306,7 +415,7 @@ static void replaceArrayInFragment(SgSymbol* replace_symb, const setidentifier(), scope_start->lineNumber(), scope_end->lineNumber()); - copyArrayBetweenStatements(replace_symb, replace_by, scope_start, scope_end, copy_scope == scope_start); + copyArrayBetweenStatements(replace_symb, replace_by, scope_start, scope_end, copy_scope == scope_start, func_info); copied.insert(copy_scope); } } @@ -365,6 +474,16 @@ void replaceDistributedArraysInIO(vector& regions, if (SgFile::switchToFile(filename) == -1) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + auto func_info_it = allFuncInfo.find(filename); + if (func_info_it == allFuncInfo.end()) + { + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + return; + } + + auto *lbound_symb = new SgSymbol(PROCEDURE_NAME, "lbound"); + auto *ubound_symb = new SgSymbol(PROCEDURE_NAME, "ubound"); + for (auto& lines : linesByFile.second) { __spf_print(DEBUG_TRACE, "[fragment] %s: %d:%d %d\n", filename.c_str(), lines.lines.first, @@ -374,7 +493,6 @@ void replaceDistributedArraysInIO(vector& regions, if (lines.isImplicit()) { - curr_stmt = current_file->SgStatementAtLine(lines.lines.first); end = current_file->SgStatementAtLine(lines.lines.second); @@ -390,6 +508,7 @@ void replaceDistributedArraysInIO(vector& regions, map> need_replace; SgStatement* last_io_bound = NULL; + FuncInfo *current_func_info = NULL; while (curr_stmt != end) { @@ -398,9 +517,24 @@ void replaceDistributedArraysInIO(vector& regions, auto var = curr_stmt->variant(); - 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__); + return; + } + curr_stmt = curr_stmt->lexNext(); while (curr_stmt && !isSgExecutableStatement(curr_stmt)) { @@ -428,7 +562,7 @@ void replaceDistributedArraysInIO(vector& regions, const string locationName = array_p->GetLocation().second; auto place = *array_p->GetDeclInfo().begin(); - string fileName = place.first; + auto decl_file_name = place.first; string suffix = "_io_l"; if (fromModule) @@ -437,7 +571,7 @@ void replaceDistributedArraysInIO(vector& regions, pair copied; copied.first = array_to_copy; - if (SgFile::switchToFile(fileName) == -1) + if (SgFile::switchToFile(decl_file_name) == -1) { auto* func_stmt = curr_stmt->getScopeForDeclare(); @@ -472,7 +606,9 @@ void replaceDistributedArraysInIO(vector& regions, insertPlace->insertStmtAfter(*stat, *st); } else - copied = copyArray(place, array_p, linesByFile.second, suffix + to_string(region->GetId()), fileName, newDeclsToInclude, copied_syms); + { + copied = copyArray(place, array_p, linesByFile.second, suffix + to_string(region->GetId()), decl_file_name, newDeclsToInclude, copied_syms); + } SgStatement* decl = SgStatement::getStatementByFileAndLine(place.first, place.second); @@ -492,10 +628,125 @@ void replaceDistributedArraysInIO(vector& regions, dir_str += "!$SPF ANALYSIS(PROCESS_PRIVATE(" + string(copied.second->identifier()) + "))\n"; decl->addComment(dir_str.c_str()); } + created_copies.insert({ array_to_copy, copied.second }); - if (curr_stmt->switchToFile() == -1) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + // make array-copy allocatable in case of main array shape not constant + if(checkDynamicArray(array_p)) + { + // insert allocatable keyword in declaration + auto *kword_list = decl->expr(2); + if (!findAlloatableKeyword(kword_list)) + { + if (!kword_list) + { + kword_list = new SgExprListExp(); + decl->setExpression(2, *kword_list); + } + + while (kword_list->rhs()) + kword_list = kword_list->rhs(); + + if (kword_list->lhs()) + { + kword_list->setRhs(new SgExprListExp()); + kword_list = kword_list->rhs(); + } + + kword_list->setLhs(new SgExpression(ALLOCATABLE_OP)); + } + + // insert allocate(a_l(lbound(a, 1):ubound(a,1),...)) statement + SgFile::switchToFile(filename); + SgStatement* insertPlace = NULL; + + auto* func_stmt = curr_stmt->getScopeForDeclare(); + for (auto iterator = func_stmt->lexNext(); + !isSgExecutableStatement(iterator) || isSPF_stat(iterator) && + !(iterator->variant() == SPF_PARALLEL_REG_DIR || iterator->variant() == SPF_END_PARALLEL_REG_DIR); + iterator = iterator->lexNext()) + { + insertPlace = iterator; + } + + //NULL - no decl stats in function! + if (!insertPlace) + insertPlace = func_stmt; + + auto st = insertPlace->controlParent(); + if (st->variant() == GLOBAL) + st = insertPlace; + + auto *stat = new SgStatement(ALLOCATE_STMT); + auto *created_array_ref = new SgArrayRefExp(*copied.second); + + auto* dim_list = new SgExprListExp(); + created_array_ref->setLhs(dim_list); + + int dim_len = array_p->GetSizes().size(); + for (int i = 1; i <= dim_len; i++) + { + auto *lcall = new SgFunctionCallExp(*lbound_symb); + auto *rcall = new SgFunctionCallExp(*ubound_symb); + + for (auto *call : {lcall, rcall}) + { + call->setLhs(new SgExprListExp()); + + call->lhs()->setLhs(new SgArrayRefExp(*array_to_copy)); + call->lhs()->setRhs(new SgValueExp(i)); + } + + auto *dot_expr = new SgExpression(DDOT); + dot_expr->setLhs(lcall); + dot_expr->setRhs(rcall); + + dim_list->setLhs(dot_expr); + + if (i < dim_len) + { + auto *next = new SgExprListExp(); + dim_list->setRhs(next); + dim_list = next; + } + } + + stat->setExpression(0, created_array_ref); + + insertPlace->insertStmtAfter(*stat, *st); + + // insert deallocate statemens before all returns + auto *find_return_stmt = func_stmt; + while (find_return_stmt != func_stmt->lastNodeOfStmt()) + { + auto *next = find_return_stmt->lexNext(); + if (next && (isSgReturnStmt(next) || next == func_stmt->lastNodeOfStmt())) + { + if (next->hasLabel()) + { + __spf_print(1, "%s has label\n", next->unparse()); + moveLabelBefore(next); + find_return_stmt = next->lexPrev(); + } + + auto *dealloc_stmt = new SgStatement(DEALLOCATE_STMT); + + dealloc_stmt->setExpression(0, new SgExprListExp()); + dealloc_stmt->expr(0)->setLhs(new SgArrayRefExp(*copied.second)); + + find_return_stmt->insertStmtAfter(*dealloc_stmt, *next->controlParent()); + + if (next == curr_stmt) + curr_stmt = dealloc_stmt; + } + + find_return_stmt = next; + } + } + + SgFile::switchToFile(filename); + + } } @@ -507,7 +758,7 @@ void replaceDistributedArraysInIO(vector& regions, { auto it = created_copies.find(p.first); if (it != created_copies.end()) - replaceArrayInFragment(p.first, p.second, it->second, last_io_bound, curr_stmt, filename); + replaceArrayInFragment(p.first, p.second, it->second, last_io_bound, curr_stmt, current_func_info, filename); else printInternalError(convertFileName(__FILE__).c_str(), __LINE__); } @@ -527,7 +778,7 @@ void replaceDistributedArraysInIO(vector& regions, } } - populateDistributedIoArrays(need_replace, curr_stmt); + populateDistributedIoArrays(need_replace, curr_stmt, filename); curr_stmt = curr_stmt->lexNext(); } } -- 2.49.1 From 16b2c6b42ba70f237a85c8529a49732f6c6b6c3f Mon Sep 17 00:00:00 2001 From: xnpster Date: Sat, 13 Sep 2025 20:48:24 +0300 Subject: [PATCH 2/6] REMOVE_DIST_ARRAYS_FROM_IO: remove debug prints --- .../ReplaceArraysInIO/replace_dist_arrays_in_io.cpp | 4 ---- 1 file changed, 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 a6df223..c5f8335 100644 --- a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp +++ b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp @@ -61,7 +61,6 @@ static SgExpression* findExprWithVariant(SgExpression* exp, int variant) static bool checkAssumedSize(SgStatement *st, const string &arrayName, const string ¤tFile) { - __spf_print(1, "Try array %s\n", arrayName.c_str()); bool found = false; DIST::Array* array_p = getArrayFromDeclarated(st, arrayName); @@ -74,8 +73,6 @@ static bool checkAssumedSize(SgStatement *st, const string &arrayName, const str SgExpression* list = st->expr(0); while (list) { - __spf_print(1, "Try list %s\n", list->lhs()->unparse()); - if (list->lhs() && list->lhs()->symbol()->identifier() == arrayName) { if(findExprWithVariant(list->lhs(), STAR_RANGE)) @@ -724,7 +721,6 @@ void replaceDistributedArraysInIO(vector& regions, { if (next->hasLabel()) { - __spf_print(1, "%s has label\n", next->unparse()); moveLabelBefore(next); find_return_stmt = next->lexPrev(); } -- 2.49.1 From 3bc93516415e662dd5e7aa1b7784d63358d422b7 Mon Sep 17 00:00:00 2001 From: xnpster Date: Sat, 13 Sep 2025 20:48:24 +0300 Subject: [PATCH 3/6] REMOVE_DIST_ARRAYS_FROM_IO: do not process arrays from headers, copy from correct declarations, improve style --- .../replace_dist_arrays_in_io.cpp | 267 +++++++++--------- 1 file changed, 141 insertions(+), 126 deletions(-) diff --git a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp index c5f8335..1ed6393 100644 --- a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp +++ b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp @@ -17,20 +17,6 @@ using std::pair; #define DEBUG_TRACE 0 -static bool findAlloatableKeyword(SgExpression* exp) -{ - if (exp) - { - if (exp->variant() == ALLOCATABLE_OP) - return true; - - return findAlloatableKeyword(exp->lhs()) || findAlloatableKeyword(exp->rhs()); - } - - return false; -} - - static bool checkDynamicArray(DIST::Array *array) { for (const auto &bounds : array->GetSizes()) @@ -59,27 +45,69 @@ static SgExpression* findExprWithVariant(SgExpression* exp, int variant) return NULL; } -static bool checkAssumedSize(SgStatement *st, const string &arrayName, const string ¤tFile) +bool switchToDeclarationFile(DIST::Array* array_p, + pair& decl_place, + const string ¤t_file_name, + FuncInfo *current_func) { + if (!array_p) + return false; + + + // try to find declaration from current function + for (const auto &p : array_p->GetDeclInfo()) + { + if (p.first == current_file_name && + current_func->linesNum.first <= p.second && + p.second <= current_func->linesNum.second) + { + decl_place = p; + return true; + } + } + + for (const auto &p : array_p->GetDeclInfo()) + { + if (SgFile::switchToFile(p.first) != -1) + { + decl_place = p; + return true; + } + } + + return false; +} + +static bool checkAssumedSize(const string &array_name, DIST::Array* array_p, const string ¤t_file_name, FuncInfo *current_func) +{ + if (!array_p) + return true; // raise true to prevent array from copying + bool found = false; - DIST::Array* array_p = getArrayFromDeclarated(st, arrayName); + pair decl_place; - auto place = *array_p->GetDeclInfo().begin(); - auto decl_file_name = place.first; + if (!switchToDeclarationFile(array_p, decl_place, current_file_name, current_func)) + return true; - SgFile::switchToFile(decl_file_name); + auto *st = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second); SgExpression* list = st->expr(0); while (list) { - if (list->lhs() && list->lhs()->symbol()->identifier() == arrayName) + if (list->lhs() && + list->lhs()->symbol() && + list->lhs()->symbol()->identifier() && + list->lhs()->symbol()->identifier() == array_name + ) { if(findExprWithVariant(list->lhs(), STAR_RANGE)) found = true; break; } + + list = list->rhs(); } if (!found) @@ -89,7 +117,8 @@ static bool checkAssumedSize(SgStatement *st, const string &arrayName, const str found = true; } - SgFile::switchToFile(currentFile); + if (SgFile::switchToFile(current_file_name) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); // can't switch back to file with array usage return found; } @@ -106,7 +135,10 @@ static void findArrays(SgExpression* exp, set& arrays) } } -static void populateDistributedIoArrays(map>& arrays, SgStatement* stat, const string& current_file) +static void populateDistributedIoArrays(map>& arrays, + SgStatement* stat, + const string& current_file_name, + FuncInfo *current_func) { auto var = stat->variant(); @@ -209,11 +241,13 @@ static void populateDistributedIoArrays(map>& array DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(by_symb), array_name); if (array_p && array_p->GetDistributeFlagVal() == Distribution::distFlag::IO_PRIV && - !checkAssumedSize(declaratedInStmt(by_symb), array_name, current_file) && - arrays[by_symb].insert(stat).second + !checkAssumedSize(array_name, array_p, current_file_name, current_func) ) { - __spf_print(DEBUG_TRACE, "[%d]: add array %s\n", stat->lineNumber(), array_p->GetName().c_str()); + auto inserted = arrays[by_symb].insert(stat).second; + + if (inserted) + __spf_print(DEBUG_TRACE, "[%d]: add array %s %p\n", stat->lineNumber(), array_p->GetName().c_str(), by_symb); } } @@ -342,8 +376,7 @@ static void replaceArrayInFragment(SgSymbol* replace_symb, SgSymbol* replace_by, SgStatement* start, SgStatement* last, - FuncInfo *func_info, - const string& filename) + FuncInfo *func_info) { while (start->lexNext() && (!isSgExecutableStatement(start->lexNext()) || start->lexNext()->variant() == ALLOCATE_STMT)) start = start->lexNext(); @@ -453,9 +486,9 @@ static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound) } void replaceDistributedArraysInIO(vector& regions, - const map>& allFuncInfo, - map>& SPF_messages, - map>>& newDeclsToInclude) + const map>& allFuncInfo, + map>& SPF_messages, + map>>& newDeclsToInclude) { map created_copies; map>> copied_syms; @@ -464,14 +497,14 @@ void replaceDistributedArraysInIO(vector& regions, { __spf_print(DEBUG_TRACE, "[%s]: enter region\n", region->GetName().c_str()); - for (auto& linesByFile : region->GetAllLinesToModify()) + for (auto& lines_by_file : region->GetAllLinesToModify()) { - const auto& filename = linesByFile.first; + const auto& current_file_name = lines_by_file.first; - if (SgFile::switchToFile(filename) == -1) + if (SgFile::switchToFile(current_file_name) == -1) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - auto func_info_it = allFuncInfo.find(filename); + auto func_info_it = allFuncInfo.find(current_file_name); if (func_info_it == allFuncInfo.end()) { printInternalError(convertFileName(__FILE__).c_str(), __LINE__); @@ -481,9 +514,9 @@ void replaceDistributedArraysInIO(vector& regions, auto *lbound_symb = new SgSymbol(PROCEDURE_NAME, "lbound"); auto *ubound_symb = new SgSymbol(PROCEDURE_NAME, "ubound"); - for (auto& lines : linesByFile.second) + for (auto& lines : lines_by_file.second) { - __spf_print(DEBUG_TRACE, "[fragment] %s: %d:%d %d\n", filename.c_str(), lines.lines.first, + __spf_print(DEBUG_TRACE, "[fragment] %s: %d:%d %d\n", current_file_name.c_str(), lines.lines.first, lines.lines.second, lines.isImplicit()); SgStatement* curr_stmt, * end; @@ -555,90 +588,70 @@ void replaceDistributedArraysInIO(vector& regions, string array_name = string(array_to_copy->identifier()); DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(array_to_copy), array_name); - bool fromModule = (array_p->GetLocation().first == DIST::l_MODULE); - const string locationName = array_p->GetLocation().second; + // at this point all considered arrays must have DIST::Array* references + if (!array_p) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + // ... and be declared in switchable files (not in headers) + pair decl_place; + if (!switchToDeclarationFile(array_p, decl_place, current_file_name, current_func_info)) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - auto place = *array_p->GetDeclInfo().begin(); - auto decl_file_name = place.first; string suffix = "_io_l"; - if (fromModule) - suffix = "_io_m"; - - pair copied; - copied.first = array_to_copy; - - if (SgFile::switchToFile(decl_file_name) == -1) + switch (array_p->GetLocation().first) { - auto* func_stmt = curr_stmt->getScopeForDeclare(); - - SgStatement* insertPlace = NULL; - for (auto iterator = func_stmt->lexNext(); - !isSgExecutableStatement(iterator) || isSPF_stat(iterator) && - !(iterator->variant() == SPF_PARALLEL_REG_DIR || iterator->variant() == SPF_END_PARALLEL_REG_DIR); - iterator = iterator->lexNext()) - { - insertPlace = iterator; - } - - //NULL - no decl stats in function! - if (!insertPlace) - insertPlace = func_stmt; - - auto st = insertPlace->controlParent(); - if (st->variant() == GLOBAL) - st = insertPlace; - - auto& copied_symb = array_to_copy->copy(); - copied.second = &copied_symb; - - auto new_name = string(array_to_copy->identifier()) + "_io_c"; - copied_symb.changeName(new_name.c_str()); - - auto stat = array_to_copy->makeVarDeclStmt(); - auto res = CalculateInteger(stat->expr(0)->copyPtr()); - res->lhs()->setSymbol(copied_symb); - stat->setExpression(0, res); - - insertPlace->insertStmtAfter(*stat, *st); - } - else - { - copied = copyArray(place, array_p, linesByFile.second, suffix + to_string(region->GetId()), decl_file_name, newDeclsToInclude, copied_syms); - } - - SgStatement* decl = SgStatement::getStatementByFileAndLine(place.first, place.second); - - if (decl) - decl = decl->lexNext(); - - if (decl) - { - string dir_str; - if (decl->comments()) - { - string str_comment = string(decl->comments()); - if (str_comment.size() && str_comment.back() != '\n') - dir_str += "\n"; - } - - dir_str += "!$SPF ANALYSIS(PROCESS_PRIVATE(" + string(copied.second->identifier()) + "))\n"; - decl->addComment(dir_str.c_str()); + case DIST::l_MODULE: + suffix = "_io_m"; + break; + case DIST::l_COMMON: + suffix = "_io_c"; + break; } - created_copies.insert({ array_to_copy, copied.second }); + auto copied_symbol = copyArray(decl_place, + array_p, + lines_by_file.second, + suffix + to_string(region->GetId()), + decl_place.first, + newDeclsToInclude, + copied_syms); + - // make array-copy allocatable in case of main array shape not constant + auto* decl_stmt = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second); + + // created declaration statement located right after original one + if (!decl_stmt || !decl_stmt->lexNext()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + decl_stmt = decl_stmt->lexNext(); + + // insert !$SPF ANALYSIS(PROCESS_PRIVATE(array)) directive before declaration statement + + string dir_str; + if (decl_stmt->comments()) + { + auto str_comment = string(decl_stmt->comments()); + if (str_comment.size() && str_comment.back() != '\n') + dir_str += "\n"; + } + + dir_str += "!$SPF ANALYSIS(PROCESS_PRIVATE(" + string(copied_symbol.second->identifier()) + "))\n"; + decl_stmt->addComment(dir_str.c_str()); + + created_copies.insert({ array_to_copy, copied_symbol.second }); + + // make array copy allocatable in case of main array shape not constant if(checkDynamicArray(array_p)) { // insert allocatable keyword in declaration - auto *kword_list = decl->expr(2); - if (!findAlloatableKeyword(kword_list)) + auto *kword_list = decl_stmt->expr(2); + if (!findExprWithVariant(kword_list, ALLOCATABLE_OP)) { if (!kword_list) { kword_list = new SgExprListExp(); - decl->setExpression(2, *kword_list); + decl_stmt->setExpression(2, *kword_list); } while (kword_list->rhs()) @@ -653,29 +666,30 @@ void replaceDistributedArraysInIO(vector& regions, kword_list->setLhs(new SgExpression(ALLOCATABLE_OP)); } + // can't switch back to file with array usage + if (SgFile::switchToFile(current_file_name) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + // insert allocate(a_l(lbound(a, 1):ubound(a,1),...)) statement - SgFile::switchToFile(filename); - SgStatement* insertPlace = NULL; + SgStatement* allocate_stmt_place = NULL; auto* func_stmt = curr_stmt->getScopeForDeclare(); for (auto iterator = func_stmt->lexNext(); - !isSgExecutableStatement(iterator) || isSPF_stat(iterator) && - !(iterator->variant() == SPF_PARALLEL_REG_DIR || iterator->variant() == SPF_END_PARALLEL_REG_DIR); + iterator && !isSgExecutableStatement(iterator); iterator = iterator->lexNext()) { - insertPlace = iterator; + allocate_stmt_place = iterator; } //NULL - no decl stats in function! - if (!insertPlace) - insertPlace = func_stmt; + if (!allocate_stmt_place) + allocate_stmt_place = func_stmt; - auto st = insertPlace->controlParent(); - if (st->variant() == GLOBAL) - st = insertPlace; + auto *allocate_stmt_parent = allocate_stmt_place->controlParent(); + if (allocate_stmt_parent->variant() == GLOBAL) + allocate_stmt_parent = allocate_stmt_place; - auto *stat = new SgStatement(ALLOCATE_STMT); - auto *created_array_ref = new SgArrayRefExp(*copied.second); + auto *created_array_ref = new SgArrayRefExp(*copied_symbol.second); auto* dim_list = new SgExprListExp(); created_array_ref->setLhs(dim_list); @@ -708,9 +722,10 @@ void replaceDistributedArraysInIO(vector& regions, } } - stat->setExpression(0, created_array_ref); + auto *allocate_stmt = new SgStatement(ALLOCATE_STMT); + allocate_stmt->setExpression(0, created_array_ref); - insertPlace->insertStmtAfter(*stat, *st); + allocate_stmt_place->insertStmtAfter(*allocate_stmt, *allocate_stmt_parent); // insert deallocate statemens before all returns auto *find_return_stmt = func_stmt; @@ -728,7 +743,7 @@ void replaceDistributedArraysInIO(vector& regions, auto *dealloc_stmt = new SgStatement(DEALLOCATE_STMT); dealloc_stmt->setExpression(0, new SgExprListExp()); - dealloc_stmt->expr(0)->setLhs(new SgArrayRefExp(*copied.second)); + dealloc_stmt->expr(0)->setLhs(new SgArrayRefExp(*copied_symbol.second)); find_return_stmt->insertStmtAfter(*dealloc_stmt, *next->controlParent()); @@ -740,9 +755,9 @@ void replaceDistributedArraysInIO(vector& regions, } } - SgFile::switchToFile(filename); - - + // can't switch back to file with array usage + if (SgFile::switchToFile(current_file_name) == -1) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); } } @@ -754,7 +769,7 @@ void replaceDistributedArraysInIO(vector& regions, { auto it = created_copies.find(p.first); if (it != created_copies.end()) - replaceArrayInFragment(p.first, p.second, it->second, last_io_bound, curr_stmt, current_func_info, filename); + replaceArrayInFragment(p.first, p.second, it->second, last_io_bound, curr_stmt, current_func_info); else printInternalError(convertFileName(__FILE__).c_str(), __LINE__); } @@ -774,7 +789,7 @@ void replaceDistributedArraysInIO(vector& regions, } } - populateDistributedIoArrays(need_replace, curr_stmt, filename); + populateDistributedIoArrays(need_replace, curr_stmt, current_file_name, current_func_info); curr_stmt = curr_stmt->lexNext(); } } -- 2.49.1 From 280beb13cc303c770c75d048a41c2987d63aa76e Mon Sep 17 00:00:00 2001 From: xnpster Date: Sat, 13 Sep 2025 20:48:24 +0300 Subject: [PATCH 4/6] REMOVE_DIST_ARRAYS_FROM_IO: regard generated intent statements, carefully detect assumed-shape arrays --- .../replace_dist_arrays_in_io.cpp | 93 ++++++++++++++++--- 1 file changed, 78 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 1ed6393..827e0db 100644 --- a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp +++ b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp @@ -17,13 +17,17 @@ using std::pair; #define DEBUG_TRACE 0 -static bool checkDynamicArray(DIST::Array *array) +static SgStatement* getDeclStatement(int line_num) { - for (const auto &bounds : array->GetSizes()) - if (bounds.first == -1 || bounds.second == -1) - return true; + PTR_BFND node = current_file->firstStatement()->thebif; + for (; node; node = node->thread) + { + SgStatement *st = BfndMapping(node); + if (st->lineNumber() == line_num && isSgDeclarationStatement(st)) + return st; + } - return false; + return NULL; } static SgExpression* findExprWithVariant(SgExpression* exp, int variant) @@ -53,7 +57,6 @@ bool switchToDeclarationFile(DIST::Array* array_p, if (!array_p) return false; - // try to find declaration from current function for (const auto &p : array_p->GetDeclInfo()) { @@ -78,6 +81,47 @@ bool switchToDeclarationFile(DIST::Array* array_p, return false; } +static bool checkAssumedShape(SgStatement* decl, const string& array_name) +{ + SgExpression* list = decl->expr(0); + SgExpression* dim_list = NULL; + + while (list) + { + auto *arr_ref = list->lhs(); + + if (arr_ref && + arr_ref->symbol() && + arr_ref->symbol()->identifier() && + arr_ref->symbol()->identifier() == array_name) + { + dim_list = arr_ref->lhs(); + break; + } + + list = list->rhs(); + } + + if (!dim_list) + { + auto *dim_expr = findExprWithVariant(decl->expr(2), DIMENSION_OP); + if (dim_expr) + dim_list = dim_expr->lhs(); + } + + while (dim_list) + { + auto *lhs = dim_list->lhs(); + + if (lhs && lhs->variant() == DDOT && (!lhs->lhs() || !lhs->rhs())) + return true; + + dim_list = dim_list->rhs(); + } + + return false; +} + static bool checkAssumedSize(const string &array_name, DIST::Array* array_p, const string ¤t_file_name, FuncInfo *current_func) { if (!array_p) @@ -90,9 +134,12 @@ static bool checkAssumedSize(const string &array_name, DIST::Array* array_p, con if (!switchToDeclarationFile(array_p, decl_place, current_file_name, current_func)) return true; - auto *st = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second); + auto *st = getDeclStatement(decl_place.second); - SgExpression* list = st->expr(0); + if (!st) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + SgExpression* list = st->expr(0); while (list) { if (list->lhs() && @@ -618,14 +665,30 @@ void replaceDistributedArraysInIO(vector& regions, copied_syms); - auto* decl_stmt = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second); - - // created declaration statement located right after original one - if (!decl_stmt || !decl_stmt->lexNext()) + // original declaration statement + auto* decl_stmt = getDeclStatement(decl_place.second); + if (!decl_stmt || !isSgDeclarationStatement(decl_stmt)) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - decl_stmt = decl_stmt->lexNext(); + auto dynamic_array = checkAssumedShape(decl_stmt, array_name); + + while (decl_stmt && !isSgExecutableStatement(decl_stmt)) + { + if (isSgDeclarationStatement(decl_stmt) && + decl_stmt->expr(0) && + decl_stmt->expr(0)->lhs() && + decl_stmt->expr(0)->lhs()->symbol() == copied_symbol.second) + { + break; + } + + decl_stmt = decl_stmt->lexNext(); + } + // created declaration statement + if (!decl_stmt || !isSgDeclarationStatement(decl_stmt)) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + // insert !$SPF ANALYSIS(PROCESS_PRIVATE(array)) directive before declaration statement string dir_str; @@ -641,8 +704,8 @@ void replaceDistributedArraysInIO(vector& regions, created_copies.insert({ array_to_copy, copied_symbol.second }); - // make array copy allocatable in case of main array shape not constant - if(checkDynamicArray(array_p)) + // make array copy allocatable in case of assumed-shape array + if(dynamic_array) { // insert allocatable keyword in declaration auto *kword_list = decl_stmt->expr(2); -- 2.49.1 From 49d3b9b96ebd063e1b31455441d3a43ad1a87402 Mon Sep 17 00:00:00 2001 From: xnpster Date: Mon, 15 Sep 2025 21:25:57 +0300 Subject: [PATCH 5/6] REMOVE_DIST_ARRAYS_FROM_IO: revert hotfix for issue with generated intent statements --- .../replace_dist_arrays_in_io.cpp | 18 +++--------------- 1 file changed, 3 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 827e0db..aeda7d3 100644 --- a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp +++ b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp @@ -17,19 +17,6 @@ using std::pair; #define DEBUG_TRACE 0 -static SgStatement* getDeclStatement(int line_num) -{ - PTR_BFND node = current_file->firstStatement()->thebif; - for (; node; node = node->thread) - { - SgStatement *st = BfndMapping(node); - if (st->lineNumber() == line_num && isSgDeclarationStatement(st)) - return st; - } - - return NULL; -} - static SgExpression* findExprWithVariant(SgExpression* exp, int variant) { if (exp) @@ -134,7 +121,7 @@ static bool checkAssumedSize(const string &array_name, DIST::Array* array_p, con if (!switchToDeclarationFile(array_p, decl_place, current_file_name, current_func)) return true; - auto *st = getDeclStatement(decl_place.second); + auto *st = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second); if (!st) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); @@ -666,7 +653,8 @@ void replaceDistributedArraysInIO(vector& regions, // original declaration statement - auto* decl_stmt = getDeclStatement(decl_place.second); + auto *decl_stmt = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second); + if (!decl_stmt || !isSgDeclarationStatement(decl_stmt)) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); -- 2.49.1 From c6f290bb560e7139bf0ed6661e236187c66cfb40 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Tue, 16 Sep 2025 08:22:53 +0300 Subject: [PATCH 6/6] trivial, version updated --- .../replace_dist_arrays_in_io.cpp | 27 +++++++------------ src/Utils/version.h | 2 +- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp index aeda7d3..02c7035 100644 --- a/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp +++ b/src/Transformations/ReplaceArraysInIO/replace_dist_arrays_in_io.cpp @@ -36,10 +36,10 @@ static SgExpression* findExprWithVariant(SgExpression* exp, int variant) return NULL; } -bool switchToDeclarationFile(DIST::Array* array_p, - pair& decl_place, - const string ¤t_file_name, - FuncInfo *current_func) +static bool switchToDeclarationFile(DIST::Array* array_p, + pair& decl_place, + const string ¤t_file_name, + FuncInfo *current_func) { if (!array_p) return false; @@ -122,9 +122,7 @@ static bool checkAssumedSize(const string &array_name, DIST::Array* array_p, con return true; auto *st = SgStatement::getStatementByFileAndLine(decl_place.first, decl_place.second); - - if (!st) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + checkNull(st, convertFileName(__FILE__).c_str(), __LINE__); SgExpression* list = st->expr(0); while (list) @@ -255,6 +253,7 @@ static void populateDistributedIoArrays(map>& array spec = spec->rhs(); } } + break; } default: break; @@ -275,8 +274,7 @@ static void populateDistributedIoArrays(map>& array DIST::Array* array_p = getArrayFromDeclarated(declaratedInStmt(by_symb), array_name); if (array_p && array_p->GetDistributeFlagVal() == Distribution::distFlag::IO_PRIV && - !checkAssumedSize(array_name, array_p, current_file_name, current_func) - ) + !checkAssumedSize(array_name, array_p, current_file_name, current_func)) { auto inserted = arrays[by_symb].insert(stat).second; @@ -379,6 +377,7 @@ static void copyArrayBetweenStatements(SgSymbol* replace_symb, auto* parent = start_is_scope ? start : start->controlParent(); if (parent && parent->lastNodeOfStmt() == start) parent = parent->controlParent(); + checkNull(parent, convertFileName(__FILE__).c_str(), __LINE__); start->insertStmtAfter(*assign, *parent); } @@ -540,13 +539,10 @@ void replaceDistributedArraysInIO(vector& regions, auto func_info_it = allFuncInfo.find(current_file_name); if (func_info_it == allFuncInfo.end()) - { printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - return; - } - auto *lbound_symb = new SgSymbol(PROCEDURE_NAME, "lbound"); - auto *ubound_symb = new SgSymbol(PROCEDURE_NAME, "ubound"); + auto *lbound_symb = new SgSymbol(FUNCTION_NAME, "lbound"); + auto *ubound_symb = new SgSymbol(FUNCTION_NAME, "ubound"); for (auto& lines : lines_by_file.second) { @@ -594,10 +590,7 @@ void replaceDistributedArraysInIO(vector& regions, } if (!current_func_info) - { printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - return; - } curr_stmt = curr_stmt->lexNext(); while (curr_stmt && !isSgExecutableStatement(curr_stmt)) diff --git a/src/Utils/version.h b/src/Utils/version.h index 97027fe..e2700aa 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2443" +#define VERSION_SPF "2444" -- 2.49.1