dependencies from func calls

This commit is contained in:
Egor Mayorov
2026-05-06 19:49:54 +03:00
parent 4d9c01bdab
commit d5eeceef9e
5 changed files with 152 additions and 6 deletions

View File

@@ -944,7 +944,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, fullIR, allFuncInfo, 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

@@ -2319,3 +2319,16 @@ static bool isIntrincis(const string& name)
return true; return true;
return false; return false;
} }
bool isPureIntrinsic(const string& name)
{
if (!isIntrincis(name))
return false;
static const set<string> intrinsicsThatMayWriteActualArgs = {
"cpu_time",
"etime",
"random_number",
};
return intrinsicsThatMayWriteActualArgs.find(name) == intrinsicsThatMayWriteActualArgs.end();
}

View File

@@ -2,6 +2,8 @@
void insertIntrinsicStat(const std::vector<FuncInfo*>& allFuncInfo); void insertIntrinsicStat(const std::vector<FuncInfo*>& allFuncInfo);
bool isPureIntrinsic(const std::string& name);
bool checkOutCalls(const std::set<std::string>& outCalls); bool checkOutCalls(const std::set<std::string>& outCalls);
std::map<SgStatement*, std::set<std::string>> fillFromIntent(SgStatement* header); std::map<SgStatement*, std::set<std::string>> fillFromIntent(SgStatement* header);
void intentInsert(const std::vector<FuncInfo*>& allFuncInfo); void intentInsert(const std::vector<FuncInfo*>& allFuncInfo);

View File

