diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index f7d75d0..95624f5 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -16,6 +17,8 @@ using namespace std; +static unordered_set collapsed; + static void RemoveEmptyPoints(ArrayAccessingIndexes& container) { ArrayAccessingIndexes resultContainer; @@ -49,41 +52,81 @@ static void Collapse(Region* region) if (region->getBasickBlocks().empty()) return; - for (auto& [arrayName, arrayRanges] : region->getHeader()->array_out) + bool firstRegion = true; + for (Region* basickBlock : region->getBasickBlocks()) { - for (Region* byBlock : region->getBasickBlocks()) + if (basickBlock->getNextRegions().empty()) { - AccessingSet intersection = byBlock->array_def[arrayName].Intersect(arrayRanges); - region->array_def[arrayName] = region->array_def[arrayName].Union(intersection); + if (firstRegion) + { + region->array_def = basickBlock->array_out; + firstRegion = false; + } + else + { + unordered_set toErease; + for (auto& [arrayName, arrayRanges] : region->array_def) + { + if (basickBlock->array_out.find(arrayName) != basickBlock->array_out.end()) + arrayRanges = arrayRanges.Intersect(basickBlock->array_out[arrayName]); + else + { + arrayRanges = AccessingSet(); + toErease.insert(arrayName); + } + } + for (string arrayName : toErease) + region->array_def.erase(arrayName); + } } } - for (auto& byBlock : region->getBasickBlocks()) - { - for (auto& [arrayName, arrayRanges] : byBlock->array_use) - { - AccessingSet diff = byBlock->array_use[arrayName].Diff(byBlock->array_in[arrayName]); - region->array_use[arrayName] = region->array_use[arrayName].Union(diff); - } - } + RegionInstruction instruction; + instruction.def = move(region->array_def); + - ArrayAccessingIndexes useUnion; for (auto& byBlock : region->getBasickBlocks()) - for (auto& [arrayName, arrayRanges] : byBlock->array_use) - useUnion[arrayName] = useUnion[arrayName].Union(byBlock->array_use[arrayName]); + { + for (auto& instruction : byBlock->instructions) + { + for (auto& [arrayName, _] : instruction.use) + { + AccessingSet diff = instruction.use[arrayName].Diff(instruction.in[arrayName]); + region->array_use[arrayName] = region->array_use[arrayName].Union(diff); + } + } + } - region->array_priv = region->array_use; - - for (Region* prevBlock : region->getHeader()->getPrevRegions()) + ArrayAccessingIndexes useUnionB; + for (auto& byBlock : region->getBasickBlocks()) + for (auto& instruction : byBlock->instructions) + for (auto& [arrayName, _] : instruction.use) + useUnionB[arrayName] = useUnionB[arrayName].Union(instruction.use[arrayName]); + + for (auto& [arrayName, _] : useUnionB) + region->array_priv[arrayName] = useUnionB[arrayName].Diff(region->array_use[arrayName]); + + instruction.use = move(region->array_use); + + for (Region* prevBlock : region->getHeader()->getPrevRegions()) + { prevBlock->replaceInNextRegions(region, region->getHeader()); - + region->addPrevRegion(prevBlock); + } + for (Region* nextBlock : region->getHeader()->getNextRegions()) + { nextBlock->replaceInPrevRegions(region, region->getHeader()); + region->addNextRegion(nextBlock); + } + region->instructions.push_back(instruction); + } -static void SolveDataFlowIteratively(Region* DFG) +static void SolveDataFlowIteratively(Region* DFG) { - unordered_set worklist(DFG->getBasickBlocks()); + auto blocks = DFG->getBasickBlocks(); + std::unordered_set worklist(blocks.begin(), blocks.end()); do { Region* b = *worklist.begin(); @@ -101,13 +144,13 @@ static void SolveDataFlowIteratively(Region* DFG) if (prevBlock->array_out.empty()) { newIn.clear(); - continue; + break; } for (const auto& [arrayName, accessSet] : prevBlock->array_out) { if (newIn.find(arrayName) != newIn.end()) - newIn[arrayName] = newIn[arrayName].Intersect(accessSet); + newIn[arrayName] = newIn[arrayName].Intersect(accessSet); else newIn[arrayName] = AccessingSet(); } @@ -117,7 +160,7 @@ static void SolveDataFlowIteratively(Region* DFG) b->array_in = move(newIn); ArrayAccessingIndexes newOut; - if (b->array_def.empty()) + if (b->array_def.empty()) newOut = b->array_in; else if (b->array_in.empty()) newOut = b->array_def; @@ -133,25 +176,157 @@ static void SolveDataFlowIteratively(Region* DFG) } /* can not differ */ - if (newOut != b->array_out) + if (newOut != b->array_out) b->array_out = newOut; else worklist.erase(b); - } - while (!worklist.empty()); + } while (!worklist.empty()); +} + +static void SolveForBasickBlock(Region* block) +{ + ArrayAccessingIndexes newIn; + bool flagFirst = true; + for (Region* prevBlock : block->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(); + } + } + } + + if (block->instructions.empty()) + block->instructions.push_back(RegionInstruction()); + + block->instructions[0].in = move(newIn); + + for (int i = 0; i < block->instructions.size(); i++) + { + auto& instruction = block->instructions[i]; + + if (i > 0) + instruction.in = block->instructions[i - 1].out; + + ArrayAccessingIndexes newOut; + if (instruction.def.empty()) + newOut = instruction.in; + else if (instruction.in.empty()) + newOut = instruction.def; + else + { + for (auto& [arrayName, accessSet] : instruction.def) + { + if (instruction.in.find(arrayName) != instruction.in.end()) + newOut[arrayName] = instruction.def[arrayName].Union(instruction.in[arrayName]); + else + newOut[arrayName] = accessSet; + } + for (auto& [arrayName, accessSet] : instruction.in) + { + if (newOut.find(arrayName) == newOut.end()) + { + newOut[arrayName] = accessSet; + } + } + } + + instruction.out = move(newOut); + } + if (!block->instructions.empty()) + block->array_out = block->instructions.back().out; +} + +static void SolveDataFlowTopologically(Region* DFG) +{ + for (Region* b : DFG->getBasickBlocks()) + { + collapsed.insert(b); + SolveForBasickBlock(b); + } } static void SolveDataFlow(Region* DFG) { if (!DFG) return; - - SolveDataFlowIteratively(DFG); for (Region* subRegion : DFG->getSubRegions()) + { SolveDataFlow(subRegion); + DFG->addBasickBlocks(subRegion); + } + vector& blocks = DFG->getBasickBlocks(); + auto pos = remove_if(blocks.begin(), blocks.end(), [](Region* r) { return collapsed.find(r) != collapsed.end(); }); + blocks.erase(pos, blocks.end()); + TopologySort(DFG->getBasickBlocks(), DFG->getHeader()); + SolveDataFlowTopologically(DFG); Collapse(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(); + int dimCount = arrayType->dimension(); + for (int i = 0; i < dimCount; i++) + { + SgExpression* sizeExpr = arrayType->sizeInDim(i); + SgConstantSymb* constValSymb = isSgConstantSymb(sizeExpr->symbol()); + string strDimLength; + if (sizeExpr && sizeExpr->variant() == INT_VAL) + strDimLength = sizeExpr->unparse(); + else if (constValSymb) + strDimLength = constValSymb->constantValue()->unparse(); + else + return false; + + if (strDimLength == "0") + return false; + declaredDims.push_back((uint64_t)stoi(strDimLength)); + } + return true; +} + +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) + return false; + vector declaredDims(dimCount); + if (!getArrayDeclaredDimensions(arrayRef, declaredDims)) + return false; + vector testArray(dimCount); + for (size_t i = 0; i < dimCount; i++) + { + testArray[i] = { 1, 1, declaredDims[i], nullptr }; + } + AccessingSet diff = AccessingSet({ testArray }).Diff(array); + + return diff.GetElements().empty(); +} + + static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set& insertedPrivates) { SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR); @@ -161,6 +336,8 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& set arraysToInsert; for (const auto& [_, accessingSet] : privates) { + if (!CheckDimensionLength(accessingSet)) + continue; for (const auto& arrayElement : accessingSet.GetElements()) { if (arrayElement.empty()) @@ -187,16 +364,16 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& } toAdd->setLhs(new SgVarRefExp(elem)); } - - if (arraysToInsert.size() == 0) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - loop->loop->insertStmtBefore(*spfStat, *loop->loop->controlParent()); - insertedPrivates.insert(spfStat); + if (arraysToInsert.size() != 0) + { + loop->loop->insertStmtBefore(*spfStat, *loop->loop->controlParent()); + insertedPrivates.insert(spfStat); + } } -void FindPrivateArrays(map> &loopGraph, map>& FullIR, set &insertedPrivates) -{ +void FindPrivateArrays(map>& loopGraph, map>& FullIR, set& insertedPrivates) +{ map result; for (const auto& [fileName, loops] : loopGraph) { @@ -210,8 +387,8 @@ void FindPrivateArrays(map> &loopGraph, mapcontrolParent(); - for (const auto& [funcInfo, blocks]: FullIR) - { + for (const auto& [funcInfo, blocks] : FullIR) + { if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func) { Region* loopRegion = new Region(loop, blocks); @@ -231,4 +408,4 @@ void FindPrivateArrays(map> &loopGraph, map 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 */ @@ -44,10 +44,10 @@ static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const A 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 , dim1.array}; + ArrayDimension* result = new(ArrayDimension){ start3, step3, tMax + 1 , dim1.array }; return result; } @@ -57,12 +57,12 @@ static vector DimensionDifference(const ArrayDimension& dim1, co 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, dim1.array}); - + if (dim1.start < intersection->start) + result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step, dim1.array }); + /* add the parts between intersection steps */ if (intersection->step > dim1.step) { @@ -70,7 +70,7 @@ static vector DimensionDifference(const ArrayDimension& dim1, co uint64_t interValue = intersection->start; for (int64_t i = start; interValue <= intersection->start + intersection->step * (intersection->tripCount - 1); i++) { - result.push_back({interValue + dim1.step, dim1.step, intersection->step / dim1.step, dim1.array}); + result.push_back({ interValue + dim1.step, dim1.step, intersection->step / dim1.step, dim1.array }); interValue += intersection->step; } } @@ -109,7 +109,7 @@ static vector ElementsIntersection(const vector& { 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++) @@ -132,14 +132,16 @@ static vector ElementsIntersection(const vector& static vector> ElementsDifference(const vector& firstElement, const vector& secondElement) { - if (firstElement.empty() || secondElement.empty()) + if (firstElement.empty()) return {}; - + if (secondElement.empty()) + return { firstElement }; + 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]); @@ -188,7 +190,7 @@ bool AccessingSet::ContainsElement(const vector& element) const { vector> tails; FindUncovered(element, tails); - return !tails.empty(); + return tails.empty(); } void AccessingSet::FindCoveredBy(const vector& element, vector>& result) const @@ -252,13 +254,15 @@ AccessingSet AccessingSet::Diff(const AccessingSet& secondSet) const return *this; AccessingSet intersection = this->Intersect(secondSet); - AccessingSet uncovered = *this; - vector> result; - for (const auto& element : intersection.GetElements()) + vector> uncovered; + for (const auto& element : allElements) { vector> current_uncovered; - uncovered.FindUncovered(element, current_uncovered); - uncovered = AccessingSet(current_uncovered); + intersection.FindUncovered(element, current_uncovered); + uncovered.insert(uncovered.end(), + std::move_iterator(current_uncovered.begin()), + std::move_iterator(current_uncovered.end()) + ); } return uncovered; } @@ -289,4 +293,4 @@ bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& r return true; return false; -} +} \ No newline at end of file diff --git a/src/PrivateAnalyzer/region.cpp b/src/PrivateAnalyzer/region.cpp index 5cde710..5252a7f 100644 --- a/src/PrivateAnalyzer/region.cpp +++ b/src/PrivateAnalyzer/region.cpp @@ -1,14 +1,16 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include "range_structures.h" #include "region.h" +#include "..\Transformations\ExpressionSubstitution\expr_transform.h" #include "SgUtils.h" using namespace std; @@ -62,14 +64,14 @@ static void BuildLoopIndex(map& loopForIndex, LoopGraph* loo 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--) + for (int i = pos - 1; i >= 0; i--) { SAPFOR::Argument* res = block->getInstructions()[i]->getInstruction()->getResult(); - if (res && args.find(res) != args.end()) + 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) + if (arg1) { string name = arg1->getValue(); int idx = name.find('%'); @@ -93,7 +95,7 @@ static string FindIndexName(int pos, SAPFOR::BasicBlock* block, mapgetInstructions(); map loopForIndex; BuildLoopIndex(loopForIndex, loop); @@ -123,7 +125,11 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces } if (point.size() == dimCount) - def[instruction->getInstruction()->getResult()->getValue()] = AccessingSet({point}); + { + def[instruction->getInstruction()->getResult()->getValue()] = AccessingSet({ point }); + RegionInstruction regionInstruction; + regionInstruction.def[instruction->getInstruction()->getResult()->getValue()] = AccessingSet({ point }); + } } } } @@ -131,7 +137,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces { vector index_vars; vector refPos; - string array_name = instruction->getInstruction()->getArg1()->getValue(); + string array_name = instruction->getInstruction()->getArg1()->getValue(); int j = i - 1; while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF) @@ -148,39 +154,53 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); int fillCount = 0; - while (!index_vars.empty() && !refPos.empty()) + vector> coeffsForDims; + int subs = ref->numberOfSubscripts(); + for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i) + { + const vector& coeffs = getAttributes(ref->subscript(i), set{ INT_VAL }); + if (coeffs.size() == 1) + { + const pair coef(coeffs[0][0], coeffs[0][1]); + coeffsForDims.push_back(coef); + } + + } + coeffsForDims = { coeffsForDims.rbegin(), coeffsForDims.rend() }; + + while (!index_vars.empty() && !refPos.empty() && !coeffsForDims.empty()) { auto var = index_vars.back(); int currentVarPos = refPos.back(); ArrayDimension current_dim; if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST) - current_dim = { stoul(var->getValue()), 1, 1, ref}; + current_dim = { stoul(var->getValue()), 1, 1, ref }; else { string name, full_name = var->getValue(); int pos = full_name.find('%'); LoopGraph* currentLoop; - if (pos != -1) + if (pos != -1) { name = full_name.substr(pos + 1); if (loopForIndex.find(name) != loopForIndex.end()) - currentLoop = loopForIndex[name]; + currentLoop = loopForIndex[name]; else return -1; } - else + else { name = FindIndexName(currentVarPos, block, loopForIndex); if (name == "") return -1; if (loopForIndex.find(name) != loopForIndex.end()) - currentLoop = loopForIndex[name]; + currentLoop = loopForIndex[name]; else return -1; } - uint64_t start = currentLoop->startVal; + uint64_t start = coeffsForDims.back().second * currentLoop->startVal + coeffsForDims.back().first; uint64_t step = currentLoop->stepVal; uint64_t iters = currentLoop->calculatedCountOfIters; current_dim = { start, step, iters, ref }; @@ -193,14 +213,29 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces } index_vars.pop_back(); refPos.pop_back(); + coeffsForDims.pop_back(); } if (fillCount == accessPoint.size()) { + RegionInstruction instruction; if (operation == SAPFOR::CFG_OP::STORE) + { def[array_name].Insert(accessPoint); + instruction.def[array_name] = { { accessPoint } }; + } else - use[array_name].Insert(accessPoint); + { + instruction.use[array_name] = { { accessPoint } }; + if (def.find(array_name) == def.end()) + use[array_name].Insert(accessPoint); + else + { + AccessingSet element({ accessPoint }); + use[array_name] = use[array_name].Union(element.Diff(def[array_name])); + } + } + region->instructions.push_back(instruction); } } } @@ -208,6 +243,41 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces } +static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const unordered_set& blockSet, unordered_map& bbToRegion) +{ + for (SAPFOR::BasicBlock* block : blockSet) + { + bool isCycleBlock = false; + for (SAPFOR::BasicBlock* prevBlock : block->getPrev()) + isCycleBlock = isCycleBlock || (blockSet.find(prevBlock) != blockSet.end()); + + if (isCycleBlock) + { + bbToRegion[block]->removeNextRegion(bbToRegion[header]); + bbToRegion[header]->removePrevRegion(bbToRegion[block]); + } + } +} + +static void DFS(Region* block, vector& result, unordered_set cycleBlocks) +{ + for (Region* nextBlock : block->getNextRegions()) + { + if (cycleBlocks.find(nextBlock) != cycleBlocks.end()) + DFS(nextBlock, result, cycleBlocks); + } + result.push_back(block); +} + +void TopologySort(std::vector& basikBlocks, Region* header) +{ + vector result; + unordered_set cycleBlocks(basikBlocks.begin(), basikBlocks.end()); + DFS(header, result, cycleBlocks); + reverse(result.begin(), result.end()); + basikBlocks = result; +} + static void SetConnections(unordered_map& bbToRegion, const unordered_set& blockSet) { for (SAPFOR::BasicBlock* block : blockSet) @@ -215,25 +285,26 @@ static void SetConnections(unordered_map& bbToRegi 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) +static Region* CreateSubRegion(LoopGraph* loop, const vector& Blocks, unordered_map& bbToRegion) { Region* region = new Region; auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); + RemoveHeaderConnection(header, blockSet, bbToRegion); if (bbToRegion.find(header) != bbToRegion.end()) - region->setHeader(bbToRegion.at(header)); + region->setHeader(bbToRegion.at(header)); else { printInternalError(convertFileName(__FILE__).c_str(), __LINE__); return NULL; } - + for (SAPFOR::BasicBlock* block : blockSet) if (bbToRegion.find(block) != bbToRegion.end()) region->addBasickBlocks(bbToRegion.at(block)); @@ -244,6 +315,7 @@ static Region* CreateSubRegion(LoopGraph* loop, const vectoraddSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); } + TopologySort(region->getBasickBlocks(), region->getHeader()); return region; } @@ -254,12 +326,13 @@ Region::Region(LoopGraph* loop, const vector& Blocks) 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->basickBlocks.push_back(bbToRegion[poiner]); + GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use, bbToRegion[poiner]); } this->header = bbToRegion[header]; SetConnections(bbToRegion, blockSet); + RemoveHeaderConnection(header, blockSet, bbToRegion); //create subRegions for (LoopGraph* childLoop : loop->children) { @@ -267,4 +340,5 @@ Region::Region(LoopGraph* loop, const vector& Blocks) continue; subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); } -} + TopologySort(basickBlocks, this->header); +} \ No newline at end of file diff --git a/src/PrivateAnalyzer/region.h b/src/PrivateAnalyzer/region.h index 935460f..3baa8a0 100644 --- a/src/PrivateAnalyzer/region.h +++ b/src/PrivateAnalyzer/region.h @@ -8,6 +8,11 @@ #include "graph_loops.h" #include "CFGraph/CFGraph.h" +struct RegionInstruction +{ + ArrayAccessingIndexes def, use, in, out; +}; + class Region : public SAPFOR::BasicBlock { public: Region() { header = nullptr; } @@ -20,13 +25,25 @@ public: void setHeader(Region* region) { header = region; } - std::unordered_set& getBasickBlocks() { return basickBlocks; } + std::vector& getBasickBlocks() { return basickBlocks; } - void addBasickBlocks(Region* region) { basickBlocks.insert(region); } + void addBasickBlocks(Region* region) { basickBlocks.push_back(region); } const std::unordered_set& getPrevRegions() { return prevRegions; } - std::unordered_set getNextRegions() { return nextRegions; } + std::unordered_set& getNextRegions() { return nextRegions; } + + void removeNextRegion(Region* region) + { + if (nextRegions.find(region) != nextRegions.end()) + nextRegions.erase(region); + } + + void removePrevRegion(Region* region) + { + if (prevRegions.find(region) != prevRegions.end()) + prevRegions.erase(region); + } void addPrevRegion(Region* region) { prevRegions.insert(region); } @@ -48,13 +65,18 @@ public: void addSubRegions(Region* region) { subRegions.insert(region); } + std::vector instructions; + ArrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv; private: - std::unordered_set subRegions, basickBlocks; + std::vector basickBlocks; + std::unordered_set subRegions; /*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 TopologySort(std::vector& basikBlocks, Region* header); \ No newline at end of file