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();
}
}
}