@@ -10,8 +10,10 @@
#include "../../Utils/errors.h" #include "../../Utils/errors.h"
#include "../../Utils/SgUtils.h" #include "../../Utils/SgUtils.h"
#include "../../GraphCall/graph_calls.h" #include "../../GraphCall/graph_calls.h"
#include "../../GraphCall/graph_calls_func.h"
#include "../../CFGraph/CFGraph.h" #include "../../CFGraph/CFGraph.h"
#include "../../CFGraph/IR.h" #include "../../CFGraph/IR.h"
#include "../FunctionPurifying/function_purifying.h"
#include "move_operators.h" #include "move_operators.h"
using namespace std; using namespace std;
@@ -145,7 +147,26 @@ static vector<SAPFOR::BasicBlock*> findBlocksInLoopsByFullIR(
return result; return result;
} }
static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(const SAPFOR::BasicBlock* bb) static map<SAPFOR::BasicBlock*, FuncInfo*> buildBasicBlockOwnerMap(
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& fullIR)
{
map<SAPFOR::BasicBlock*, FuncInfo*> owners;
for (const auto& kv : fullIR)
{
FuncInfo* fi = kv.first;
if (!fi)
continue;
for (SAPFOR::BasicBlock* bb : kv.second)
if (bb)
owners[bb] = fi;
}
return owners;
}
static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(
const SAPFOR::BasicBlock* bb,
FuncInfo* caller,
const map<string, FuncInfo*>& funcMapByName)
{ {
if (!bb) if (!bb)
return {}; return {};
@@ -422,6 +443,97 @@ static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(c
map<string, SgStatement*> varUsages; map<string, SgStatement*> varUsages;
map<SgStatement*, set<SgStatement*>> operatorsDependencies; map<SgStatement*, set<SgStatement*>> operatorsDependencies;
function<void(SgExpression*, SgStatement*)> applyOutputEffectsFromRhs =
[&](SgExpression* expr, SgStatement* stmt)
{
if (!expr || !stmt || !caller)
return;
if (isSgValueExp(expr) || expr->variant() == CONST_REF)
return;
if (expr->variant() == FUNC_CALL)
{
auto* fcall = isSgFunctionCallExp(expr);
if (fcall)
{
FuncInfo* callee = nullptr;
string resolvedCalleeName;
for (const auto& cd : caller->callsFromDetailed)
{
if (cd.pointerDetailCallsFrom.first != static_cast<void*>(expr))
continue;
if (cd.pointerDetailCallsFrom.second != FUNC_CALL)
continue;
resolvedCalleeName = cd.detailCallsFrom.first;
if (!cd.detailCallsFrom.first.empty())
callee = getFuncInfo(funcMapByName, cd.detailCallsFrom.first);
break;
}
if (resolvedCalleeName.empty() && fcall->symbol())
{
SgSymbol* sym = OriginalSymbol(fcall->symbol());
if (sym && sym->identifier())
resolvedCalleeName = sym->identifier();
}
if (!callee && !resolvedCalleeName.empty())
callee = getFuncInfo(funcMapByName, resolvedCalleeName);
string lowerCalleeName = resolvedCalleeName;
for (char& c : lowerCalleeName)
c = static_cast<char>(tolower(static_cast<unsigned char>(c)));
const bool unknownCalleeTreatAsPureIntrinsic =
!callee && !lowerCalleeName.empty() && isPureIntrinsic(lowerCalleeName);
const int nArgs = fcall->numberOfArgs();
for (int i = 0; i < nArgs; ++i)
{
bool mayModify = false;
if (callee)
{
if (i >= callee->funcParams.countOfPars)
mayModify = true;
else
mayModify = callee->funcParams.isArgOut(i)
|| callee->funcParams.isArgInOut(i);
}
else if (unknownCalleeTreatAsPureIntrinsic)
mayModify = false;
else
mayModify = true;
if (!mayModify)
continue;
set<string> argKeys;
collectUsedKeysFromExpression(fcall->arg(i), argKeys);
for (const string& k : argKeys)
varDeclarations[k] = stmt;
}
for (int i = 0; i < nArgs; ++i)
applyOutputEffectsFromRhs(fcall->arg(i), stmt);
}
return;
}
if (auto* arrayRef = isSgArrayRefExp(expr))
{
for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i)
applyOutputEffectsFromRhs(arrayRef->subscript(i), stmt);
return;
}
if (expr->variant() == VAR_REF)
return;
applyOutputEffectsFromRhs(expr->lhs(), stmt);
applyOutputEffectsFromRhs(expr->rhs(), stmt);
};
for (SgStatement* stmt : operatorsOrder) for (SgStatement* stmt : operatorsOrder)
{ {
set<string> usedKeys; set<string> usedKeys;
@@ -436,6 +548,9 @@ static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(c
if (!declarationKey.empty()) if (!declarationKey.empty())
varDeclarations[declarationKey] = stmt; varDeclarations[declarationKey] = stmt;
if (stmt && caller)
applyOutputEffectsFromRhs(stmt->expr(1), stmt);
for (const string& key : usedKeys) for (const string& key : usedKeys)
varUsages[key] = stmt; varUsages[key] = stmt;
} }
@@ -638,18 +753,31 @@ static bool reorderOperatorsInBasicBlockUsingDeps(
return true; return true;
} }
void moveOperators(SgFile* file, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform) { void moveOperators(SgFile* file,
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR,
const map<string, vector<FuncInfo*>>& allFuncInfo,
int& countOfTransform)
{
if (!file) if (!file)
return; return;
if (SgFile::switchToFile(file->filename()) == -1) if (SgFile::switchToFile(file->filename()) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
map<string, FuncInfo*> funcMap;
createMapOfFunc(allFuncInfo, funcMap);
const map<SAPFOR::BasicBlock*, FuncInfo*> blockOwner = buildBasicBlockOwnerMap(FullIR);
const auto loopBlocks = findBlocksInLoopsByFullIR(file, FullIR); const auto loopBlocks = findBlocksInLoopsByFullIR(file, FullIR);
for (auto* bb : loopBlocks) for (auto* bb : loopBlocks)
{ {
if (!bb) if (!bb)
continue; continue;
const auto operatorsDependencies = analyzeBasicBlockIntraDependencies(bb); FuncInfo* caller = nullptr;
auto itOwn = blockOwner.find(bb);
if (itOwn != blockOwner.end())
caller = itOwn->second;
const auto operatorsDependencies = analyzeBasicBlockIntraDependencies(bb, caller, funcMap);
if (reorderOperatorsInBasicBlockUsingDeps(bb, operatorsDependencies)) if (reorderOperatorsInBasicBlockUsingDeps(bb, operatorsDependencies))
countOfTransform += 1; countOfTransform += 1;
} }

View File

@@ -3,4 +3,7 @@
#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,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR,
const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo,
int& countOfTransform);