Merge pull request 'egormayorov' (#78) from egormayorov into master

This commit was merged in pull request #78.
This commit is contained in:
2026-03-27 08:29:34 +03:00
4 changed files with 118 additions and 87 deletions

View File

@@ -1,4 +1,4 @@
#include "Utils/leak_detector.h"
#include "Utils/leak_detector.h"
#pragma comment(linker, "/STACK:536870912") // 512 МБ
@@ -943,7 +943,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
}
}
else if (curr_regime == MOVE_OPERATORS)
moveOperators(file, loopGraph, fullIR, countOfTransform);
moveOperators(file, fullIR, countOfTransform);
else if (curr_regime == PRIVATE_REMOVING_ANALYSIS)
{
auto itFound = loopGraph.find(file->filename());

View File

@@ -17,7 +17,6 @@
using namespace std;
set<int> loop_tags = {FOR_NODE};
set<int> control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE};
set<int> control_end_tags = {CONTROL_END};
@@ -53,13 +52,25 @@ static vector<SAPFOR::IR_Block*> findInstructionsFromStatement(SgStatement* st,
vector<SAPFOR::BasicBlock*> findFuncBlocksByFuncStatement(SgStatement *st, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) {
vector<SAPFOR::BasicBlock*> result;
if (!st)
return result;
Statement* forSt = (Statement*)st;
const string stmtFile = st->fileName();
const int stmtLine = st->lineNumber();
for (auto& func: FullIR) {
if (func.first->funcPointer->getCurrProcessFile() == forSt->getCurrProcessFile()
&& func.first->funcPointer->lineNumber() == forSt->lineNumber())
if (!func.first || !func.first->funcPointer)
continue;
const string funcFile = func.first->fileName;
const int funcLine = func.first->funcPointer->lineNumber();
// Important: select CFG blocks only for the same file and function header.
if (funcFile == stmtFile && funcLine == stmtLine)
{
result = func.second;
break;
}
}
return result;
@@ -160,40 +171,60 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
if (!instr)
return string();
SgExpression* ex = instr->getExpression();
if (!ex || !ex->unparse())
if (!ex)
return string();
auto normalizeExprText = [](const string& raw) -> string
{
string t;
t.reserve(raw.size());
for (unsigned char c : raw)
if (!std::isspace(c))
t.push_back((char)c);
auto stripOneLayer = [](const string& x) -> string
auto exprKey = [&](auto&& self, SgExpression* e) -> string
{
if (!e)
return string("_");
if (auto* ar = isSgArrayRefExp(e))
{
if (x.size() < 2 || x.front() != '(' || x.back() != ')')
return x;
int bal = 0;
for (size_t i = 0; i + 1 < x.size(); ++i)
SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr;
string key = string("A(") + (sym ? sym->identifier() : "?");
const int n = ar->numberOfSubscripts();
for (int i = 0; i < n; ++i)
{
if (x[i] == '(') bal++;
else if (x[i] == ')') bal--;
if (bal == 0 && i + 1 < x.size() - 1)
return x;
key += ",";
key += self(self, ar->subscript(i));
}
return x.substr(1, x.size() - 2);
};
while (true)
{
const string stripped = stripOneLayer(t);
if (stripped == t)
break;
t = stripped;
key += ")";
return key;
}
return t;
if (e->variant() == VAR_REF || e->variant() == CONST_REF)
{
SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr;
return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")";
}
if (auto* v = isSgValueExp(e))
{
if (e->variant() == INT_VAL)
return string("I(") + to_string(v->intValue()) + ")";
if (e->variant() == BOOL_VAL)
return string("B(") + (v->boolValue() ? "1" : "0") + ")";
if (e->variant() == CHAR_VAL)
return string("CH(") + string(1, v->charValue()) + ")";
if (e->variant() == FLOAT_VAL)
return string("F(") + (v->floatValue() ? v->floatValue() : "") + ")";
if (e->variant() == DOUBLE_VAL)
return string("D(") + (v->doubleValue() ? v->doubleValue() : "") + ")";
if (e->variant() == STRING_VAL)
return string("S(") + (v->stringValue() ? v->stringValue() : "") + ")";
}
string key = string("N(") + to_string(e->variant());
if (e->lhs())
key += ",L=" + self(self, e->lhs());
if (e->rhs())
key += ",R=" + self(self, e->rhs());
key += ")";
return key;
};
return "MEMEX#" + normalizeExprText(ex->unparse());
return "MEMEX#" + exprKey(exprKey, ex);
};
auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool
@@ -296,6 +327,9 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
addDep(instr->getArg1());
addDep(instr->getArg2());
if (instr->getOperation() == SAPFOR::CFG_OP::RANGE)
addDep(instr->getResult());
if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)
addDep(instr->getResult());
@@ -343,7 +377,7 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
return result;
}
static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const char* expectedFile)
{
if (!bb)
return false;
@@ -373,6 +407,18 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
if (ops.size() < 2)
return false;
// Check that analyzed BB is in the same file as the expected file
const char* bbFile = ops.front()->fileName();
if (!bbFile)
bbFile = "(unknown)";
if (expectedFile && strcmp(expectedFile, bbFile) != 0)
return false;
for (auto* st : ops)
{
if (!st || !st->fileName() || strcmp(st->fileName(), bbFile) != 0)
return false;
}
SgStatement* parent = ops.front()->controlParent();
if (!parent)
return false;
@@ -425,59 +471,45 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
const auto depsMap = analyzeBasicBlockIntraDependencies(bb);
vector<SgStatement*> order = ops;
auto buildPos = [&](const vector<SgStatement*>& v)
auto indexIn = [](const vector<SgStatement*>& v, SgStatement* s) -> int
{
map<SgStatement*, int> pos;
for (int i = 0; i < (int)v.size(); ++i)
pos[v[i]] = i;
return pos;
if (v[i] == s)
return i;
return -1;
};
const int maxIterations = (int)order.size() * (int)order.size() + 10;
bool anyMove = false;
for (int iter = 0; iter < maxIterations; ++iter)
for (SgStatement* s : ops)
{
bool movedThisIter = false;
const auto pos = buildPos(order);
auto itDeps = depsMap.find(s);
if (itDeps == depsMap.end() || itDeps->second.empty())
continue;
for (int i = 0; i < (int)order.size(); ++i)
int posS = indexIn(order, s);
if (posS < 0)
continue;
int lastDepIdx = -1;
for (SgStatement* dep : itDeps->second)
{
SgStatement* curSt = order[i];
auto it = depsMap.find(curSt);
if (it == depsMap.end() || it->second.empty())
continue;
int lastDepIdx = -1;
for (SgStatement* dep : it->second)
{
auto itP = pos.find(dep);
if (itP != pos.end())
lastDepIdx = max(lastDepIdx, itP->second);
}
if (lastDepIdx < 0)
continue;
int target = lastDepIdx + 1;
if (target == i)
continue;
SgStatement* moved = order[i];
order.erase(order.begin() + i);
if (target > i)
target -= 1;
if (target < 0)
target = 0;
if (target > (int)order.size())
target = (int)order.size();
order.insert(order.begin() + target, moved);
movedThisIter = true;
anyMove = true;
break;
const int j = indexIn(order, dep);
if (j >= 0)
lastDepIdx = max(lastDepIdx, j);
}
if (lastDepIdx < 0)
continue;
if (!movedThisIter)
break;
if (posS == lastDepIdx + 1)
continue;
order.erase(order.begin() + posS);
int lp = lastDepIdx;
if (posS < lastDepIdx)
lp = lastDepIdx - 1;
const int insertAt = lp + 1;
order.insert(order.begin() + insertAt, s);
}
bool changed = false;
@@ -548,15 +580,14 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
return true;
}
void moveOperators(SgFile *file, map<string, vector<LoopGraph*>>& loopGraph,
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR,
int& countOfTransform) {
void moveOperators(SgFile* file, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform) {
if (!file)
return;
if (SgFile::switchToFile(file->filename()) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i) {
for (int i = 0; i < funcNum; ++i)
{
SgStatement* st = file->functions(i);
const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR);
@@ -564,8 +595,8 @@ void moveOperators(SgFile *file, map<string, vector<LoopGraph*>>& loopGraph,
{
if (!bb)
continue;
if (reorderOperatorsInBasicBlockUsingDeps(bb))
if (reorderOperatorsInBasicBlockUsingDeps(bb, file->filename()))
countOfTransform += 1;
}
}
}
}

View File

@@ -3,4 +3,4 @@
#include "../../GraphLoop/graph_loops.h"
#include "../../CFGraph/CFGraph.h"
void moveOperators(SgFile *file, std::map<std::string, std::vector<LoopGraph*>>& loopGraph, const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform);
void moveOperators(SgFile* file, const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform);

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2471"
#define VERSION_SPF "2472"