fix algorythm

This commit is contained in:
2026-02-21 02:34:57 +03:00
parent 80a1fecb1c
commit 42044b60f1
4 changed files with 365 additions and 88 deletions

View File

@@ -1,14 +1,16 @@
#include<vector>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<string>
#include <algorithm>
#include <vector>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <numeric>
#include <iostream>
#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<string, LoopGraph*>& loopForIndex, LoopGraph* loo
static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, LoopGraph*>& loopForIndex) {
unordered_set<SAPFOR::Argument*> 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, map<string, Loop
return "";
}
static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use) {
static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use, Region* region) {
auto instructions = block->getInstructions();
map<string, LoopGraph*> 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<SAPFOR::Argument*> index_vars;
vector<int> 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<pair<int, int>> coeffsForDims;
int subs = ref->numberOfSubscripts();
for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i)
{
const vector<int*>& coeffs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
if (coeffs.size() == 1)
{
const pair<int, int> 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<SAPFOR::BasicBlock*>& blockSet, unordered_map<SAPFOR::BasicBlock*, Region*>& 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<Region*>& result, unordered_set<Region*> cycleBlocks)
{
for (Region* nextBlock : block->getNextRegions())
{
if (cycleBlocks.find(nextBlock) != cycleBlocks.end())
DFS(nextBlock, result, cycleBlocks);
}
result.push_back(block);
}
void TopologySort(std::vector<Region*>& basikBlocks, Region* header)
{
vector<Region*> result;
unordered_set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end());
DFS(header, result, cycleBlocks);
reverse(result.begin(), result.end());
basikBlocks = result;
}
static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet)
{
for (SAPFOR::BasicBlock* block : blockSet)
@@ -215,25 +285,26 @@ static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& 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<SAPFOR::BasicBlock*>& Blocks, const unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, unordered_map<SAPFOR::BasicBlock*, Region*>& 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 vector<SAPFOR::BasicBlock*
continue;
region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion));
}
TopologySort(region->getBasickBlocks(), region->getHeader());
return region;
}
@@ -254,12 +326,13 @@ Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& 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<SAPFOR::BasicBlock*>& Blocks)
continue;
subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion));
}
}
TopologySort(basickBlocks, this->header);
}