add restore pass

This commit is contained in:
2026-04-27 16:18:43 +03:00
parent fe7e3449e8
commit 5f25567a14
13 changed files with 470 additions and 278 deletions

View File

@@ -1,36 +1,34 @@
#include <algorithm>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <set>
#include <vector>
#include <queue>
#include <numeric>
#include <iostream>
#include "ArrayConstantPropagation/propagation.h"
#include "CFGraph/CFGraph.h"
#include "Distribution/Array.h"
#include "errors.h"
#include "graph_loops.h"
#include "private_arrays_search.h"
#include "range_structures.h"
#include "region.h"
#include "SgUtils.h"
#include "Transformations/ArrayConstantPropagation/propagation.h"
#include "utils.h"
#include "Utils/AstWrapper.h"
using namespace std;
extern std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays;
extern map<string, vector<Messages>> SPF_messages;
extern unordered_set<SgStatement*> statementsToRemove;
extern unordered_map<string, vector<pair<SgStatement*, SgStatement*>>> expToChange;
static unordered_set<Region*> collapsed;
static set<Region*> collapsed;
static void RemoveEmptyPoints(ArrayAccessingIndexes& container)
{
ArrayAccessingIndexes resultContainer;
unordered_set<string> toRemove;
set<string> toRemove;
for (auto& [arrayName, accessingSet] : container)
{
@@ -60,6 +58,7 @@ static void Collapse(Region* region)
return;
bool firstRegion = true;
int blockCount = 0;
for (Region* basickBlock : region->getBasickBlocks())
{
if (basickBlock->getNextRegions().empty())
@@ -71,7 +70,7 @@ static void Collapse(Region* region)
}
else
{
unordered_set<string> toErease;
set<string> toErease;
for (auto& [arrayName, arrayRanges] : region->array_def)
{
if (basickBlock->array_out.find(arrayName) != basickBlock->array_out.end())
@@ -91,11 +90,15 @@ static void Collapse(Region* region)
RegionInstruction instruction;
instruction.def = move(region->array_def);
ArrayAccessingIndexes recursivePriv;
for (auto& byBlock : region->getBasickBlocks())
{
if (!byBlock->array_priv.empty())
recursivePriv = byBlock->array_priv;
for (auto& instruction : byBlock->instructions)
{
if (!instruction.def.empty() || !instruction.use.empty())
blockCount++;
for (auto& [arrayName, _] : instruction.use)
{
AccessingSet diff = instruction.use[arrayName].Diff(instruction.in[arrayName]);
@@ -127,67 +130,8 @@ static void Collapse(Region* region)
region->addNextRegion(nextBlock);
}
region->instructions.push_back(instruction);
}
static void SolveDataFlowIteratively(Region* DFG)
{
auto blocks = DFG->getBasickBlocks();
std::unordered_set<Region*> worklist(blocks.begin(), blocks.end());
do
{
Region* b = *worklist.begin();
ArrayAccessingIndexes newIn;
bool flagFirst = true;
for (Region* prevBlock : b->getPrevRegions())
{
if (flagFirst)
{
newIn = prevBlock->array_out;
flagFirst = false;
}
else
{
if (prevBlock->array_out.empty())
{
newIn.clear();
break;
}
for (const auto& [arrayName, accessSet] : prevBlock->array_out)
{
if (newIn.find(arrayName) != newIn.end())
newIn[arrayName] = newIn[arrayName].Intersect(accessSet);
else
newIn[arrayName] = AccessingSet();
}
}
}
b->array_in = move(newIn);
ArrayAccessingIndexes newOut;
if (b->array_def.empty())
newOut = b->array_in;
else if (b->array_in.empty())
newOut = b->array_def;
else
{
for (auto& [arrayName, accessSet] : b->array_def)
{
if (newOut.find(arrayName) != newOut.end())
newOut[arrayName] = b->array_def[arrayName].Union(b->array_in[arrayName]);
else
newOut[arrayName] = accessSet;
}
}
/* can not differ */
if (newOut != b->array_out)
b->array_out = newOut;
else
worklist.erase(b);
} while (!worklist.empty());
if (blockCount == 1 && !recursivePriv.empty())
region->array_priv = move(recursivePriv);
}
static void SolveForBasickBlock(Region* block)
@@ -380,11 +324,26 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes&
spfStat->setFileName(loop->loop->fileName());
SgExpression* toAdd = new SgExpression(EXPR_LIST, new SgExpression(ACC_PRIVATE_OP), NULL, NULL);
set<SgSymbol*> arraysToInsert;
std::cout << "First bp\n";
for (const auto& [_, accessingSet] : privates)
for (const auto& [arrayName, accessingSet] : privates)
{
int idx = arrayName.find('%');
string name = (idx != -1 ? arrayName.substr(idx+1) : arrayName);
if (!CheckDimensionLength(accessingSet))
{
wstring messageE, messageR;
__spf_printToLongBuf(
messageE,
L"Private array '%s' was skipped because dimension lengths are inconsistent",
to_wstring(name).c_str());
__spf_printToLongBuf(
messageR,
R159,
to_wstring("array " + name + " has inconsistent dimension lengths").c_str());
SPF_messages[loop->loop->fileName()].push_back(
Messages(WARR, loop->loop->lineNumber(), messageR, messageE, 1029));
continue;
}
for (const auto& arrayElement : accessingSet.GetElements())
{
if (arrayElement.empty())
@@ -462,20 +421,4 @@ void findPrivateArrays(map<string, vector<LoopGraph*>>& loopGraph, map<FuncInfo*
AddPrivateArraysToLoop(loop, result[loop], insertedPrivates);
}
}
for (SgStatement* st : statementsToRemove)
{
SgFile::switchToFile(st->fileName());
st->deleteStmt();
}
for (auto& [filename, statements] : expToChange)
{
SgFile::switchToFile(filename);
for (auto& [statement, statementCopy] : statements)
{
statement->insertStmtBefore(*statementCopy, *statement->controlParent());
statement->deleteStmt();
}
}
}

View File

@@ -3,7 +3,7 @@
#include <vector>
#include <map>
#include <set>
#include <unordered_set>
#include <set>
#include "range_structures.h"
#include "graph_loops.h"

View File

@@ -1,6 +1,6 @@
#include <vector>
#include <map>
#include <unordered_set>
#include <set>
#include <string>
#include "utils.h"

View File

@@ -2,7 +2,7 @@
#include <vector>
#include <map>
#include <unordered_set>
#include <set>
#include <string>
#include <cstdint>

View File

@@ -1,8 +1,8 @@
#include <algorithm>
#include <vector>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <set>
#include <map>
#include <string>
#include <numeric>
#include <iostream>
@@ -23,9 +23,9 @@ static bool isParentStmt(SgStatement* stmt, SgStatement* parent)
}
/*returns head block and loop*/
static pair<SAPFOR::BasicBlock*, unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const vector<SAPFOR::BasicBlock*> blocks)
pair<SAPFOR::BasicBlock*, set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const vector<SAPFOR::BasicBlock*> blocks)
{
unordered_set<SAPFOR::BasicBlock*> block_loop;
set<SAPFOR::BasicBlock*> block_loop;
SAPFOR::BasicBlock* head_block = nullptr;
auto loop_operator = loop->loop->GetOriginal();
for (const auto& block : blocks)
@@ -51,16 +51,16 @@ static pair<SAPFOR::BasicBlock*, unordered_set<SAPFOR::BasicBlock*>> GetBasicBlo
return { head_block, block_loop };
}
static void BuildLoopIndex(map<string, LoopGraph*>& loopForIndex, LoopGraph* loop) {
static void BuildLoopIndex(map<SgStatement*, LoopGraph*>& loopForIndex, LoopGraph* loop) {
string index = loop->loopSymbol();
loopForIndex[index] = loop;
loopForIndex[loop->loop->GetOriginal()] = loop;
for (const auto& childLoop : loop->children)
BuildLoopIndex(loopForIndex, childLoop);
}
static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, LoopGraph*>& loopForIndex) {
unordered_set<SAPFOR::Argument*> args = { block->getInstructions()[pos]->getInstruction()->getArg1() };
set<SAPFOR::Argument*> args = { block->getInstructions()[pos]->getInstruction()->getArg1() };
for (int i = pos - 1; i >= 0; i--)
{
@@ -95,7 +95,7 @@ static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, Loop
static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use, Region* region) {
auto instructions = block->getInstructions();
map<string, LoopGraph*> loopForIndex;
map<SgStatement*, LoopGraph*> loopForIndex;
BuildLoopIndex(loopForIndex, loop);
for (int i = 0; i < instructions.size(); i++)
{
@@ -136,7 +136,6 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
vector<SAPFOR::Argument*> index_vars;
vector<int> refPos;
string array_name = instruction->getInstruction()->getArg1()->getValue();
int j = i - 1;
while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF)
{
@@ -180,25 +179,16 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
string name, full_name = var->getValue();
int pos = full_name.find('%');
LoopGraph* currentLoop;
if (pos != -1)
{
name = full_name.substr(pos + 1);
if (loopForIndex.find(name) != loopForIndex.end())
currentLoop = loopForIndex[name];
else
return -1;
}
else
{
name = FindIndexName(currentVarPos, block, loopForIndex);
if (name == "")
return -1;
if (loopForIndex.find(name) != loopForIndex.end())
currentLoop = loopForIndex[name];
else
return -1;
}
auto serachInstr = instruction->getInstruction()->getOperator();
while (serachInstr && serachInstr->variant() != FOR_NODE)
serachInstr = serachInstr->controlParent();
name = full_name.substr(pos + 1);
if (loopForIndex.find(serachInstr) != loopForIndex.end())
currentLoop = loopForIndex[serachInstr];
else
return -1;
uint64_t start = coeffsForDims.back().second * currentLoop->startVal + coeffsForDims.back().first;
uint64_t step = currentLoop->stepVal;
@@ -243,7 +233,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
}
static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const unordered_set<SAPFOR::BasicBlock*>& blockSet, unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const set<SAPFOR::BasicBlock*>& blockSet, map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
{
for (SAPFOR::BasicBlock* block : blockSet)
{
@@ -259,18 +249,35 @@ static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const unordered_s
}
}
static void DFS(Region* block, vector<Region*>& result, unordered_set<Region*> cycleBlocks)
static bool DFS(Region* block,
vector<Region*>& result,
const set<Region*>& cycleBlocks,
map<Region*, int>& color)
{
auto it = color.find(block);
if (it != color.end())
{
if (it->second == 0)
return false;
if (it->second == 1)
return true;
}
color[block] = 0;
for (Region* nextBlock : block->getNextRegions())
{
if (cycleBlocks.find(nextBlock) != cycleBlocks.end())
DFS(nextBlock, result, cycleBlocks);
if (cycleBlocks.find(nextBlock) == cycleBlocks.end())
continue;
if (!DFS(nextBlock, result, cycleBlocks, color))
return false;
}
color[block] = 1;
result.push_back(block);
return true;
}
bool HasCycle(Region* block, const std::unordered_set<Region*>& cycleBlocks, std::unordered_set<Region*>& visitedBlocks)
bool HasCycle(Region* block, const std::set<Region*>& cycleBlocks, std::set<Region*>& visitedBlocks)
{
return false;
if (visitedBlocks.find(block) != visitedBlocks.end())
return true;
visitedBlocks.insert(block);
@@ -284,18 +291,17 @@ bool HasCycle(Region* block, const std::unordered_set<Region*>& cycleBlocks, std
bool TopologySort(std::vector<Region*>& basikBlocks, Region* header)
{
unordered_set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end());
unordered_set<Region*> visitedBlocks;
if (HasCycle(header, cycleBlocks, visitedBlocks))
return false;
set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end());
vector<Region*> result;
DFS(header, result, cycleBlocks);
map<Region*, int> color;
if (!DFS(header, result, cycleBlocks, color))
return false;
reverse(result.begin(), result.end());
basikBlocks = move(result);
return true;
}
static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet)
static void SetConnections(map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const set<SAPFOR::BasicBlock*>& blockSet)
{
for (SAPFOR::BasicBlock* block : blockSet)
{
@@ -309,7 +315,7 @@ static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegi
}
}
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
{
Region* region = new Region;
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks);
@@ -340,7 +346,7 @@ static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*
Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks)
{
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks);
unordered_map<SAPFOR::BasicBlock*, Region*> bbToRegion;
map<SAPFOR::BasicBlock*, Region*> bbToRegion;
for (auto poiner : blockSet)
{
bbToRegion[poiner] = new Region(*poiner);

View File

@@ -2,7 +2,7 @@
#include <vector>
#include <map>
#include <unordered_set>
#include <set>
#include <string>
#include "graph_loops.h"
@@ -29,9 +29,9 @@ public:
void addBasickBlocks(Region* region) { basickBlocks.push_back(region); }
const std::unordered_set<Region*>& getPrevRegions() { return prevRegions; }
const std::set<Region*>& getPrevRegions() { return prevRegions; }
std::unordered_set<Region*>& getNextRegions() { return nextRegions; }
std::set<Region*>& getNextRegions() { return nextRegions; }
void removeNextRegion(Region* region)
{
@@ -61,7 +61,7 @@ public:
nextRegions.insert(source);
}
std::unordered_set<Region*> getSubRegions() { return subRegions; }
std::set<Region*> getSubRegions() { return subRegions; }
void addSubRegions(Region* region) { subRegions.insert(region); }
@@ -71,14 +71,14 @@ public:
private:
std::vector<Region*> basickBlocks;
std::unordered_set<Region*> subRegions;
std::set<Region*> subRegions;
/*next Region which is BB for current BB Region*/
std::unordered_set<Region*> nextRegions;
std::set<Region*> nextRegions;
/*prev Regions which is BBs for current BB Region*/
std::unordered_set<Region*> prevRegions;
std::set<Region*> prevRegions;
Region* header;
};
bool HasCycle(Region* block, const std::unordered_set<Region*>& cycleBlocks, std::unordered_set<Region*>& visitedBlocks);
bool HasCycle(Region* block, const std::set<Region*>& cycleBlocks, std::set<Region*>& visitedBlocks);
bool TopologySort(std::vector<Region*>& basikBlocks, Region* header);