From c82ebd7a16d4d9e55e4dc81375feeff0b2eb174b Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Thu, 7 May 2026 00:51:42 +0300 Subject: [PATCH] dependencies from proc calls --- .../MoveOperators/move_operators.cpp | 167 +++++++++++++++++- 1 file changed, 164 insertions(+), 3 deletions(-) diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index dea1fbd..2ce3319 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -534,22 +534,183 @@ static map> analyzeBasicBlockIntraDependencies( applyOutputEffectsFromRhs(expr->rhs(), stmt); }; + auto analyzeProcStatCallHead = [&](SgStatement* callStmt, + SgCallStmt*& sgCall, + FuncInfo*& callee, + string& resolvedCalleeName, + bool& unknownCalleeTreatAsPureIntrinsic, + int& nArgs) -> bool + { + sgCall = nullptr; + callee = nullptr; + resolvedCalleeName.clear(); + unknownCalleeTreatAsPureIntrinsic = false; + nArgs = 0; + + if (!callStmt || !caller || callStmt->variant() != PROC_STAT) + return false; + + sgCall = isSgCallStmt(callStmt); + if (!sgCall) + return false; + + for (const auto& cd : caller->callsFromDetailed) + { + if (cd.pointerDetailCallsFrom.first != static_cast(callStmt)) + continue; + if (cd.pointerDetailCallsFrom.second != PROC_STAT) + continue; + resolvedCalleeName = cd.detailCallsFrom.first; + if (!cd.detailCallsFrom.first.empty()) + callee = getFuncInfo(funcMapByName, cd.detailCallsFrom.first); + break; + } + + if (resolvedCalleeName.empty() && callStmt->symbol()) + { + SgSymbol* sym = OriginalSymbol(callStmt->symbol()); + if (sym && sym->identifier()) + resolvedCalleeName = removeString("call ", string(sym->identifier())); + } + + if (!callee && !resolvedCalleeName.empty()) + callee = getFuncInfo(funcMapByName, resolvedCalleeName); + + string lowerCalleeName = resolvedCalleeName; + for (char& c : lowerCalleeName) + c = static_cast(tolower(static_cast(c))); + + unknownCalleeTreatAsPureIntrinsic = + !callee && !lowerCalleeName.empty() && isPureIntrinsic(lowerCalleeName); + + nArgs = sgCall->numberOfArgs(); + return true; + }; + + function applyOutputEffectsFromProcStat = [&](SgStatement* callStmt) + { + SgCallStmt* sgCall = nullptr; + FuncInfo* callee = nullptr; + string resolvedCalleeName; + bool unknownCalleeTreatAsPureIntrinsic = false; + int nArgs = 0; + if (!analyzeProcStatCallHead(callStmt, sgCall, callee, resolvedCalleeName, + unknownCalleeTreatAsPureIntrinsic, nArgs)) + return; + + 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 argKeys; + collectUsedKeysFromExpression(sgCall->arg(i), argKeys); + for (const string& k : argKeys) + varDeclarations[k] = callStmt; + } + + for (int i = 0; i < nArgs; ++i) + applyOutputEffectsFromRhs(sgCall->arg(i), callStmt); + }; + + auto addCallUsageDependencies = [&](SgStatement* stmt, + const map& varUsages, + map>& operatorsDependencies) + { + SgCallStmt* sgCall = nullptr; + FuncInfo* callee = nullptr; + string resolvedCalleeName; + bool unknownCalleeTreatAsPureIntrinsic = false; + int nArgs = 0; + if (!analyzeProcStatCallHead(stmt, sgCall, callee, resolvedCalleeName, + unknownCalleeTreatAsPureIntrinsic, nArgs)) + return; + + 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 argKeys; + collectUsedKeysFromExpression(sgCall->arg(i), argKeys); + for (const string& k : argKeys) + { + auto itu = varUsages.find(k); + if (itu != varUsages.end() && itu->second && itu->second != stmt) + operatorsDependencies[stmt].insert(itu->second); + } + } + }; + for (SgStatement* stmt : operatorsOrder) { set usedKeys; if (stmt) { - collectUsedKeysFromExpression(stmt->expr(1), usedKeys); - collectUsedKeysFromArraySubscripts(isSgArrayRefExp(stmt->expr(0)), usedKeys); + if (stmt->variant() == ASSIGN_STAT) + { + collectUsedKeysFromExpression(stmt->expr(1), usedKeys); + collectUsedKeysFromArraySubscripts(isSgArrayRefExp(stmt->expr(0)), usedKeys); + } + else if (stmt->variant() == PROC_STAT) + { + if (SgCallStmt* callSt = isSgCallStmt(stmt)) + { + for (int z = 0; z < callSt->numberOfArgs(); ++z) + collectUsedKeysFromExpression(callSt->arg(z), usedKeys); + } + else + { + for (SgExpression* par = stmt->expr(0); par; par = par->rhs()) + if (par->lhs()) + collectUsedKeysFromExpression(par->lhs(), usedKeys); + } + } } addOperatorDependencies(stmt, usedKeys, varDeclarations, varUsages, operatorsDependencies); + if (stmt && stmt->variant() == PROC_STAT) + addCallUsageDependencies(stmt, varUsages, operatorsDependencies); + const string declarationKey = declarationKeyFromLeftPart(stmt); if (!declarationKey.empty()) varDeclarations[declarationKey] = stmt; if (stmt && caller) - applyOutputEffectsFromRhs(stmt->expr(1), stmt); + { + if (stmt->variant() == ASSIGN_STAT) + applyOutputEffectsFromRhs(stmt->expr(1), stmt); + else if (stmt->variant() == PROC_STAT) + applyOutputEffectsFromProcStat(stmt); + } for (const string& key : usedKeys) varUsages[key] = stmt;