From 0df1d3d5fe85873b96303eba2b7a2f5e9403bca4 Mon Sep 17 00:00:00 2001 From: Oleg Nikitin Date: Tue, 29 Apr 2025 17:55:51 +0300 Subject: [PATCH] add dataflow solvation --- src/PrivateAnalyzer/private_arrays_search.cpp | 67 +++++++++++++++++-- src/PrivateAnalyzer/private_arrays_search.h | 3 +- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index 17bd679..f8ab229 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -464,10 +464,12 @@ void AccessingSet::Insert(const vector& element) allElements.insert(allElements.end(), tails.begin(), tails.end()); } -void AccessingSet::Union(const AccessingSet& source) { +AccessingSet AccessingSet::Union(const AccessingSet& source) { + AccessingSet result; for(auto& element: source.GetElements()) { - Insert(element); + result.Insert(element); } + return result; } AccessingSet AccessingSet::Intersect(const AccessingSet& secondSet) const @@ -506,6 +508,27 @@ AccessingSet AccessingSet::Diff(const AccessingSet& secondSet) const 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 false; + } + } + } + return true; +} + void Collapse(Region* region) { //Region* newBlock = new Region(); @@ -514,7 +537,7 @@ void Collapse(Region* region) for (Region* byBlock : region->getBasickBlocks()) { AccessingSet intersection = byBlock->array_def[arrayName].Intersect(arrayRanges); - region->array_def[arrayName].Union(intersection); + region->array_def[arrayName] = region->array_def[arrayName].Union(intersection); } } @@ -522,7 +545,7 @@ void Collapse(Region* region) for (auto& [arrayName, arrayRanges] : byBlock->array_use) { AccessingSet diff = byBlock->array_use[arrayName].Diff(byBlock->array_in[arrayName]); - region->array_use[arrayName].Union(diff); + region->array_use[arrayName] = region->array_use[arrayName].Union(diff); } } @@ -580,6 +603,7 @@ Region::Region(LoopGraph* loop, vector& Blocks) { bbToRegion[poiner] = new Region(*poiner); } + this->header = bbToRegion[header]; SetConnections(bbToRegion, blockSet); //create subRegions for (LoopGraph* childLoop : loop->children) @@ -588,9 +612,42 @@ Region::Region(LoopGraph* loop, vector& Blocks) } } +void SolveDataFlowIteratively(Region* DFG) +{ + unordered_set worklist(DFG->getBasickBlocks()); + do + { + Region* b = *worklist.begin(); + ArrayAccessingIndexes newIn; + for (Region* prevBlock : b->getPrevRegions()) + { + for (const auto& [arrayName, accessSet] : prevBlock->array_out) + { + newIn[arrayName] = newIn[arrayName].Intersect(accessSet); + } + } + b->array_in = newIn; + ArrayAccessingIndexes newOut; + for (auto& [arrayName, accessSet] : b->array_in) + { + newOut[arrayName] = b->array_in[arrayName].Union(b->array_def[arrayName]); + } + /* can not differ */ + if (newOut != b->array_out) + { + b->array_out = newOut; + } + else + { + worklist.erase(b); + } + } + while (!worklist.empty()); +} + void SolveDataFlow(Region* DFG) { - //SolveDataFlowIteratively(DFG) + SolveDataFlowIteratively(DFG); for (Region* subRegion : DFG->getSubRegions()) { SolveDataFlow(subRegion); diff --git a/src/PrivateAnalyzer/private_arrays_search.h b/src/PrivateAnalyzer/private_arrays_search.h index 9a5aa49..f8508f3 100644 --- a/src/PrivateAnalyzer/private_arrays_search.h +++ b/src/PrivateAnalyzer/private_arrays_search.h @@ -24,12 +24,13 @@ class AccessingSet { AccessingSet() {}; vector> GetElements() const; void Insert(const vector& element); - void Union(const AccessingSet& source); + AccessingSet Union(const AccessingSet& source); AccessingSet Intersect(const AccessingSet& secondSet) const; AccessingSet Diff(const AccessingSet& secondSet) const; bool ContainsElement(const vector& element) const; void FindCoveredBy(const vector& element, vector>& result) const; void FindUncovered(const vector& element, vector>& result) const; + friend bool operator==(const AccessingSet& lhs, const AccessingSet& rhs); }; using ArrayAccessingIndexes = map;