diff --git a/src/ArrayConstantPropagation/propagation.cpp b/src/ArrayConstantPropagation/propagation.cpp index bf56a3f..a9400fc 100644 --- a/src/ArrayConstantPropagation/propagation.cpp +++ b/src/ArrayConstantPropagation/propagation.cpp @@ -3,13 +3,35 @@ #include "../Utils/SgUtils.h" #include +#include #include #include #include using namespace std; -static SgStatement* declPlace = NULL; +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) { @@ -40,158 +62,148 @@ static SgExpression* CreateVar(int& variableNumber, SgType* type) string name = varName + std::to_string(variableNumber) + "__"; variableNumber++; - SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *declPlace->controlParent()); + SgStatement* funcStart = declPlace->controlParent(); + SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *funcStart); + + variablesToAdd.insert(varSymbol); + positionsToAdd.insert(declPlace); + + return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr()); +} + +static SgStatement* FindLastDeclStatement(SgStatement* funcStart) +{ + SgStatement* endSt = funcStart->lastNodeOfStmt(); + SgStatement* cur = funcStart->lexNext(); + SgStatement* lastDecl = funcStart; + const set declVariants = { VAR_DECL, VAR_DECL_90, ALLOCATABLE_STMT, DIM_STAT, + EXTERN_STAT, COMM_STAT, HPF_TEMPLATE_STAT, DVM_VAR_DECL, STRUCT_DECL }; + + while (cur && cur != endSt) + { + if (cur->variant() == INTERFACE_STMT) + cur = cur->lastNodeOfStmt(); + + if (declVariants.find(cur->variant()) != declVariants.end()) + lastDecl = cur; + else if (isSgExecutableStatement(cur)) + break; + + cur = cur->lexNext(); + } + + return lastDecl; +} + +static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unordered_set& symbols) +{ + if (symbols.empty()) + return; const string commonBlockName = "__propagation_common__"; - SgStatement* funcStart = declPlace->controlParent(); + SgStatement* funcEnd = funcStart->lastNodeOfStmt(); SgStatement* commonStat = NULL; SgExpression* commonList = NULL; - SgStatement* funcEnd = funcStart->lastNodeOfStmt(); - SgStatement* current = funcStart->lexNext(); - - while (current != funcEnd && current) + for (SgStatement* cur = funcStart->lexNext(); + cur && cur != funcEnd; cur = cur->lexNext()) { - if (current->variant() == COMM_STAT) + if (cur->variant() != COMM_STAT) + continue; + + for (SgExpression* exp = cur->expr(0); exp; exp = exp->rhs()) { - for (SgExpression* exp = current->expr(0); exp; exp = exp->rhs()) + if (exp->variant() != COMM_LIST) + continue; + + const char* id = exp->symbol() ? exp->symbol()->identifier() : NULL; + string existingName = id ? string(id) : string("spf_unnamed"); + if (existingName == commonBlockName) { - if (exp->variant() == COMM_LIST) - { - string existingName = exp->symbol() ? - string(exp->symbol()->identifier()) : - string("spf_unnamed"); - if (existingName == commonBlockName) - { - commonStat = current; - commonList = exp; - break; - } - } - } - if (commonStat) + commonStat = cur; + commonList = exp; break; + } } - current = current->lexNext(); + if (commonStat) + break; } vector varRefs; - if (commonList) + for (SgSymbol* sym : symbols) { - SgExpression* varList = commonList->lhs(); - if (varList) - { - auto extractSymbol = [](SgExpression* exp) -> SgSymbol* { - if (!exp) - return NULL; - if (exp->symbol()) - return exp->symbol(); - if (exp->lhs() && exp->lhs()->symbol()) - return exp->lhs()->symbol(); - return NULL; - }; - if (varList->variant() == EXPR_LIST) - { - for (SgExpression* exp = varList; exp; exp = exp->rhs()) - { - SgExpression* varExp = exp->lhs(); - SgSymbol* sym = extractSymbol(varExp); - if (sym) - { - varRefs.push_back(new SgVarRefExp(sym)); - } - } - } - else - { - for (SgExpression* varExp = varList; varExp; varExp = varExp->rhs()) - { - SgSymbol* sym = extractSymbol(varExp); - if (sym) - { - varRefs.push_back(new SgVarRefExp(sym)); - } - } - } - } + 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) { - current = funcStart->lexNext(); - while (current != funcEnd && current) - { - if (current->variant() == COMM_STAT) - { - commonStat = current; - break; - } - current = current->lexNext(); - } - SgSymbol* commonSymbol = new SgSymbol(COMMON_NAME, commonBlockName.c_str()); - commonList = new SgExpression(COMM_LIST, NULL, NULL, commonSymbol); + commonList = new SgExpression(COMM_LIST, varList, NULL, commonSymbol); - if (commonStat) - { - SgExpression* lastCommList = commonStat->expr(0); - if (lastCommList) - { - while (lastCommList->rhs()) - lastCommList = lastCommList->rhs(); - lastCommList->setRhs(commonList); - } - else - { - commonStat->setExpression(0, commonList); - } - } - else - { - commonStat = new SgStatement(COMM_STAT); - commonStat->setFileName(declPlace->fileName()); - commonStat->setFileId(declPlace->getFileId()); - commonStat->setProject(declPlace->getProject()); - commonStat->setlineNumber(getNextNegativeLineNumber()); - commonStat->setExpression(0, commonList); - - declPlace->insertStmtBefore(*commonStat, *declPlace->controlParent()); - } + commonStat = new SgStatement(COMM_STAT); + commonStat->setFileName(funcStart->fileName()); + commonStat->setFileId(funcStart->getFileId()); + commonStat->setProject(funcStart->getProject()); + commonStat->setlineNumber(getNextNegativeLineNumber()); + commonStat->setExpression(0, commonList); + SgStatement* lastDecl = FindLastDeclStatement(funcStart); + lastDecl->insertStmtAfter(*commonStat, *funcStart); + statementsToRemove.insert(commonStat); } - varRefs.push_back(new SgVarRefExp(varSymbol)); - - if (varRefs.size() > 0) + else { - std::reverse(varRefs.begin(), varRefs.end()); - SgExpression* varList = makeExprList(varRefs, false); - commonList->setLhs(varList); } - return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr()); } static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map& arrayToVariable, int& variableNumber) { if (!exp) - { return; - } - vector subnodes = { exp->lhs(), exp->rhs() }; string expUnparsed; SgExpression* toAdd = NULL; if (exp->variant() == ARRAY_REF && CheckConstIndexes(exp->lhs())) { - cout << st->unparse() << endl; + expUnparsed = exp->unparse(); if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) { arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); } - st->setExpression(1, arrayToVariable[expUnparsed]->copyPtr()); + positionsToAdd.insert(declPlace); + SgSymbol* builder = arrayToVariable[expUnparsed]->symbol(); + auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent()); + auto* newVarExp = new SgVarRefExp(sym); + expToChange[st->fileName()].push_back({ st , st->copyPtr() }); + st->setExpression(1, newVarExp); return; } for (int i = 0; i < 2; i++) @@ -199,27 +211,30 @@ static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map if (subnodes[i] && subnodes[i]->variant() == ARRAY_REF && subnodes[i]->symbol()->type()->baseType() && CheckConstIndexes(subnodes[i]->lhs())) { expUnparsed = subnodes[i]->unparse(); - if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) - { - arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType());; - } - toAdd = arrayToVariable[expUnparsed]->copyPtr(); + if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) + arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType()); + + positionsToAdd.insert(declPlace); + SgSymbol* builder = arrayToVariable[expUnparsed]->symbol(); + auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent()); + toAdd = new SgVarRefExp(sym); if (toAdd) { if (i == 0) { + expToChange[st->fileName()].push_back({ st , st->copyPtr() });; exp->setLhs(toAdd); } else { + expToChange[st->fileName()].push_back({ st , st->copyPtr() });; exp->setRhs(toAdd); } } } else - { TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber); - } + } } @@ -227,11 +242,14 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map< { if (exp->symbol()->type()->variant() == T_STRING) return; + if (changed.find(st) != changed.end()) + return; string expUnparsed = exp->unparse(); if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) { 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()); @@ -240,6 +258,59 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map< 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) @@ -252,7 +323,7 @@ void ArrayConstantPropagation(SgProject& project) if (!file) continue; - + SgFile::switchToFile(file->filename()); const int funcNum = file->numberOfFunctions(); for (int i = 0; i < funcNum; ++i) { @@ -262,40 +333,48 @@ void ArrayConstantPropagation(SgProject& project) for (; st != lastNode; st = st->lexNext()) { - if (st->variant() == ASSIGN_STAT) - { - if (st->expr(1)) - { - TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); - } - if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs())) - { - TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); - } - } - else if (st->variant() == FOR_NODE) + if (st->variant() == FOR_NODE) { SgExpression* lowerBound = st->expr(0)->lhs(); SgExpression* upperBound = st->expr(0)->rhs(); + SgStatement* boundCopy = NULL; 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()); - } + 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())) { - if (arrayToVariable.find(lowerBoundUnparsed) == arrayToVariable.end()) - { - arrayToVariable[lowerBoundUnparsed] = CreateVar(variableNumber, lowerBound->symbol()->type()->baseType()); - } + 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 index e2e76cd..f33523c 100644 --- a/src/ArrayConstantPropagation/propagation.h +++ b/src/ArrayConstantPropagation/propagation.h @@ -1,4 +1,20 @@ #pragma once #include "../Utils/SgUtils.h" +#include +#include + +using namespace std; + +struct ExprRestoreEntry +{ + enum Kind { kStatementExpr, kExprChild }; + Kind kind; + SgStatement* stmt; + int stmtExprIndex; + SgExpression* parent; + bool childIsRhs; + SgExpression* savedCopy; +}; + void ArrayConstantPropagation(SgProject& project); \ No newline at end of file diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index 95624f5..041c2bc 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -7,16 +7,24 @@ #include #include +#include "ArrayConstantPropagation/propagation.h" +#include "CFGraph/CFGraph.h" +#include "Distribution/Array.h" +#include "graph_loops.h" #include "private_arrays_search.h" #include "range_structures.h" #include "region.h" #include "SgUtils.h" -#include "graph_loops.h" -#include "CFGraph/CFGraph.h" #include "utils.h" +#include "Utils/AstWrapper.h" using namespace std; +extern std::map, std::pair> declaredArrays; + +extern unordered_set statementsToRemove; +extern unordered_map>> expToChange; + static unordered_set collapsed; static void RemoveEmptyPoints(ArrayAccessingIndexes& container) @@ -33,10 +41,9 @@ static void RemoveEmptyPoints(ArrayAccessingIndexes& container) points.push_back(arrayPoint); } - if (points.size() < accessingSet.GetElements().size() && !points.empty()) + if (!points.empty()) resultContainer[arrayName] = points; - - if (points.empty()) + else toRemove.insert(arrayName); } @@ -281,7 +288,6 @@ static void SolveDataFlow(Region* DFG) static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector& declaredDims) { - declaredDims.clear(); if (!arrayRef || !arrayRef->symbol() || !isSgArrayType(arrayRef->symbol()->type())) return false; SgArrayType* arrayType = (SgArrayType*)arrayRef->symbol()->type(); @@ -290,43 +296,83 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector { SgExpression* sizeExpr = arrayType->sizeInDim(i); SgConstantSymb* constValSymb = isSgConstantSymb(sizeExpr->symbol()); - string strDimLength; + SgSubscriptExp* subscriptExpr = isSgSubscriptExp(sizeExpr); + uint64_t dimLength; if (sizeExpr && sizeExpr->variant() == INT_VAL) - strDimLength = sizeExpr->unparse(); + dimLength = stol(sizeExpr->unparse()); else if (constValSymb) - strDimLength = constValSymb->constantValue()->unparse(); + dimLength = stol(constValSymb->constantValue()->unparse()); + else if (subscriptExpr) + { + dimLength = stol(subscriptExpr->rhs()->unparse()) - stol(subscriptExpr->lhs()->unparse()); + } else return false; - if (strDimLength == "0") + if (dimLength == 0) return false; - declaredDims.push_back((uint64_t)stoi(strDimLength)); + declaredDims.push_back(dimLength); } return true; } +static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym) +{ + if (!arrSym) + return nullptr; + for (auto& [key, val] : declaredArrays) + { + DIST::Array* distArr = val.first; + if (!distArr) + continue; + Symbol* declSym = distArr->GetDeclSymbol(); + if (!declSym) + continue; + SgSymbol* sgDecl = declSym->GetOriginal(); + if (sgDecl && isEqSymbols(sgDecl, arrSym)) + return distArr; + } + return nullptr; +} + static bool CheckDimensionLength(const AccessingSet& array) { if (array.GetElements().empty()) return false; size_t dimCount = array.GetElements()[0].size(); SgArrayRefExp* arrayRef = array.GetElements()[0][0].array; - if (!arrayRef) + if (!arrayRef || !arrayRef->symbol()) return false; - vector declaredDims(dimCount); - if (!getArrayDeclaredDimensions(arrayRef, declaredDims)) - return false; - vector testArray(dimCount); - for (size_t i = 0; i < dimCount; i++) + + vector declaredDims; + declaredDims.reserve(dimCount); + + DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol()); + if (distArr && distArr->GetDimSize() == (int)dimCount) { - testArray[i] = { 1, 1, declaredDims[i], nullptr }; + const auto& sizes = distArr->GetSizes(); + bool valid = true; + for (size_t i = 0; i < dimCount && valid; ++i) + { + int lo = sizes[i].first; + int hi = sizes[i].second; + if (lo > hi) + valid = false; + else + declaredDims.push_back((uint64_t)(hi - lo + 1)); + } + if (valid && declaredDims.size() == dimCount) + { + vector testArray(dimCount); + for (size_t i = 0; i < dimCount; i++) + testArray[i] = { 1, 1, declaredDims[i], nullptr }; + return AccessingSet({ testArray }).Diff(array).GetElements().empty(); + } } - AccessingSet diff = AccessingSet({ testArray }).Diff(array); - return diff.GetElements().empty(); + return false; } - static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set& insertedPrivates) { SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR); @@ -334,6 +380,7 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& spfStat->setFileName(loop->loop->fileName()); SgExpression* toAdd = new SgExpression(EXPR_LIST, new SgExpression(ACC_PRIVATE_OP), NULL, NULL); set arraysToInsert; + std::cout << "First bp\n"; for (const auto& [_, accessingSet] : privates) { if (!CheckDimensionLength(accessingSet)) @@ -391,7 +438,15 @@ void FindPrivateArrays(map>& loopGraph, mapfileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func) { - Region* loopRegion = new Region(loop, blocks); + Region* loopRegion; + try + { + loopRegion = new Region(loop, blocks); + } + catch (...) + { + continue; + } if (loopRegion->getBasickBlocks().size() <= 1) { delete(loopRegion); @@ -403,9 +458,24 @@ 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/region.cpp b/src/PrivateAnalyzer/region.cpp index 7e47308..94c1815 100644 --- a/src/PrivateAnalyzer/region.cpp +++ b/src/PrivateAnalyzer/region.cpp @@ -150,6 +150,8 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces vector accessPoint(n); auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); + if (!ref) + continue; int fillCount = 0; vector> coeffsForDims; @@ -204,7 +206,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces current_dim = { start, step, iters, ref }; } - if (current_dim.start != 0 && current_dim.step != 0 && current_dim.tripCount != 0) + if (current_dim.step != 0 && current_dim.tripCount != 0) { accessPoint[n - index_vars.size()] = current_dim; fillCount++; @@ -267,13 +269,30 @@ static void DFS(Region* block, vector& result, unordered_set c result.push_back(block); } -void TopologySort(std::vector& basikBlocks, Region* header) +bool HasCycle(Region* block, const std::unordered_set& cycleBlocks, std::unordered_set& visitedBlocks) +{ + if (visitedBlocks.find(block) != visitedBlocks.end()) + return true; + visitedBlocks.insert(block); + for (Region* nextBlock : block->getNextRegions()) + { + if (cycleBlocks.find(nextBlock) != cycleBlocks.end() && HasCycle(nextBlock, cycleBlocks, visitedBlocks)) + return true; + } + return false; +} + +bool TopologySort(std::vector& basikBlocks, Region* header) { - vector result; unordered_set cycleBlocks(basikBlocks.begin(), basikBlocks.end()); + unordered_set visitedBlocks; + if (HasCycle(header, cycleBlocks, visitedBlocks)) + return false; + vector result; DFS(header, result, cycleBlocks); reverse(result.begin(), result.end()); - basikBlocks = result; + basikBlocks = move(result); + return true; } static void SetConnections(unordered_map& bbToRegion, const unordered_set& blockSet) @@ -313,7 +332,8 @@ static Region* CreateSubRegion(LoopGraph* loop, const vectoraddSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); } - TopologySort(region->getBasickBlocks(), region->getHeader()); + if (!TopologySort(region->getBasickBlocks(), region->getHeader())) + throw std::runtime_error("Unnoticed cycle"); return region; } @@ -337,6 +357,7 @@ Region::Region(LoopGraph* loop, const vector& Blocks) if (!childLoop->isFor()) continue; subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); - } - TopologySort(basickBlocks, this->header); + } + if (!TopologySort(basickBlocks, this->header)) + throw std::runtime_error("Unnoticed cycle"); } \ No newline at end of file diff --git a/src/PrivateAnalyzer/region.h b/src/PrivateAnalyzer/region.h index 3baa8a0..2b39af2 100644 --- a/src/PrivateAnalyzer/region.h +++ b/src/PrivateAnalyzer/region.h @@ -79,4 +79,6 @@ private: Region* header; }; -void TopologySort(std::vector& basikBlocks, Region* header); \ No newline at end of file +bool HasCycle(Region* block, const std::unordered_set& cycleBlocks, std::unordered_set& visitedBlocks); + +bool TopologySort(std::vector& basikBlocks, Region* header); \ No newline at end of file diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index 95b0e61..cd69c2f 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -318,7 +318,7 @@ void InitPassesDependencies(map> &passDepsIn, set list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE); - list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS); + list({ ARRAY_PROPAGATION, CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS); list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS); list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS); diff --git a/src/Utils/SgUtils.cpp b/src/Utils/SgUtils.cpp index cb009ff..5360662 100644 --- a/src/Utils/SgUtils.cpp +++ b/src/Utils/SgUtils.cpp @@ -658,7 +658,7 @@ string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const ch if (wasDeleted) { - if (str.size() || str.back() != '\n') + if (str.size() && str.back() != '\n') str += '\n'; st->setComments(str.c_str()); } diff --git a/src/Utils/version.h b/src/Utils/version.h index 207a063..3680f7f 100644 --- a/src/Utils/version.h +++ b/src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2473" +#define VERSION_SPF "2474"