From a113463b64220710b86e5f19580890b89d32f3b1 Mon Sep 17 00:00:00 2001 From: Oleg Nikitin Date: Fri, 19 Dec 2025 01:55:23 +0300 Subject: [PATCH] fixes, add pass --- CMakeLists.txt | 6 + src/ArrayConstantPropagation/propagation.cpp | 192 ++++++++++++++++++ src/ArrayConstantPropagation/propagation.h | 4 + src/PrivateAnalyzer/private_arrays_search.cpp | 32 +++ src/PrivateAnalyzer/range_structures.cpp | 19 +- src/PrivateAnalyzer/region.cpp | 31 ++- src/Sapfor.cpp | 4 + src/Sapfor.h | 4 + src/Utils/PassManager.h | 4 +- 9 files changed, 274 insertions(+), 22 deletions(-) create mode 100644 src/ArrayConstantPropagation/propagation.cpp create mode 100644 src/ArrayConstantPropagation/propagation.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b0e020..580342b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,6 +163,10 @@ set(PARALLEL_REG src/ParallelizationRegions/ParRegions.cpp src/ParallelizationRegions/resolve_par_reg_conflicts.cpp src/ParallelizationRegions/resolve_par_reg_conflicts.h) +set(ARRAY_PROP src/ArrayConstantPropagation/propagation.cpp + src/ArrayConstantPropagation/propagation.h +) + set(TR_DEAD_CODE src/Transformations/DeadCodeRemoving/dead_code.cpp src/Transformations/DeadCodeRemoving/dead_code.h) set(TR_CP src/Transformations/CheckPoints/checkpoints.cpp @@ -420,6 +424,7 @@ set(SOURCE_EXE ${TRANSFORMS} ${PARALLEL_REG} ${PRIV} + ${ARRAY_PROP} ${FDVM} ${OMEGA} ${UTILS} @@ -471,6 +476,7 @@ source_group (GraphLoop FILES ${GR_LOOP}) source_group (LoopAnalyzer FILES ${LOOP_ANALYZER}) source_group (ParallelizationRegions FILES ${PARALLEL_REG}) 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/ArrayConstantPropagation/propagation.cpp b/src/ArrayConstantPropagation/propagation.cpp new file mode 100644 index 0000000..95011b3 --- /dev/null +++ b/src/ArrayConstantPropagation/propagation.cpp @@ -0,0 +1,192 @@ +#include "propagation.h" + +#include "../Utils/SgUtils.h" + +#include +#include +#include +#include + +using namespace std; + +static SgStatement* declPlace = NULL; + +static bool CheckConstIndexes(SgExpression* exp) +{ + if (!exp) + { + return true; + } + SgExpression* lhs = exp->lhs(); + SgExpression* rhs = exp->rhs(); + do + { + if (lhs->variant() != INT_VAL) + { + return false; + } + if (rhs) + { + lhs = rhs->lhs(); + rhs = rhs->rhs(); + } + } while (rhs); + return true; +} + +static SgExpression* CreateVar(int& variableNumber, SgType* type) +{ + string varName = "__tmp_prop_var"; + string name = varName + std::to_string(variableNumber) + "__"; + variableNumber++; + + SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *declPlace->controlParent()); + + SgVarDeclStmt* decl = varSymbol->makeVarDeclStmt(); + decl->setVariant(VAR_DECL); + SgStatement* insertPoint = declPlace; + SgStatement* scope = declPlace->controlParent(); + decl->setFileName(insertPoint->fileName()); + decl->setFileId(insertPoint->getFileId()); + decl->setProject(insertPoint->getProject()); + decl->setlineNumber(getNextNegativeLineNumber()); + + insertPoint->insertStmtBefore(*decl, *scope); + + return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr()); +} + +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; + if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) + { + arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); + } + st->setExpression(1, arrayToVariable[expUnparsed]->copyPtr()); + return; + } + for (int i = 0; i < 2; i++) + { + 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 (toAdd) + { + if (i == 0) + { + exp->setLhs(toAdd); + } + else + { + exp->setRhs(toAdd); + } + } + } + else + { + TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber); + } + } +} + +static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) +{ + if (exp->symbol()->type()->variant() == T_STRING) + return; + string expUnparsed = exp->unparse(); + if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) + { + arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()); + } + SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, arrayToVariable[expUnparsed]->copyPtr(), st->expr(1)->copyPtr(), NULL); + + newStatement->setFileId(st->getFileId()); + newStatement->setProject(st->getProject()); + + newStatement->setlineNumber(getNextNegativeLineNumber()); + newStatement->setLocalLineNumber(st->lineNumber()); + st->insertStmtBefore(*newStatement, *st->controlParent()); +} + +void ArrayConstantPropagation(SgProject& project) +{ + unordered_map arrayToVariable; + int variableNumber = 0; + for (int i = 0; i < project.numberOfFiles(); i++) + { + SgFile* file = &(project.file(i)); + + if (!file) + continue; + + const int funcNum = file->numberOfFunctions(); + for (int i = 0; i < funcNum; ++i) + { + SgStatement* st = file->functions(i); + declPlace = st->lexNext(); + SgStatement* lastNode = st->lastNodeOfStmt(); + + for (; st != lastNode; st = st->lexNext()) + { + cout << st->unparse() << endl; + 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) + { + 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()); + } + st->expr(0)->setRhs(arrayToVariable[upperBoundUnparsed]->copyPtr()); + } + 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()); + } + st->expr(0)->setLhs(arrayToVariable[lowerBoundUnparsed]->copyPtr()); + } + } + } + /*st = file->functions(i); + for (; st != lastNode; st = st->lexNext()) + { + cout << st->unparse() << endl; + }*/ + } + //FILE* unp = fopen(file->filename(), "w"); + //file->unparse(unp); + } +} \ No newline at end of file diff --git a/src/ArrayConstantPropagation/propagation.h b/src/ArrayConstantPropagation/propagation.h new file mode 100644 index 0000000..e2e76cd --- /dev/null +++ b/src/ArrayConstantPropagation/propagation.h @@ -0,0 +1,4 @@ +#pragma once +#include "../Utils/SgUtils.h" + +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 b4ccd84..08cab87 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -16,6 +16,35 @@ using namespace std; +static void RemoveEmptyPoints(ArrayAccessingIndexes& container) +{ + ArrayAccessingIndexes resultContainer; + unordered_set toRemove; + for (auto& [arrayName, accessingSet] : container) + { + vector> points; + for (auto& arrayPoint : accessingSet.GetElements()) + { + if (!arrayPoint.empty()) + points.push_back(arrayPoint); + } + if (points.size() < accessingSet.GetElements().size() && !points.empty()) + resultContainer[arrayName] = points; + + if (points.empty()) + toRemove.insert(arrayName); + } + + for (const string& name : toRemove) + { + container.erase(name); + } + for (auto& [arrayName, accessingSet] : resultContainer) + { + container[arrayName] = accessingSet; + } +} + static void Collapse(Region* region) { if (region->getBasickBlocks().empty()) @@ -188,6 +217,8 @@ void FindPrivateArrays(map> &loopGraph, mapisFor()) + continue; SgStatement* search_func = loop->loop->GetOriginal(); while (search_func && (!isSgProgHedrStmt(search_func))) @@ -204,6 +235,7 @@ void FindPrivateArrays(map> &loopGraph, maparray_priv); result[loop] = loopRegion->array_priv; delete(loopRegion); } diff --git a/src/PrivateAnalyzer/range_structures.cpp b/src/PrivateAnalyzer/range_structures.cpp index 96890b6..373ffa5 100644 --- a/src/PrivateAnalyzer/range_structures.cpp +++ b/src/PrivateAnalyzer/range_structures.cpp @@ -64,18 +64,13 @@ static vector DimensionDifference(const ArrayDimension& dim1, co result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step, dim1.array}); /* add the parts between intersection steps */ - uint64_t start = (intersection->start - dim1.start) / dim1.step; - uint64_t interValue = intersection->start; - for (int64_t i = start; dim1.start + i * dim1.step <= intersection->start + intersection->step * (intersection->tripCount - 1); i++) + if (intersection->step > dim1.step) { - uint64_t centerValue = dim1.start + i * dim1.step; - if (centerValue == interValue) + uint64_t start = (intersection->start - dim1.start) / dim1.step; + uint64_t interValue = intersection->start; + for (int64_t i = start; interValue <= intersection->start + intersection->step * (intersection->tripCount - 1); i++) { - if (i - start > 1) - { - result.push_back({ dim1.start + (start + 1) * dim1.step, dim1.step, i - start - 1, dim1.array }); - start = i; - } + result.push_back({interValue + dim1.step, dim1.step, intersection->step / dim1.step, dim1.array}); interValue += intersection->step; } } @@ -216,6 +211,10 @@ void AccessingSet::Insert(const vector& element) } AccessingSet AccessingSet::Union(const AccessingSet& source) { + if (source.GetElements().empty()) + return *this; + if (allElements.empty()) + return source; AccessingSet result; for (auto& element : source.GetElements()) result.Insert(element); diff --git a/src/PrivateAnalyzer/region.cpp b/src/PrivateAnalyzer/region.cpp index 097e826..6346d0b 100644 --- a/src/PrivateAnalyzer/region.cpp +++ b/src/PrivateAnalyzer/region.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "range_structures.h" #include "region.h" @@ -108,11 +109,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces { vector index_vars; vector refPos; - string array_name; - if (operation == SAPFOR::CFG_OP::STORE) - array_name = instruction->getInstruction()->getArg1()->getValue(); - else - array_name = instruction->getInstruction()->getArg2()->getValue(); + string array_name = instruction->getInstruction()->getArg1()->getValue(); int j = i - 1; while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF) @@ -128,6 +125,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); vector> coefsForDims; + int subs = ref->numberOfSubscripts(); for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i) { const vector& coefs = getAttributes(ref->subscript(i), set{ INT_VAL }); @@ -174,13 +172,17 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces return -1; } - uint64_t start = currentLoop->startVal * currentCoefs.first + currentCoefs.second; - uint64_t step = currentCoefs.first; - current_dim = { start, step, (uint64_t)currentLoop->calculatedCountOfIters, ref }; + uint64_t start = currentLoop->startVal; + uint64_t step = currentLoop->stepVal; + uint64_t iters = currentLoop->calculatedCountOfIters; + current_dim = { start, step, iters, ref }; } - accessPoint[n - index_vars.size()] = current_dim; - fillCount++; + if (current_dim.start != 0 && current_dim.step != 0 && current_dim.tripCount != 0) + { + accessPoint[n - index_vars.size()] = current_dim; + fillCount++; + } index_vars.pop_back(); refPos.pop_back(); coefsForDims.pop_back(); @@ -230,8 +232,11 @@ static Region* CreateSubRegion(LoopGraph* loop, const vectoraddBasickBlocks(bbToRegion.at(block)); for (LoopGraph* childLoop : loop->children) + { + if (!childLoop->isFor()) + continue; region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); - + } return region; } @@ -250,5 +255,9 @@ Region::Region(LoopGraph* loop, const vector& Blocks) SetConnections(bbToRegion, blockSet); //create subRegions for (LoopGraph* childLoop : loop->children) + { + if (!childLoop->isFor()) + continue; subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); + } } diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index fd6ad3b..d37f078 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -46,6 +46,7 @@ #include "DynamicAnalysis/gCov_parser_func.h" #include "DynamicAnalysis/createParallelRegions.h" +#include "ArrayConstantPropagation/propagation.h" #include "DirectiveProcessing/directive_analyzer.h" #include "DirectiveProcessing/directive_creator.h" #include "DirectiveProcessing/insert_directive.h" @@ -1918,6 +1919,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS) FindPrivateArrays(loopGraph, fullIR, insertedPrivates); + else if (curr_regime == ARRAY_PROPAGATION) + 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.; __spf_print(1, "PROFILE: time for this pass = %f sec (total %f sec)\n", elapsed, elapsedGlobal); diff --git a/src/Sapfor.h b/src/Sapfor.h index 0add735..373d5c7 100644 --- a/src/Sapfor.h +++ b/src/Sapfor.h @@ -188,6 +188,8 @@ enum passes { TRANSFORM_ASSUMED_SIZE_PARAMETERS, + ARRAY_PROPAGATION, + TEST_PASS, EMPTY_PASS }; @@ -377,6 +379,8 @@ static void setPassValues() passNames[TRANSFORM_ASSUMED_SIZE_PARAMETERS] = "TRANSFORM_ASSUMED_SIZE_PARAMETERS"; + passNames[ARRAY_PROPAGATION] = "ARRAY_PROPAGATION"; + passNames[TEST_PASS] = "TEST_PASS"; } diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index f2715d3..50730fc 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -316,9 +316,11 @@ 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); + //Pass( CALL_GRAPH2 ) <= Pass(ARRAY_PROPAGATION); + 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, REVERSE_CREATED_NESTED_LOOPS, PREDICT_SCHEME, CALCULATE_STATS_SCHEME, REVERT_SPF_DIRS, CLEAR_SPF_DIRS, TRANSFORM_SHADOW_IF_FULL,