add restore pass
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <set>
|
||||
|
||||
#include "range_structures.h"
|
||||
#include "graph_loops.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user