3 Commits

Author SHA1 Message Date
ALEXks
746bdf29b2 Merge branch 'master' into egormayorov 2026-03-20 15:33:38 +03:00
ALEXks
16f0560c8e updated 2026-03-20 15:33:33 +03:00
Egor Mayorov
8cae169131 Add swith to file usage 2026-03-18 00:44:22 +03:00
5 changed files with 111 additions and 149 deletions

View File

@@ -1,4 +1,4 @@
#include "Utils/leak_detector.h" #include "Utils/leak_detector.h"
#pragma comment(linker, "/STACK:536870912") // 512 МБ #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) else if (curr_regime == MOVE_OPERATORS)
moveOperators(file, fullIR, countOfTransform); moveOperators(file, loopGraph, fullIR, countOfTransform);
else if (curr_regime == PRIVATE_REMOVING_ANALYSIS) else if (curr_regime == PRIVATE_REMOVING_ANALYSIS)
{ {
auto itFound = loopGraph.find(file->filename()); auto itFound = loopGraph.find(file->filename());

View File

@@ -17,6 +17,10 @@
using namespace std; using namespace std;
// Provided by Sage runtime (declared in libSage++.h)
extern SgFile *current_file;
set<int> loop_tags = {FOR_NODE}; set<int> loop_tags = {FOR_NODE};
set<int> control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; set<int> control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE};
set<int> control_end_tags = {CONTROL_END}; set<int> control_end_tags = {CONTROL_END};
@@ -52,25 +56,13 @@ static vector<SAPFOR::IR_Block*> findInstructionsFromStatement(SgStatement* st,
vector<SAPFOR::BasicBlock*> findFuncBlocksByFuncStatement(SgStatement *st, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) { vector<SAPFOR::BasicBlock*> findFuncBlocksByFuncStatement(SgStatement *st, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) {
vector<SAPFOR::BasicBlock*> result; vector<SAPFOR::BasicBlock*> result;
if (!st)
return result;
Statement* forSt = (Statement*)st; Statement* forSt = (Statement*)st;
const string stmtFile = st->fileName();
const int stmtLine = st->lineNumber();
for (auto& func: FullIR) { for (auto& func: FullIR) {
if (!func.first || !func.first->funcPointer) if (func.first->funcPointer->getCurrProcessFile() == forSt->getCurrProcessFile()
continue; && func.first->funcPointer->lineNumber() == forSt->lineNumber())
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; result = func.second;
break;
} }
} }
return result; return result;
@@ -171,60 +163,40 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
if (!instr) if (!instr)
return string(); return string();
SgExpression* ex = instr->getExpression(); SgExpression* ex = instr->getExpression();
if (!ex) if (!ex || !ex->unparse())
return string(); 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 exprKey = [&](auto&& self, SgExpression* e) -> string auto stripOneLayer = [](const string& x) -> string
{ {
if (!e) if (x.size() < 2 || x.front() != '(' || x.back() != ')')
return string("_"); return x;
int bal = 0;
if (auto* ar = isSgArrayRefExp(e)) for (size_t i = 0; i + 1 < x.size(); ++i)
{ {
SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr; if (x[i] == '(') bal++;
string key = string("A(") + (sym ? sym->identifier() : "?"); else if (x[i] == ')') bal--;
const int n = ar->numberOfSubscripts(); if (bal == 0 && i + 1 < x.size() - 1)
for (int i = 0; i < n; ++i) return x;
{
key += ",";
key += self(self, ar->subscript(i));
} }
key += ")"; return x.substr(1, x.size() - 2);
return key;
}
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;
}; };
while (true)
return "MEMEX#" + exprKey(exprKey, ex); {
const string stripped = stripOneLayer(t);
if (stripped == t)
break;
t = stripped;
}
return t;
};
return "MEMEX#" + normalizeExprText(ex->unparse());
}; };
auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool
@@ -327,9 +299,6 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
addDep(instr->getArg1()); addDep(instr->getArg1());
addDep(instr->getArg2()); 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) if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)
addDep(instr->getResult()); addDep(instr->getResult());
@@ -377,7 +346,7 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
return result; return result;
} }
static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const char* expectedFile) static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
{ {
if (!bb) if (!bb)
return false; return false;
@@ -407,18 +376,6 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const
if (ops.size() < 2) if (ops.size() < 2)
return false; 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(); SgStatement* parent = ops.front()->controlParent();
if (!parent) if (!parent)
return false; return false;
@@ -470,70 +427,60 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const
// as close as possible after its last dependency (if any). // as close as possible after its last dependency (if any).
const auto depsMap = analyzeBasicBlockIntraDependencies(bb); const auto depsMap = analyzeBasicBlockIntraDependencies(bb);
vector<SgStatement*> order = ops; vector<SgStatement*> order = ops;
const vector<SgStatement*> originalOrder = ops;
const int nOrig = (int)originalOrder.size();
auto indexIn = [](const vector<SgStatement*>& v, SgStatement* s) -> int auto buildPos = [&](const vector<SgStatement*>& v)
{ {
map<SgStatement*, int> pos;
for (int i = 0; i < (int)v.size(); ++i) for (int i = 0; i < (int)v.size(); ++i)
if (v[i] == s) pos[v[i]] = i;
return i; return pos;
return -1;
}; };
auto indexInOriginal = [&](SgStatement* s) -> int const int maxIterations = (int)order.size() * (int)order.size() + 10;
bool anyMove = false;
for (int iter = 0; iter < maxIterations; ++iter)
{ {
return indexIn(originalOrder, s); bool movedThisIter = false;
}; const auto pos = buildPos(order);
for (SgStatement* s : ops) for (int i = 0; i < (int)order.size(); ++i)
{ {
auto itDeps = depsMap.find(s); SgStatement* curSt = order[i];
if (itDeps == depsMap.end() || itDeps->second.empty()) auto it = depsMap.find(curSt);
if (it == depsMap.end() || it->second.empty())
continue; continue;
int lastDepOrigIdx = -1; int lastDepIdx = -1;
for (SgStatement* dep : itDeps->second) for (SgStatement* dep : it->second)
{ {
const int j = indexInOriginal(dep); auto itP = pos.find(dep);
if (j >= 0) if (itP != pos.end())
lastDepOrigIdx = max(lastDepOrigIdx, j); lastDepIdx = max(lastDepIdx, itP->second);
} }
if (lastDepOrigIdx < 0) if (lastDepIdx < 0)
continue; continue;
SgStatement* successor = nullptr; int target = lastDepIdx + 1;
if (lastDepOrigIdx + 1 < nOrig) if (target == i)
successor = originalOrder[lastDepOrigIdx + 1];
int posS = indexIn(order, s);
if (posS < 0)
continue; continue;
if (successor == nullptr) SgStatement* moved = order[i];
{ order.erase(order.begin() + i);
if (posS == (int)order.size() - 1) if (target > i)
continue; target -= 1;
order.erase(order.begin() + posS); if (target < 0)
order.push_back(s); target = 0;
continue; if (target > (int)order.size())
target = (int)order.size();
order.insert(order.begin() + target, moved);
movedThisIter = true;
anyMove = true;
break;
} }
if (successor == s) if (!movedThisIter)
continue; break;
const int posSucc = indexIn(order, successor);
if (posSucc < 0)
continue;
if (posS + 1 == posSucc)
continue;
order.erase(order.begin() + posS);
const int posSucc2 = indexIn(order, successor);
if (posSucc2 < 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
order.insert(order.begin() + posSucc2, s);
} }
bool changed = false; bool changed = false;
@@ -604,23 +551,38 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const
return true; return true;
} }
void moveOperators(SgFile* file, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform) { void moveOperators(SgFile *file, map<string, vector<LoopGraph*>>& loopGraph,
if (!file) const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR,
return; int& countOfTransform) {
if (SgFile::switchToFile(file->filename()) == -1) // Correct usage pattern in this project:
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); // save current file -> switch -> work on current_file -> restore.
const int funcNum = file->numberOfFunctions(); const string oldFileName = (current_file ? current_file->filename() : "");
for (const auto& [fileName, _] : loopGraph)
{
if (SgFile::switchToFile(fileName.c_str()) == -1)
continue;
SgFile* curFile = current_file;
if (!curFile)
continue;
const int funcNum = curFile->numberOfFunctions();
for (int i = 0; i < funcNum; ++i) for (int i = 0; i < funcNum; ++i)
{ {
SgStatement* st = file->functions(i); SgStatement* st = curFile->functions(i);
const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR); const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR);
for (auto* bb : loopBlocks) for (auto* bb : loopBlocks)
{ {
if (!bb) if (!bb)
continue; continue;
if (reorderOperatorsInBasicBlockUsingDeps(bb, file->filename())) if (reorderOperatorsInBasicBlockUsingDeps(bb))
countOfTransform += 1; countOfTransform += 1;
} }
} }
} }
if (!oldFileName.empty())
SgFile::switchToFile(oldFileName.c_str());
}

View File

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

View File

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