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/projects/dvm b/projects/dvm index 7aefb0d..4d4041a 160000 --- a/projects/dvm +++ b/projects/dvm @@ -1 +1 @@ -Subproject commit 7aefb0d897fa63a495b772afc83e957aa510dfa0 +Subproject commit 4d4041a0811397add7e5e742681b5786e6c8a021 diff --git a/projects/libpredictor b/projects/libpredictor index 7e57477..d08cb25 160000 --- a/projects/libpredictor +++ b/projects/libpredictor @@ -1 +1 @@ -Subproject commit 7e57477dfa403a6517b0aca790d15f2772d25576 +Subproject commit d08cb25cc6b0fd13a452ee634abc1e65e0901c3d diff --git a/src/ArrayConstantPropagation/propagation.cpp b/src/ArrayConstantPropagation/propagation.cpp deleted file mode 100644 index 034c6b4..0000000 --- a/src/ArrayConstantPropagation/propagation.cpp +++ /dev/null @@ -1,380 +0,0 @@ -#include "propagation.h" - -#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 positionsToAdd; -unordered_set statementsToRemove; -unordered_map>> expToChange; - -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++; - - 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* funcEnd = funcStart->lastNodeOfStmt(); - SgStatement* commonStat = NULL; - SgExpression* commonList = NULL; - - for (SgStatement* cur = funcStart->lexNext(); - cur && cur != funcEnd; cur = cur->lexNext()) - { - if (cur->variant() != COMM_STAT) - continue; - - for (SgExpression* exp = cur->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) - { - commonStat = cur; - commonList = exp; - break; - } - } - if (commonStat) - break; - } - - vector varRefs; - for (SgSymbol* sym : symbols) - { - 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); - - SgStatement* insertAfter = FindLastDeclStatement(funcStart); - 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; - 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())) - { - expUnparsed = exp->unparse(); - if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) - { - arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); - } - 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++) - { - 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()); - - 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); - - } -} - -static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) -{ - 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()) - { - 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->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) -{ - SgStatement* firstStatement = declPlace->lexPrev(); - st = st->lexPrev(); - string array = exp->unparse(); - 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()) - { - 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); - 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(); - } -} - -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; - SgFile::switchToFile(file->filename()); - 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()) - { - if (st->variant() == FOR_NODE) - { - 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) - { - 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 deleted file mode 100644 index 65fe4ed..0000000 --- a/src/ArrayConstantPropagation/propagation.h +++ /dev/null @@ -1,20 +0,0 @@ -#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 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 new file mode 100644 index 0000000..058e5b2 --- /dev/null +++ b/src/Transformations/ArrayConstantPropagation/propagation.cpp @@ -0,0 +1,631 @@ +#include "propagation.h" + +#include "../Utils/SgUtils.h" + +#include +#include +#include +#include +#include + +using namespace std; + +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 false; + } + SgExpression* lhs = exp->lhs(); + SgExpression* rhs = exp->rhs(); + do + { + if (lhs && 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++; + + SgStatement* funcStart = declPlace->controlParent(); + SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), SgTypeInt(), funcStart); + + 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; + 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 map& symbols) +{ + if (symbols.empty()) + return; + + 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()) + { + if (cur->variant() != COMM_STAT) + continue; + + for (SgExpression* exp = cur->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) + { + commonStat = cur; + commonList = exp; + break; + } + } + if (commonStat) + break; + } + + vector varRefs; + for (const auto& [name, sym] : symbols) + { + if (!sym || sym->variant() != VARIABLE_NAME || string(sym->identifier()) == commonBlockName) + continue; + 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 (const auto& [name, sym] : symbols) + { + if (!sym) + continue; + 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; + 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 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 false; + bool isChanged = false; + vector subnodes = { exp->lhs(), exp->rhs() }; + + string expUnparsed; + SgExpression* toAdd = NULL; + 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()); + arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); + } + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + auto* sym = new SgSymbol(VARIABLE_NAME, arrayToName[expUnparsed].c_str(), SgTypeInt(), declPlace->controlParent()); + auto* newVarExp = new SgVarRefExp(sym); + copyStatement(st); + st->setExpression(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())) + { + isChanged = true; + expUnparsed = subnodes[i]->unparse(); + if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) + { + arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType()); + arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); + } + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + SgSymbol* builder = arrayToVariable[expUnparsed]->symbol(); + auto* sym = new SgSymbol(VARIABLE_NAME, arrayToName[expUnparsed].c_str(), SgTypeInt(), declPlace->controlParent()); + toAdd = new SgVarRefExp(sym); + if (toAdd) + { + copyStatement(st); + if (i == 0) + exp->setLhs(toAdd); + else + exp->setRhs(toAdd); + } + } + else + isChanged = isChanged || TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber); + + } + return isChanged; +} + +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()) + return; + string expUnparsed = exp->unparse(); + if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) + { + arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); + arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); + } + 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()); + + st->insertStmtBefore(*newStatement, *st->controlParent()); + + newStatement->setlineNumber(getNextNegativeLineNumber()); + newStatement->setLocalLineNumber(st->lineNumber()); + + changed.insert(st); + statementsToRemove.insert(newStatement); +} + +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(); + while (st &&st != firstStatement) + { + if (st->variant() == ASSIGN_STAT) + { + if (st->expr(1)) + { + TransformRightPart(st, st->expr(1), 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, variableNumber); + } + st = st->lexPrev(); + } +} + +static void CheckVariable(SgStatement* st, SgExpression* exp, map& arrayToVariable, int& variableNumber) +{ + SgStatement* firstStatement = declPlace->lexPrev(); + st = st->lexPrev(); + while (st != firstStatement) + { + if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol()) + { + 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)) + { + if(TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber)) + { + 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()) + { + TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); + positionsToAdd[string(declPlace->fileName())].insert(declPlace); + } + } + st = st->lexPrev(); + } +} + +static void findConstValues( + SgProject& project, + const map>& borderVars, + const map& arrayToVariable, + map& hitCount, + map>>>& result) +{ + 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++) + { + 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); + if (!st) + continue; + declPlace = st; + SgStatement* lastNode = st->lastNodeOfStmt(); + + for (; st != lastNode; st = st->lexNext()) + { + 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(); + + + 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); + + } + } + } + } + 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() +{ + cout << "ARRAY_PROPAGATION_RESTORE" << endl; + 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()); + st->deleteStmt(); + } +} diff --git a/src/Transformations/ArrayConstantPropagation/propagation.h b/src/Transformations/ArrayConstantPropagation/propagation.h new file mode 100644 index 0000000..190bd03 --- /dev/null +++ b/src/Transformations/ArrayConstantPropagation/propagation.h @@ -0,0 +1,11 @@ +#pragma once +#include "../Utils/SgUtils.h" + +#include +#include + +using namespace std; + + +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);