From 11e9fab482799ac5fe830e7b88068be217a49789 Mon Sep 17 00:00:00 2001 From: Oleg Nikitin Date: Tue, 27 May 2025 02:25:39 +0300 Subject: [PATCH] change file structure --- CMakeLists.txt | 6 +- src/CFGraph/IR.cpp | 12 +- src/PrivateAnalyzer/private_arrays_search.cpp | 725 ++---------------- src/PrivateAnalyzer/private_arrays_search.h | 111 +-- src/PrivateAnalyzer/range_structures.cpp | 317 ++++++++ src/PrivateAnalyzer/range_structures.h | 36 + src/PrivateAnalyzer/region.cpp | 268 +++++++ src/PrivateAnalyzer/region.h | 60 ++ src/Utils/PassManager.h | 2 +- 9 files changed, 744 insertions(+), 793 deletions(-) create mode 100644 src/PrivateAnalyzer/range_structures.cpp create mode 100644 src/PrivateAnalyzer/range_structures.h create mode 100644 src/PrivateAnalyzer/region.cpp create mode 100644 src/PrivateAnalyzer/region.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b0f054..145d672 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,7 +115,11 @@ set(OMEGA src/SageAnalysisTool/OmegaForSage/add-assert.cpp set(PRIV src/PrivateAnalyzer/private_analyzer.cpp src/PrivateAnalyzer/private_analyzer.h src/PrivateAnalyzer/private_arrays_search.cpp - src/PrivateAnalyzer/private_arrays_search.h) + src/PrivateAnalyzer/private_arrays_search.h + src/PrivateAnalyzer/range_structures.cpp + src/PrivateAnalyzer/range_structures.h + src/PrivateAnalyzer/region.cpp + src/PrivateAnalyzer/region.h) set(FDVM ${fdvm_sources}/acc.cpp ${fdvm_sources}/acc_across.cpp diff --git a/src/CFGraph/IR.cpp b/src/CFGraph/IR.cpp index 5c8bd0c..6ead0e4 100644 --- a/src/CFGraph/IR.cpp +++ b/src/CFGraph/IR.cpp @@ -395,7 +395,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector& if (ex) { const int var = ex->variant(); - if ((var == VAR_REF || var == CONST_REF || var == LABEL_REF) && !ex->lhs() && !ex->rhs()) // îáðàùåíèå ê ïåðåìåííîé + if ((var == VAR_REF || var == CONST_REF || var == LABEL_REF) && !ex->lhs() && !ex->rhs()) // ��������� � ���������� { if (var == CONST_REF) { @@ -450,7 +450,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector& return arg1; auto reg = isLeft ? NULL : createRegister(); - Instruction* instr = new Instruction(isLeft ? CFG_OP::STORE : CFG_OP::LOAD, arg1, createConstArg(numArgs), isLeft ? isLeft : reg); + Instruction* instr = new Instruction(isLeft ? CFG_OP::STORE : CFG_OP::LOAD, arg1, createConstArg(numArgs), isLeft ? isLeft : reg, NULL, ex); blocks.push_back(new IR_Block(instr)); return reg; } @@ -485,7 +485,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector& auto arg1 = arrayRef ? arrayRef : createArrayArg(ref, blocks, func, numArgs, commonVars); auto reg = isLeft ? NULL : createRegister(); - instr = new Instruction(isLeft ? CFG_OP::STORE : CFG_OP::LOAD, arg1, createConstArg(1), isLeft ? isLeft : reg); + instr = new Instruction(isLeft ? CFG_OP::STORE : CFG_OP::LOAD, arg1, createConstArg(1), isLeft ? isLeft : reg, NULL, ex); blocks.push_back(new IR_Block(instr)); return reg; } @@ -602,7 +602,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector& { if (returnReg == NULL) { - Instruction* instr = new Instruction(CFG_OP::LOAD, arg, NULL, reg); + Instruction* instr = new Instruction(CFG_OP::LOAD, arg, NULL, reg, NULL, ex); blocks.push_back(new IR_Block(instr)); } else @@ -1572,7 +1572,7 @@ vector buildIR(SgStatement* function, const FuncInfo* func, const vec else findReturn(0, blocks.size(), blocks, blocks.back()->getNumber()); - // äîáàâëåíèå ñâÿçåé ïî GOTO è ïåðåõîäàì + // ���������� ������ �� GOTO � ��������� for (int z = 0; z < blocks.size(); ++z) { auto op = blocks[z]->getInstruction()->getOperation(); @@ -1592,7 +1592,7 @@ vector buildIR(SgStatement* function, const FuncInfo* func, const vec blocks[z]->setJump(it->second); - // çàìåíèì ìåòêó íà íîìåð èíñòðóêöèè + // ������� ����� �� ����� ���������� arg->setValue(to_string(it->second->getNumber())); arg->setType(CFG_ARG_TYPE::INSTR); } diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index 4461d94..c603178 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -7,553 +7,19 @@ #include #include "private_arrays_search.h" +#include "range_structures.h" +#include "region.h" #include "../Utils/SgUtils.h" #include "../GraphLoop/graph_loops.h" #include "../CFGraph/CFGraph.h" using namespace std; -void print_info(LoopGraph* loop) -{ - cout << "loopSymbol: " << loop->loopSymbol << endl; - for (const auto& ops : loop->writeOpsForLoop) - { - cout << "Array name: " << ops.first->GetShortName() << endl; - for (const auto i : ops.second) - { - i.printInfo(); - } - } - if (!loop->children.empty()) - { - for (const auto child : loop->children) - { - print_info(child); - } - } -} - -static bool isParentStmt(SgStatement* stmt, SgStatement* parent) -{ - for (; stmt; stmt = stmt->controlParent()) - if (stmt == parent) - { - return true; - } - return false; -} - -/*returns head block and loop*/ -pair> GetBasicBlocksForLoop(const LoopGraph* loop, const vector blocks) -{ - unordered_set block_loop; - SAPFOR::BasicBlock* head_block = nullptr; - auto loop_operator = loop->loop->GetOriginal(); - for (const auto& block : blocks) - { - if (!block || (block->getInstructions().size() == 0)) - { - continue; - } - SgStatement* first = block->getInstructions().front()->getInstruction()->getOperator(); - SgStatement* last = block->getInstructions().back()->getInstruction()->getOperator(); - if (isParentStmt(first, loop_operator) && isParentStmt(last, loop_operator)) - { - block_loop.insert(block); - - if ((!head_block) && (first == loop_operator) && (last == loop_operator) && - (block->getInstructions().size() == 2) && - (block->getInstructions().back()->getInstruction()->getOperation() == SAPFOR::CFG_OP::JUMP_IF)) - { - head_block = block; - } - - } - } - return { head_block, block_loop }; -} - - -static void BuildLoopIndex(map& loopForIndex, LoopGraph* loop) { - string index = loop->loopSymbol; - loopForIndex[index] = 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()}; - - for (int i = pos-1; i >= 0; i--) { - SAPFOR::Argument* res = block->getInstructions()[i]->getInstruction()->getResult(); - if (res && args.find(res) != args.end()) { - SAPFOR::Argument* arg1 = block->getInstructions()[i]->getInstruction()->getArg1(); - SAPFOR::Argument* arg2 = block->getInstructions()[i]->getInstruction()->getArg2(); - if (arg1) { - string name = arg1->getValue(); - int idx = name.find('%'); - if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end()) - return name.substr(idx + 1); - else { - args.insert(arg1); - } - } - if (arg2) { - string name = arg2->getValue(); - int idx = name.find('%'); - if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end()) - return name.substr(idx + 1); - else { - args.insert(arg2); - } - } - } - } - return ""; -} - -static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use) { - auto instructions = block->getInstructions(); - map loopForIndex; - BuildLoopIndex(loopForIndex, loop); - for(int i = 0; i < instructions.size(); i++) - { - auto instruction = instructions[i]; - if(!instruction->getInstruction()->getArg1()) { - continue; - } - auto operation = instruction->getInstruction()->getOperation(); - auto type = instruction->getInstruction()->getArg1()->getType(); - if ((operation == SAPFOR::CFG_OP::STORE || operation == SAPFOR::CFG_OP::LOAD) && type == SAPFOR::CFG_ARG_TYPE::ARRAY) - { - 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(); - } - int j = i - 1; - while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF) - { - index_vars.push_back(instructions[j]->getInstruction()->getArg1()); - refPos.push_back(j); - j--; - } - /*to choose correct dimension*/ - int n = index_vars.size(); - vector accessPoint(n); - /*if (operation == SAPFOR::CFG_OP::STORE) - { - if (def[array_name].empty()) - { - def[array_name].resize(n); - } - } - else - { - if (use[array_name].empty()) - { - use[array_name].resize(n); - } - }*/ - - SgArrayRefExp* ref = (SgArrayRefExp*)instruction->getInstruction()->getExpression(); - vector> coefsForDims; - for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i) - { - const vector& coefs = getAttributes(ref->subscript(i), set{ INT_VAL }); - if (coefs.size() == 1) - { - const pair coef(coefs[0][0], coefs[0][1]); - coefsForDims.push_back(coef); - } - - } - cout << coefsForDims.size() << endl; - - while (!index_vars.empty()) - { - auto var = index_vars.back(); - int currentVarPos = refPos.back(); - pair currentCoefs = coefsForDims.back(); - ArrayDimension current_dim; - if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST) { - current_dim = { stoul(var->getValue()), 1, 1 }; - } - else - { - 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; - } - } - uint64_t start = currentLoop->startVal * currentCoefs.first + currentCoefs.second; - uint64_t step = currentCoefs.first; - current_dim = { start, step, (uint64_t)currentLoop->calculatedCountOfIters }; - } - /*if (operation == SAPFOR::CFG_OP::STORE) - { - def[array_name][n - index_vars.size()].push_back(current_dim); - } - else - { - use[array_name][n - index_vars.size()].push_back(current_dim); - }*/ - accessPoint[n - index_vars.size()] = current_dim; - index_vars.pop_back(); - refPos.pop_back(); - coefsForDims.pop_back(); - } - if (operation == SAPFOR::CFG_OP::STORE) - { - def[array_name].Insert(accessPoint); - } - else - { - use[array_name].Insert(accessPoint); - } - } - } - return 0; - -} - -static vector FindParticularSolution(const ArrayDimension& dim1, const ArrayDimension& dim2) -{ - for (uint64_t i = 0; i < dim1.tripCount; i++) - { - uint64_t leftPart = dim1.start + i * dim1.step; - for (uint64_t j = 0; j < dim2.tripCount; j++) - { - uint64_t rightPart = dim2.start + j * dim2.step; - if (leftPart == rightPart) - { - return {i, j}; - } - } - } - return {}; -} - -/* dim1 /\ dim2 */ -static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const ArrayDimension& dim2) -{ - vector partSolution = FindParticularSolution(dim1, dim2); - if (partSolution.empty()) - { - return NULL; - } - int64_t x0 = partSolution[0], y0 = partSolution[1]; - /* x = x_0 + c * t */ - /* y = y_0 + d * t */ - int64_t c = dim2.step / gcd(dim1.step, dim2.step); - int64_t d = dim1.step / gcd(dim1.step, dim2.step); - int64_t tXMin, tXMax, tYMin, tYMax; - tXMin = -x0 / c; - tXMax = (dim1.tripCount - 1 - x0) / c; - tYMin = -y0 / d; - tYMax = (dim2.tripCount - 1 - y0) / d; - int64_t tMin = max(tXMin, tYMin); - uint64_t tMax = min(tXMax, tYMax); - if (tMin > tMax) - { - return NULL; - } - uint64_t start3 = dim1.start + x0 * dim1.step; - uint64_t step3 = c * dim1.step; - ArrayDimension* result = new(ArrayDimension){ start3, step3, tMax + 1 }; - return result; -} - -/* dim1 / dim2 */ -static vector DimensionDifference(const ArrayDimension& dim1, const ArrayDimension& dim2) -{ - ArrayDimension* intersection = DimensionIntersection(dim1, dim2); - if (!intersection) - { - return {dim1}; - } - vector result; - /* add the part before intersection */ - if (dim1.start < intersection->start) - { - result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step }); - } - /* 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++) - { - uint64_t centerValue = dim1.start + i * dim1.step; - if (centerValue == interValue) - { - if (i - start > 1) - { - result.push_back({ dim1.start + (start + 1) * dim1.step, dim1.step, i - start - 1 }); - start = i; - } - interValue += intersection->step; - } - } - /* add the part after intersection */ - if (intersection->start + intersection->step * (intersection->tripCount - 1) < dim1.start + dim1.step * (dim1.tripCount - 1)) - { - /* first value after intersection */ - uint64_t right_start = intersection->start + intersection->step * (intersection->tripCount - 1) + dim1.step; - uint64_t tripCount = (dim1.start + dim1.step * dim1.tripCount - right_start) / dim1.step; - result.push_back({right_start, dim1.step, tripCount}); - } - delete(intersection); - return result; -} - - -static vector DimensionUnion(const ArrayDimension& dim1, const ArrayDimension& dim2) -{ - vector res; - ArrayDimension* inter = DimensionIntersection(dim1, dim2); - if(!inter) - { - return { dim1, dim2 }; - } - res.push_back(*inter); - delete(inter); - vector diff1, diff2; - diff1 = DimensionDifference(dim1, dim2); - diff2 = DimensionDifference(dim2, dim1); - res.insert(res.end(), diff1.begin(), diff1.end()); - res.insert(res.end(), diff2.begin(), diff2.end()); - return res; -} - -static vector ElementsIntersection(const vector& firstElement, const vector& secondElement) -{ - if(firstElement.empty() || secondElement.empty()) { - return {}; - } - size_t dimAmount = firstElement.size(); - /* check if there is no intersecction */ - for(size_t i = 0; i < dimAmount; i++) - { - if(FindParticularSolution(firstElement[i], secondElement[i]).empty()){ - return {}; - } - } - vector result(dimAmount); - for(size_t i = 0; i < dimAmount; i++) - { - ArrayDimension* resPtr = DimensionIntersection(firstElement[i], secondElement[i]); - if(resPtr) - { - result[i] = *resPtr; - } - else - { - return {}; - } - } - return result; -} - -static vector> ElementsDifference(const vector& firstElement, - const vector& secondElement) -{ - if(firstElement.empty() || secondElement.empty()) { - return {}; - } - vector intersection = ElementsIntersection(firstElement, secondElement); - vector> result; - if(intersection.empty()) - { - return {firstElement}; - } - for(int i = 0; i < firstElement.size(); i++) - { - auto dimDiff = DimensionDifference(firstElement[i], secondElement[i]); - if(!dimDiff.empty()) - { - vector firstCopy = firstElement; - for(const auto& range: dimDiff) - { - firstCopy[i] = range; - result.push_back(firstCopy); - } - } - } - return result; -} - -static void ElementsUnion(const vector& firstElement, const vector& secondElement, - vector>& lc, vector>& rc, - vector& intersection) -{ - /* lc(rc) is a set of ranges, which only exist in first(second) element*/ - intersection = ElementsIntersection(firstElement, secondElement); - lc = ElementsDifference(firstElement, intersection); - rc = ElementsDifference(secondElement, intersection); -} - -void AccessingSet::FindUncovered(const vector& element, vector>& result) const{ - vector> newTails; - result.push_back(element); - for(const auto& currentElement: allElements) - { - for(const auto& tailLoc: result) - { - auto intersection = ElementsIntersection(tailLoc, currentElement); - auto diff = ElementsDifference(tailLoc, intersection); - if(!diff.empty()) { - newTails.insert(newTails.end(), diff.begin(), diff.end()); - } - } - result = move(newTails); - } -} - -bool AccessingSet::ContainsElement(const vector& element) const -{ - vector> tails; - FindUncovered(element, tails); - return !tails.empty(); -} - -void AccessingSet::FindCoveredBy(const vector& element, vector>& result) const -{ - for(const auto& currentElement: allElements) - { - auto intersection = ElementsIntersection(element, currentElement); - if(!intersection.empty()) { - result.push_back(intersection); - } - } -} - -vector> AccessingSet::GetElements() const -{ - return allElements; -} - -void AccessingSet::Insert(const vector& element) -{ - vector> tails; - FindUncovered(element, tails); - allElements.insert(allElements.end(), tails.begin(), tails.end()); -} - -AccessingSet AccessingSet::Union(const AccessingSet& source) { - AccessingSet result; - for(auto& element: source.GetElements()) { - result.Insert(element); - } - return result; -} - -AccessingSet AccessingSet::Intersect(const AccessingSet& secondSet) const -{ - vector> result; - for(const auto& element: allElements) - { - if(secondSet.ContainsElement(element)) - { - result.push_back(element); - } - else - { - vector> coveredBy; - secondSet.FindCoveredBy(element, coveredBy); - if(!coveredBy.empty()) - { - result.insert(result.end(), coveredBy.begin(), coveredBy.end()); - } - } - } - return AccessingSet(result); -} - -AccessingSet AccessingSet::Diff(const AccessingSet& secondSet) const -{ - AccessingSet intersection = this->Intersect(secondSet); - AccessingSet uncovered = *this; - vector> result; - for (const auto& element : intersection.GetElements()) - { - vector> current_uncovered; - uncovered.FindUncovered(element, current_uncovered); - uncovered = AccessingSet(current_uncovered); - } - return uncovered; -} - -static bool operator!=(const ArrayDimension& lhs, const ArrayDimension& rhs) -{ - return !(lhs.start == rhs.start && lhs.step == rhs.step && lhs.tripCount == rhs.tripCount); -} - - -static bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs) -{ - for (size_t i = 0; i < lhs.allElements.size(); i++) - { - for (size_t j = 0; j < lhs.allElements[i].size(); j++) - { - if (lhs.allElements[i][j] != rhs.allElements[i][j]) - { - return true; - } - } - } - return false; -} - -static bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs) -{ - if(lhs.size() != rhs.size()) - { - return true; - } - for(auto& [key, value]: lhs) - { - if(rhs.find(key) == rhs.end()) - { - return true; - } - } - return false; -} - void Collapse(Region* region) { if (region->getBasickBlocks().empty()) return; - else - { - cout << region->getBasickBlocks().size(); - } + for (auto& [arrayName, arrayRanges] : region->getHeader()->array_out) { for (Region* byBlock : region->getBasickBlocks()) @@ -592,71 +58,6 @@ void Collapse(Region* region) { nextBlock->replaceInPrevRegions(region, region->getHeader()); } - for (Region* bb : region->getBasickBlocks()) - { - delete(bb); - } - cout << "Collapse\n"; -} - -static void SetConnections(unordered_map& bbToRegion, const unordered_set& blockSet) -{ - for (SAPFOR::BasicBlock* block : blockSet) - { - for (SAPFOR::BasicBlock* nextBlock : block->getNext()) - { - if (bbToRegion.find(nextBlock) != bbToRegion.end()) - { - bbToRegion[block]->addNextRegion(bbToRegion[nextBlock]); - } - } - for (SAPFOR::BasicBlock* prevBlock : block->getPrev()) - { - if (bbToRegion.find(prevBlock) != bbToRegion.end()) - { - bbToRegion[block]->addPrevRegion(bbToRegion[prevBlock]); - } - } - } -} - -static Region* CreateSubRegion(LoopGraph* loop, const vector& Blocks, const unordered_map& bbToRegion) -{ - Region* region = new Region; - auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); - for (SAPFOR::BasicBlock* block : Blocks) - { - if (bbToRegion.find(block) != bbToRegion.end()) - { - region->addBasickBlocks(bbToRegion.at(block)); - } - } - for (LoopGraph* childLoop : loop->children) - { - region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); - } - return region; -} - -Region::Region(LoopGraph* loop, const vector& Blocks) -{ - auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); - unordered_map bbToRegion; - for (auto poiner : blockSet) - { - bbToRegion[poiner] = new Region(*poiner); - this->basickBlocks.insert(bbToRegion[poiner]); - ArrayAccessingIndexes def, use; - GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use); - - } - this->header = bbToRegion[header]; - SetConnections(bbToRegion, blockSet); - //create subRegions - for (LoopGraph* childLoop : loop->children) - { - subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); - } } static void SolveDataFlowIteratively(Region* DFG) @@ -666,31 +67,56 @@ static void SolveDataFlowIteratively(Region* DFG) { Region* b = *worklist.begin(); ArrayAccessingIndexes newIn; + bool flagFirst = true; for (Region* prevBlock : b->getPrevRegions()) { - for (const auto& [arrayName, accessSet] : prevBlock->array_out) + if (flagFirst) { - if (newIn.find(arrayName) != newIn.end()) - { - newIn[arrayName] = newIn[arrayName].Intersect(accessSet); - } - else - { - newIn[arrayName] = accessSet; - } - } - } - b->array_in = newIn; - ArrayAccessingIndexes newOut; - for (auto& [arrayName, accessSet] : b->array_def) - { - if (newOut.find(arrayName) != newOut.end()) - { - newOut[arrayName] = b->array_def[arrayName].Union(b->array_in[arrayName]); + newIn = prevBlock->array_out; + flagFirst = false; } else { - newOut[arrayName] = accessSet; + if (prevBlock->array_out.empty()) + { + newIn.clear(); + continue; + } + 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 */ @@ -704,18 +130,18 @@ static void SolveDataFlowIteratively(Region* DFG) } } while (!worklist.empty()); - cout << "solveDFIt\n"; } static void SolveDataFlow(Region* DFG) { + if (!DFG) + return; SolveDataFlowIteratively(DFG); for (Region* subRegion : DFG->getSubRegions()) { SolveDataFlow(subRegion); } Collapse(DFG); - cout << "SolveDF\n"; } map FindPrivateArrays(map> &loopGraph, map>& FullIR) @@ -727,17 +153,6 @@ map FindPrivateArrays(mapgetNumber() == 4) - { - GetDefUseArray(bb, loop, def, use); - return {}; - } - } - // Region* loopRegion = new Region(loop, blocks); SolveDataFlow(loopRegion); result[loop] = loopRegion->array_priv; @@ -745,47 +160,5 @@ map FindPrivateArrays(map A = { {1, 1, 2}, {0, 1, 6} }; - vector B = { {0, 1, 6}, {2, 1, 2} }; - vector C = { {1, 1, 2}, {2, 1, 2} }; return result; } - -void GetDimensionInfo(LoopGraph* loop, map>>& loopDimensionsInfo, int level) -{ - cout << "line_num: " << loop->lineNum << endl; - for (const auto& writeOpPairs : loop->writeOpsForLoop) - { - vector> arrayDimensions(writeOpPairs.first->GetDimSize()); - loopDimensionsInfo[writeOpPairs.first] = arrayDimensions; - for (const auto& writeOp : writeOpPairs.second) - { - for (const auto& coeficient_pair : writeOp.coefficients) - { - uint64_t start, step, tripCount; - start = loop->startVal * coeficient_pair.first.first + coeficient_pair.first.second; - step = loop->stepVal * coeficient_pair.first.first; - tripCount = (loop->endVal - coeficient_pair.first.second) / step; - if (start <= loop->endVal) - { - loopDimensionsInfo[writeOpPairs.first][level].push_back({start, step, tripCount}); - cout << "level: " << level << endl; - cout << "start: " << start << endl; - cout << "step: " << step << endl; - cout << "trip_count: " << tripCount << endl; - cout << endl; - } - - - } - } - } - cout << "line_num_after: " << loop->lineNumAfterLoop << endl; - if (!loop->children.empty()) - { - for (const auto& childLoop : loop->children) - { - GetDimensionInfo(childLoop, loopDimensionsInfo, level+1); - } - } -} diff --git a/src/PrivateAnalyzer/private_arrays_search.h b/src/PrivateAnalyzer/private_arrays_search.h index cc26f78..1b8dfdd 100644 --- a/src/PrivateAnalyzer/private_arrays_search.h +++ b/src/PrivateAnalyzer/private_arrays_search.h @@ -4,118 +4,11 @@ #include #include +#include "range_structures.h" +#include "region.h" #include "../GraphLoop/graph_loops.h" #include "../CFGraph/CFGraph.h" - -struct ArrayDimension -{ - uint64_t start, step, tripCount; -}; - -class AccessingSet { - private: - std::vector> allElements; - - public: - AccessingSet(std::vector> input) : allElements(input) {}; - AccessingSet() {}; - std::vector> GetElements() const; - void Insert(const std::vector& element); - AccessingSet Union(const AccessingSet& source); - AccessingSet Intersect(const AccessingSet& secondSet) const; - AccessingSet Diff(const AccessingSet& secondSet) const; - bool ContainsElement(const std::vector& element) const; - void FindCoveredBy(const std::vector& element, std::vector>& result) const; - void FindUncovered(const std::vector& element, std::vector>& result) const; - friend bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs); -}; - -using ArrayAccessingIndexes = std::map; - -class Region: public SAPFOR::BasicBlock { - public: - Region() - { - header = nullptr; - } - - Region(SAPFOR::BasicBlock block) : SAPFOR::BasicBlock::BasicBlock(block) - { - header = nullptr; - } - - Region(LoopGraph* loop, const std::vector& Blocks); - - Region* getHeader() - { - return header; - } - - std::unordered_set& getBasickBlocks() - { - return basickBlocks; - } - - void addBasickBlocks(Region* region) - { - basickBlocks.insert(region); - } - std::unordered_set getPrevRegions() - { - return prevRegions; - } - - std::unordered_set getNextRegions() - { - return nextRegions; - } - - void addPrevRegion(Region* region) - { - prevRegions.insert(region); - } - - void addNextRegion(Region* region) - { - nextRegions.insert(region); - } - - void replaceInPrevRegions(Region* source, Region* destination) - { - prevRegions.erase(destination); - prevRegions.insert(source); - } - - void replaceInNextRegions(Region* source, Region* destination) - { - nextRegions.erase(destination); - nextRegions.insert(source); - } - - std::unordered_set getSubRegions() - { - return subRegions; - } - - void addSubRegions(Region* region) - { - subRegions.insert(region); - } - - ArrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv; - - private: - std::unordered_set subRegions, basickBlocks; - /*next Region which is BB for current BB Region*/ - std::unordered_set nextRegions; - /*prev Regions which is BBs for current BB Region*/ - std::unordered_set prevRegions; - Region* header; -}; - - void Collapse(Region* region); std::map FindPrivateArrays(std::map>& loopGraph, std::map>& FullIR); -void GetDimensionInfo(LoopGraph* loop, std::map>>& loopDimensionsInfo, int level); std::pair> GetBasicBlocksForLoop(const LoopGraph* loop, const std::vector blocks); diff --git a/src/PrivateAnalyzer/range_structures.cpp b/src/PrivateAnalyzer/range_structures.cpp new file mode 100644 index 0000000..618fcfa --- /dev/null +++ b/src/PrivateAnalyzer/range_structures.cpp @@ -0,0 +1,317 @@ +#include +#include +#include +#include +#include + +#include "range_structures.h" + +using namespace std; + +static vector FindParticularSolution(const ArrayDimension& dim1, const ArrayDimension& dim2) +{ + for (uint64_t i = 0; i < dim1.tripCount; i++) + { + uint64_t leftPart = dim1.start + i * dim1.step; + for (uint64_t j = 0; j < dim2.tripCount; j++) + { + uint64_t rightPart = dim2.start + j * dim2.step; + if (leftPart == rightPart) + { + return { i, j }; + } + } + } + return {}; +} + +/* dim1 /\ dim2 */ +static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const ArrayDimension& dim2) +{ + vector partSolution = FindParticularSolution(dim1, dim2); + if (partSolution.empty()) + { + return NULL; + } + int64_t x0 = partSolution[0], y0 = partSolution[1]; + /* x = x_0 + c * t */ + /* y = y_0 + d * t */ + int64_t c = dim2.step / gcd(dim1.step, dim2.step); + int64_t d = dim1.step / gcd(dim1.step, dim2.step); + int64_t tXMin, tXMax, tYMin, tYMax; + tXMin = -x0 / c; + tXMax = (dim1.tripCount - 1 - x0) / c; + tYMin = -y0 / d; + tYMax = (dim2.tripCount - 1 - y0) / d; + int64_t tMin = max(tXMin, tYMin); + uint64_t tMax = min(tXMax, tYMax); + if (tMin > tMax) + { + return NULL; + } + uint64_t start3 = dim1.start + x0 * dim1.step; + uint64_t step3 = c * dim1.step; + ArrayDimension* result = new(ArrayDimension){ start3, step3, tMax + 1 }; + return result; +} + +/* dim1 / dim2 */ +static vector DimensionDifference(const ArrayDimension& dim1, const ArrayDimension& dim2) +{ + ArrayDimension* intersection = DimensionIntersection(dim1, dim2); + if (!intersection) + { + return { dim1 }; + } + vector result; + /* add the part before intersection */ + if (dim1.start < intersection->start) + { + result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step }); + } + /* 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++) + { + uint64_t centerValue = dim1.start + i * dim1.step; + if (centerValue == interValue) + { + if (i - start > 1) + { + result.push_back({ dim1.start + (start + 1) * dim1.step, dim1.step, i - start - 1 }); + start = i; + } + interValue += intersection->step; + } + } + /* add the part after intersection */ + if (intersection->start + intersection->step * (intersection->tripCount - 1) < dim1.start + dim1.step * (dim1.tripCount - 1)) + { + /* first value after intersection */ + uint64_t right_start = intersection->start + intersection->step * (intersection->tripCount - 1) + dim1.step; + uint64_t tripCount = (dim1.start + dim1.step * dim1.tripCount - right_start) / dim1.step; + result.push_back({ right_start, dim1.step, tripCount }); + } + delete(intersection); + return result; +} + + +static vector DimensionUnion(const ArrayDimension& dim1, const ArrayDimension& dim2) +{ + vector res; + ArrayDimension* inter = DimensionIntersection(dim1, dim2); + if (!inter) + { + return { dim1, dim2 }; + } + res.push_back(*inter); + delete(inter); + vector diff1, diff2; + diff1 = DimensionDifference(dim1, dim2); + diff2 = DimensionDifference(dim2, dim1); + res.insert(res.end(), diff1.begin(), diff1.end()); + res.insert(res.end(), diff2.begin(), diff2.end()); + return res; +} + +static vector ElementsIntersection(const vector& firstElement, const vector& secondElement) +{ + if (firstElement.empty() || secondElement.empty()) { + return {}; + } + size_t dimAmount = firstElement.size(); + /* check if there is no intersecction */ + for (size_t i = 0; i < dimAmount; i++) + { + if (FindParticularSolution(firstElement[i], secondElement[i]).empty()) { + return {}; + } + } + vector result(dimAmount); + for (size_t i = 0; i < dimAmount; i++) + { + ArrayDimension* resPtr = DimensionIntersection(firstElement[i], secondElement[i]); + if (resPtr) + { + result[i] = *resPtr; + } + else + { + return {}; + } + } + return result; +} + +static vector> ElementsDifference(const vector& firstElement, + const vector& secondElement) +{ + if (firstElement.empty() || secondElement.empty()) { + return {}; + } + vector intersection = ElementsIntersection(firstElement, secondElement); + vector> result; + if (intersection.empty()) + { + return { firstElement }; + } + for (int i = 0; i < firstElement.size(); i++) + { + auto dimDiff = DimensionDifference(firstElement[i], secondElement[i]); + if (!dimDiff.empty()) + { + vector firstCopy = firstElement; + for (const auto& range : dimDiff) + { + firstCopy[i] = range; + result.push_back(firstCopy); + } + } + } + return result; +} + +static void ElementsUnion(const vector& firstElement, const vector& secondElement, + vector>& lc, vector>& rc, + vector& intersection) +{ + /* lc(rc) is a set of ranges, which only exist in first(second) element*/ + intersection = ElementsIntersection(firstElement, secondElement); + lc = ElementsDifference(firstElement, intersection); + rc = ElementsDifference(secondElement, intersection); +} + +void AccessingSet::FindUncovered(const vector& element, vector>& result) const { + vector> newTails; + result.push_back(element); + for (const auto& currentElement : allElements) + { + for (const auto& tailLoc : result) + { + auto intersection = ElementsIntersection(tailLoc, currentElement); + auto diff = ElementsDifference(tailLoc, intersection); + if (!diff.empty()) { + newTails.insert(newTails.end(), diff.begin(), diff.end()); + } + } + result = move(newTails); + } +} + +bool AccessingSet::ContainsElement(const vector& element) const +{ + vector> tails; + FindUncovered(element, tails); + return !tails.empty(); +} + +void AccessingSet::FindCoveredBy(const vector& element, vector>& result) const +{ + for (const auto& currentElement : allElements) + { + auto intersection = ElementsIntersection(element, currentElement); + if (!intersection.empty()) { + result.push_back(intersection); + } + } +} + +vector> AccessingSet::GetElements() const { return allElements; } + +void AccessingSet::Insert(const vector& element) +{ + vector> tails; + FindUncovered(element, tails); + allElements.insert(allElements.end(), tails.begin(), tails.end()); +} + +AccessingSet AccessingSet::Union(const AccessingSet& source) { + AccessingSet result; + for (auto& element : source.GetElements()) { + result.Insert(element); + } + for (auto& element : allElements) + { + result.Insert(element); + } + return result; +} + +AccessingSet AccessingSet::Intersect(const AccessingSet& secondSet) const +{ + vector> result; + if (secondSet.GetElements().empty() || this->allElements.empty()) + return AccessingSet(result); + for (const auto& element : allElements) + { + if (secondSet.ContainsElement(element)) + { + result.push_back(element); + } + else + { + vector> coveredBy; + secondSet.FindCoveredBy(element, coveredBy); + if (!coveredBy.empty()) + { + result.insert(result.end(), coveredBy.begin(), coveredBy.end()); + } + } + } + return AccessingSet(result); +} + +AccessingSet AccessingSet::Diff(const AccessingSet& secondSet) const +{ + if (secondSet.GetElements().empty() || allElements.empty()) + return *this; + AccessingSet intersection = this->Intersect(secondSet); + AccessingSet uncovered = *this; + vector> result; + for (const auto& element : intersection.GetElements()) + { + vector> current_uncovered; + uncovered.FindUncovered(element, current_uncovered); + uncovered = AccessingSet(current_uncovered); + } + return uncovered; +} + +bool operator!=(const ArrayDimension& lhs, const ArrayDimension& rhs) +{ + return !(lhs.start == rhs.start && lhs.step == rhs.step && lhs.tripCount == rhs.tripCount); +} + + +bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs) +{ + for (size_t i = 0; i < lhs.allElements.size(); i++) + { + for (size_t j = 0; j < lhs.allElements[i].size(); j++) + { + if (lhs.allElements[i][j] != rhs.allElements[i][j]) + { + return true; + } + } + } + return false; +} + +bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs) +{ + if (lhs.size() != rhs.size()) + { + return true; + } + for (auto& [key, value] : lhs) + { + if (rhs.find(key) == rhs.end()) + { + return true; + } + } + return false; +} diff --git a/src/PrivateAnalyzer/range_structures.h b/src/PrivateAnalyzer/range_structures.h new file mode 100644 index 0000000..004f73e --- /dev/null +++ b/src/PrivateAnalyzer/range_structures.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include +#include + +struct ArrayDimension +{ + uint64_t start, step, tripCount; +}; + +class AccessingSet { +private: + std::vector> allElements; + +public: + AccessingSet(std::vector> input) : allElements(input) {}; + AccessingSet() {}; + AccessingSet(const AccessingSet& a) { allElements = a.GetElements(); }; + std::vector> GetElements() const; + void Insert(const std::vector& element); + AccessingSet Union(const AccessingSet& source); + AccessingSet Intersect(const AccessingSet& secondSet) const; + AccessingSet Diff(const AccessingSet& secondSet) const; + bool ContainsElement(const std::vector& element) const; + void FindCoveredBy(const std::vector& element, std::vector>& result) const; + void FindUncovered(const std::vector& element, std::vector>& result) const; + friend bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs); +}; + +using ArrayAccessingIndexes = std::map; + +bool operator!=(const ArrayDimension& lhs, const ArrayDimension& rhs); +bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs); +bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs); \ No newline at end of file diff --git a/src/PrivateAnalyzer/region.cpp b/src/PrivateAnalyzer/region.cpp new file mode 100644 index 0000000..64375d9 --- /dev/null +++ b/src/PrivateAnalyzer/region.cpp @@ -0,0 +1,268 @@ +#include +#include +#include +#include +#include +#include + +#include "range_structures.h" +#include "region.h" + +#include "../Utils/SgUtils.h" + +using namespace std; + +static bool isParentStmt(SgStatement* stmt, SgStatement* parent) +{ + for (; stmt; stmt = stmt->controlParent()) + if (stmt == parent) + { + return true; + } + return false; +} + +/*returns head block and loop*/ +pair> GetBasicBlocksForLoop(const LoopGraph* loop, const vector blocks) +{ + unordered_set block_loop; + SAPFOR::BasicBlock* head_block = nullptr; + auto loop_operator = loop->loop->GetOriginal(); + for (const auto& block : blocks) + { + if (!block || (block->getInstructions().size() == 0)) + { + continue; + } + SgStatement* first = block->getInstructions().front()->getInstruction()->getOperator(); + SgStatement* last = block->getInstructions().back()->getInstruction()->getOperator(); + if (isParentStmt(first, loop_operator) && isParentStmt(last, loop_operator)) + { + block_loop.insert(block); + + if ((!head_block) && (first == loop_operator) && (last == loop_operator) && + (block->getInstructions().size() == 2) && + (block->getInstructions().back()->getInstruction()->getOperation() == SAPFOR::CFG_OP::JUMP_IF)) + { + head_block = block; + } + + } + } + return { head_block, block_loop }; +} + +static void BuildLoopIndex(map& loopForIndex, LoopGraph* loop) { + string index = loop->loopSymbol; + loopForIndex[index] = 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() }; + + for (int i = pos - 1; i >= 0; i--) { + SAPFOR::Argument* res = block->getInstructions()[i]->getInstruction()->getResult(); + if (res && args.find(res) != args.end()) { + SAPFOR::Argument* arg1 = block->getInstructions()[i]->getInstruction()->getArg1(); + SAPFOR::Argument* arg2 = block->getInstructions()[i]->getInstruction()->getArg2(); + if (arg1) { + string name = arg1->getValue(); + int idx = name.find('%'); + if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end()) + return name.substr(idx + 1); + else { + args.insert(arg1); + } + } + if (arg2) { + string name = arg2->getValue(); + int idx = name.find('%'); + if (idx != -1 && loopForIndex.find(name.substr(idx + 1)) != loopForIndex.end()) + return name.substr(idx + 1); + else { + args.insert(arg2); + } + } + } + } + return ""; +} + +static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use) { + auto instructions = block->getInstructions(); + map loopForIndex; + BuildLoopIndex(loopForIndex, loop); + for (int i = 0; i < instructions.size(); i++) + { + auto instruction = instructions[i]; + if (!instruction->getInstruction()->getArg1()) { + continue; + } + auto operation = instruction->getInstruction()->getOperation(); + auto type = instruction->getInstruction()->getArg1()->getType(); + if ((operation == SAPFOR::CFG_OP::STORE || operation == SAPFOR::CFG_OP::LOAD) && type == SAPFOR::CFG_ARG_TYPE::ARRAY) + { + 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(); + } + int j = i - 1; + while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF) + { + index_vars.push_back(instructions[j]->getInstruction()->getArg1()); + refPos.push_back(j); + j--; + } + /*to choose correct dimension*/ + int n = index_vars.size(); + vector accessPoint(n); + + auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); + + vector> coefsForDims; + for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i) + { + const vector& coefs = getAttributes(ref->subscript(i), set{ INT_VAL }); + if (coefs.size() == 1) + { + const pair coef(coefs[0][0], coefs[0][1]); + coefsForDims.push_back(coef); + } + + } + + while (!index_vars.empty()) + { + auto var = index_vars.back(); + int currentVarPos = refPos.back(); + pair currentCoefs = coefsForDims.back(); + ArrayDimension current_dim; + if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST) { + current_dim = { stoul(var->getValue()), 1, 1 }; + } + else + { + 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; + } + } + uint64_t start = currentLoop->startVal * currentCoefs.first + currentCoefs.second; + uint64_t step = currentCoefs.first; + current_dim = { start, step, (uint64_t)currentLoop->calculatedCountOfIters }; + } + accessPoint[n - index_vars.size()] = current_dim; + index_vars.pop_back(); + refPos.pop_back(); + coefsForDims.pop_back(); + } + if (operation == SAPFOR::CFG_OP::STORE) + { + def[array_name].Insert(accessPoint); + } + else + { + use[array_name].Insert(accessPoint); + } + } + } + return 0; + +} + +static void SetConnections(unordered_map& bbToRegion, const unordered_set& blockSet) +{ + for (SAPFOR::BasicBlock* block : blockSet) + { + for (SAPFOR::BasicBlock* nextBlock : block->getNext()) + { + if (bbToRegion.find(nextBlock) != bbToRegion.end()) + { + bbToRegion[block]->addNextRegion(bbToRegion[nextBlock]); + } + } + for (SAPFOR::BasicBlock* prevBlock : block->getPrev()) + { + if (bbToRegion.find(prevBlock) != bbToRegion.end()) + { + bbToRegion[block]->addPrevRegion(bbToRegion[prevBlock]); + } + } + } +} + +static Region* CreateSubRegion(LoopGraph* loop, const vector& Blocks, const unordered_map& bbToRegion) +{ + Region* region = new Region; + auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); + if (bbToRegion.find(header) != bbToRegion.end()) + { + region->setHeader(bbToRegion.at(header)); + } + else + { + return NULL; + } + for (SAPFOR::BasicBlock* block : blockSet) + { + if (bbToRegion.find(block) != bbToRegion.end()) + { + region->addBasickBlocks(bbToRegion.at(block)); + } + } + for (LoopGraph* childLoop : loop->children) + { + region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); + } + cout << header << endl; + return region; +} + +Region::Region(LoopGraph* loop, const vector& Blocks) +{ + auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); + unordered_map bbToRegion; + for (auto poiner : blockSet) + { + bbToRegion[poiner] = new Region(*poiner); + this->basickBlocks.insert(bbToRegion[poiner]); + GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use); + + } + this->header = bbToRegion[header]; + SetConnections(bbToRegion, blockSet); + //create subRegions + for (LoopGraph* childLoop : loop->children) + { + subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); + } +} diff --git a/src/PrivateAnalyzer/region.h b/src/PrivateAnalyzer/region.h new file mode 100644 index 0000000..5e85900 --- /dev/null +++ b/src/PrivateAnalyzer/region.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include +#include +#include + +#include "../GraphLoop/graph_loops.h" +#include "../CFGraph/CFGraph.h" + +class Region : public SAPFOR::BasicBlock { +public: + Region() { header = nullptr; } + + Region(SAPFOR::BasicBlock block) : SAPFOR::BasicBlock::BasicBlock(block) { header = nullptr; } + + Region(LoopGraph* loop, const std::vector& Blocks); + + Region* getHeader() { return header; } + + void setHeader(Region* region) { header = region; } + + std::unordered_set& getBasickBlocks() { return basickBlocks; } + + void addBasickBlocks(Region* region) { basickBlocks.insert(region); } + + const std::unordered_set& getPrevRegions() { return prevRegions; } + + std::unordered_set getNextRegions() { return nextRegions; } + + void addPrevRegion(Region* region) { prevRegions.insert(region); } + + void addNextRegion(Region* region) { nextRegions.insert(region); } + + void replaceInPrevRegions(Region* source, Region* destination) + { + prevRegions.erase(destination); + prevRegions.insert(source); + } + + void replaceInNextRegions(Region* source, Region* destination) + { + nextRegions.erase(destination); + nextRegions.insert(source); + } + + std::unordered_set getSubRegions() { return subRegions; } + + void addSubRegions(Region* region) { subRegions.insert(region); } + + ArrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv; + +private: + std::unordered_set subRegions, basickBlocks; + /*next Region which is BB for current BB Region*/ + std::unordered_set nextRegions; + /*prev Regions which is BBs for current BB Region*/ + std::unordered_set prevRegions; + Region* header; +}; diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index dad0a52..482b949 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -316,7 +316,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 }) <= Pass(FIND_PRIVATE_ARRAYS); + list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS); passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS, EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,