Files
SAPFOR/src/Transformations/ArrayConstantPropagation/propagation.cpp

640 lines
22 KiB
C++
Raw Normal View History

2025-12-19 01:55:23 +03:00
#include "propagation.h"
#include "../Utils/SgUtils.h"
2026-04-09 21:56:03 +03:00
#include <functional>
2026-04-27 16:18:43 +03:00
#include <iostream>
#include <map>
#include <set>
2025-12-19 01:55:23 +03:00
#include <vector>
using namespace std;
2026-04-27 16:18:43 +03:00
static SgStatement* declPlace = NULL;
static set<SgStatement*> changed;
static map<string, SgSymbol*> variablesToAdd;
static map<string, set<SgStatement*>> positionsToAdd;
static map<string, string> arrayToName;
2026-05-01 12:03:41 +03:00
static map<string, set<SgStatement*>> statementsToRemove;
2026-04-27 16:18:43 +03:00
static map<string, map<SgStatement*, SgStatement*>> expToChange;
2026-05-01 12:03:41 +03:00
static int variableNumber = 0;
2025-12-19 01:55:23 +03:00
2026-05-01 12:03:41 +03:00
static bool checkConstIndexes(SgExpression* exp)
2025-12-19 01:55:23 +03:00
{
if (!exp)
{
2026-04-27 16:18:43 +03:00
return false;
2025-12-19 01:55:23 +03:00
}
SgExpression* lhs = exp->lhs();
SgExpression* rhs = exp->rhs();
do
{
2026-04-27 16:18:43 +03:00
if (lhs && lhs->variant() != INT_VAL)
2025-12-19 01:55:23 +03:00
{
return false;
}
if (rhs)
{
lhs = rhs->lhs();
rhs = rhs->rhs();
}
} while (rhs);
return true;
}
2026-05-01 12:03:41 +03:00
static SgExpression* createVar(SgType* type)
2025-12-19 01:55:23 +03:00
{
2026-04-27 16:18:43 +03:00
string varName = "tmp_prop_var";
2025-12-19 01:55:23 +03:00
string name = varName + std::to_string(variableNumber) + "__";
variableNumber++;
2026-03-12 04:25:45 +03:00
SgStatement* funcStart = declPlace->controlParent();
2026-04-27 16:18:43 +03:00
SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), SgTypeInt(), funcStart);
2026-03-12 04:25:45 +03:00
2026-04-27 16:18:43 +03:00
variablesToAdd[name] = varSymbol;
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
2026-03-12 04:25:45 +03:00
return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr());
}
2026-05-01 12:03:41 +03:00
static SgStatement* findLastDeclStatement(SgStatement* funcStart)
2026-03-12 04:25:45 +03:00
{
2026-04-27 16:18:43 +03:00
if (!funcStart)
return NULL;
2026-05-01 12:03:41 +03:00
2026-03-12 04:25:45 +03:00
SgStatement* endSt = funcStart->lastNodeOfStmt();
SgStatement* cur = funcStart->lexNext();
SgStatement* lastDecl = funcStart;
const set<int> declVariants = { VAR_DECL, VAR_DECL_90, ALLOCATABLE_STMT, DIM_STAT,
EXTERN_STAT, COMM_STAT, HPF_TEMPLATE_STAT, DVM_VAR_DECL, STRUCT_DECL };
while (cur && cur != endSt)
{
if (cur->variant() == INTERFACE_STMT)
cur = cur->lastNodeOfStmt();
if (declVariants.find(cur->variant()) != declVariants.end())
lastDecl = cur;
else if (isSgExecutableStatement(cur))
break;
cur = cur->lexNext();
}
return lastDecl;
}
2026-05-01 12:03:41 +03:00
static void insertCommonAndDeclsForFunction(SgStatement* funcStart, const map<string, SgSymbol*>& symbols)
2026-03-12 04:25:45 +03:00
{
if (symbols.empty())
return;
2025-12-19 01:55:23 +03:00
2026-04-27 16:18:43 +03:00
if (!funcStart)
return;
2026-05-01 12:03:41 +03:00
const string commonBlockName = "__propagation_common__";
2025-12-19 01:55:23 +03:00
2026-03-12 04:25:45 +03:00
SgStatement* funcEnd = funcStart->lastNodeOfStmt();
2025-12-19 01:55:23 +03:00
SgStatement* commonStat = NULL;
SgExpression* commonList = NULL;
2026-03-12 04:25:45 +03:00
for (SgStatement* cur = funcStart->lexNext();
2026-04-27 16:18:43 +03:00
cur && cur != funcEnd; cur = cur->lexNext())
2025-12-19 01:55:23 +03:00
{
2026-03-12 04:25:45 +03:00
if (cur->variant() != COMM_STAT)
continue;
for (SgExpression* exp = cur->expr(0); exp; exp = exp->rhs())
2025-12-19 01:55:23 +03:00
{
2026-03-12 04:25:45 +03:00
if (exp->variant() != COMM_LIST)
continue;
const char* id = exp->symbol() ? exp->symbol()->identifier() : NULL;
string existingName = id ? string(id) : string("spf_unnamed");
if (existingName == commonBlockName)
2025-12-19 01:55:23 +03:00
{
2026-03-12 04:25:45 +03:00
commonStat = cur;
commonList = exp;
2025-12-19 01:55:23 +03:00
break;
2026-03-12 04:25:45 +03:00
}
2025-12-19 01:55:23 +03:00
}
2026-03-12 04:25:45 +03:00
if (commonStat)
break;
2025-12-19 01:55:23 +03:00
}
vector<SgExpression*> varRefs;
2026-04-27 16:18:43 +03:00
for (const auto& [name, sym] : symbols)
2026-04-09 21:56:03 +03:00
{
if (!sym || sym->variant() != VARIABLE_NAME || string(sym->identifier()) == commonBlockName)
continue;
2026-04-27 16:18:43 +03:00
SgSymbol* symToAdd = new SgSymbol(VARIABLE_NAME, name.c_str(), SgTypeInt(), funcStart);
2026-04-09 21:56:03 +03:00
varRefs.push_back(new SgVarRefExp(symToAdd));
}
2026-03-12 04:25:45 +03:00
SgExpression* varList = makeExprList(varRefs, false);
2025-12-19 01:55:23 +03:00
2026-05-01 12:03:41 +03:00
SgStatement* insertAfter = findLastDeclStatement(funcStart);
2026-04-27 16:18:43 +03:00
for (const auto& [name, sym] : symbols)
2026-04-09 21:56:03 +03:00
{
2026-04-27 16:18:43 +03:00
if (!sym)
continue;
2026-04-09 21:56:03 +03:00
SgStatement* declStmt = sym->makeVarDeclStmt();
if (!declStmt)
continue;
if (SgVarDeclStmt* vds = isSgVarDeclStmt(declStmt))
vds->setVariant(VAR_DECL_90);
declStmt->setFileName(funcStart->fileName());
declStmt->setFileId(funcStart->getFileId());
declStmt->setProject(funcStart->getProject());
declStmt->setlineNumber(getNextNegativeLineNumber());
insertAfter->insertStmtAfter(*declStmt, *funcStart);
insertAfter = declStmt;
2026-05-01 12:03:41 +03:00
statementsToRemove[declStmt->fileName()].insert(declStmt);
2026-04-09 21:56:03 +03:00
}
2025-12-19 01:55:23 +03:00
if (!commonList)
{
SgSymbol* commonSymbol = new SgSymbol(COMMON_NAME, commonBlockName.c_str());
2026-03-12 04:25:45 +03:00
commonList = new SgExpression(COMM_LIST, varList, NULL, commonSymbol);
2025-12-19 01:55:23 +03:00
2026-03-12 04:25:45 +03:00
commonStat = new SgStatement(COMM_STAT);
commonStat->setFileName(funcStart->fileName());
commonStat->setFileId(funcStart->getFileId());
commonStat->setProject(funcStart->getProject());
commonStat->setlineNumber(getNextNegativeLineNumber());
commonStat->setExpression(0, commonList);
2025-12-19 01:55:23 +03:00
2026-05-01 12:03:41 +03:00
SgStatement* lastDecl = findLastDeclStatement(funcStart);
2026-03-12 04:25:45 +03:00
lastDecl->insertStmtAfter(*commonStat, *funcStart);
2026-05-01 12:03:41 +03:00
statementsToRemove[commonStat->fileName()].insert(commonStat);
2025-12-19 01:55:23 +03:00
}
2026-03-12 04:25:45 +03:00
else
2025-12-19 01:55:23 +03:00
commonList->setLhs(varList);
}
2026-04-27 16:18:43 +03:00
static void copyStatement(SgStatement* st)
2025-12-19 01:55:23 +03:00
{
2026-04-27 16:18:43 +03:00
if (!st)
2025-12-19 01:55:23 +03:00
return;
2026-05-01 12:03:41 +03:00
2026-04-27 16:18:43 +03:00
if (expToChange[st->fileName()].find(st) == expToChange[st->fileName()].end())
{
SgStatement* boundCopy = st->copyPtr();
for (int i = 0; i < 3; i++)
{
SgExpression* expCopy = st->expr(i);
if (expCopy)
boundCopy->setExpression(i, expCopy->copyPtr());
else
boundCopy->setExpression(i, NULL);
}
expToChange[st->fileName()][st] = boundCopy;
}
}
2026-05-01 12:03:41 +03:00
static bool transformRightPart(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable)
2026-04-27 16:18:43 +03:00
{
if (!exp)
return false;
bool isChanged = false;
2025-12-19 01:55:23 +03:00
vector<SgExpression*> subnodes = { exp->lhs(), exp->rhs() };
string expUnparsed;
SgExpression* toAdd = NULL;
2026-05-01 12:03:41 +03:00
if (isArrayRef(exp) && checkConstIndexes(exp->lhs()))
2025-12-19 01:55:23 +03:00
{
2026-04-09 21:56:03 +03:00
expUnparsed = exp->unparse();
2026-04-27 16:18:43 +03:00
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp && exp->symbol() &&
exp->symbol()->type() && exp->symbol()->type()->baseType())
2025-12-19 01:55:23 +03:00
{
2026-05-01 12:03:41 +03:00
arrayToVariable[expUnparsed] = createVar(exp->symbol()->type()->baseType());
2026-04-27 16:18:43 +03:00
arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse();
2025-12-19 01:55:23 +03:00
}
2026-04-27 16:18:43 +03:00
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
auto* sym = new SgSymbol(VARIABLE_NAME, arrayToName[expUnparsed].c_str(), SgTypeInt(), declPlace->controlParent());
2026-04-09 21:56:03 +03:00
auto* newVarExp = new SgVarRefExp(sym);
2026-04-27 16:18:43 +03:00
copyStatement(st);
2026-04-09 21:56:03 +03:00
st->setExpression(1, newVarExp);
2026-04-27 16:18:43 +03:00
return true;
2025-12-19 01:55:23 +03:00
}
2026-05-01 12:03:41 +03:00
2025-12-19 01:55:23 +03:00
for (int i = 0; i < 2; i++)
{
2026-04-27 16:18:43 +03:00
if (subnodes[i] && isArrayRef(subnodes[i]) && subnodes[i]->symbol() && subnodes[i]->symbol()->type() &&
2026-05-01 12:03:41 +03:00
subnodes[i]->symbol()->type()->baseType() && checkConstIndexes(subnodes[i]->lhs()))
2025-12-19 01:55:23 +03:00
{
2026-04-27 16:18:43 +03:00
isChanged = true;
2025-12-19 01:55:23 +03:00
expUnparsed = subnodes[i]->unparse();
2026-04-27 16:18:43 +03:00
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end())
{
2026-05-01 12:03:41 +03:00
arrayToVariable[expUnparsed] = createVar(subnodes[i]->symbol()->type()->baseType());
2026-04-27 16:18:43 +03:00
arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse();
}
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
2026-04-09 21:56:03 +03:00
SgSymbol* builder = arrayToVariable[expUnparsed]->symbol();
2026-04-27 16:18:43 +03:00
auto* sym = new SgSymbol(VARIABLE_NAME, arrayToName[expUnparsed].c_str(), SgTypeInt(), declPlace->controlParent());
2026-04-09 21:56:03 +03:00
toAdd = new SgVarRefExp(sym);
2025-12-19 01:55:23 +03:00
if (toAdd)
{
2026-04-27 16:18:43 +03:00
copyStatement(st);
2025-12-19 01:55:23 +03:00
if (i == 0)
exp->setLhs(toAdd);
else
exp->setRhs(toAdd);
}
}
else
2026-05-01 12:03:41 +03:00
isChanged = isChanged || transformRightPart(st, subnodes[i], arrayToVariable);
2026-04-27 16:18:43 +03:00
2025-12-19 01:55:23 +03:00
}
2026-04-27 16:18:43 +03:00
return isChanged;
2025-12-19 01:55:23 +03:00
}
2026-05-01 12:03:41 +03:00
static void transformLeftPart(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable)
2025-12-19 01:55:23 +03:00
{
2026-04-27 16:18:43 +03:00
if (!st || !st->expr(1))
return;
if (!exp || !exp->symbol() || !exp->symbol()->type() || !exp->symbol()->type()->baseType())
return;
2025-12-19 01:55:23 +03:00
if (exp->symbol()->type()->variant() == T_STRING)
return;
2026-03-12 04:25:45 +03:00
if (changed.find(st) != changed.end())
return;
2026-05-01 12:03:41 +03:00
2025-12-19 01:55:23 +03:00
string expUnparsed = exp->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType())
{
2026-05-01 12:03:41 +03:00
arrayToVariable[expUnparsed] = createVar(exp->symbol()->type()->baseType());
2026-04-27 16:18:43 +03:00
arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse();
2025-12-19 01:55:23 +03:00
}
2026-04-27 16:18:43 +03:00
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
auto* sym = new SgSymbol(VARIABLE_NAME, arrayToName[expUnparsed].c_str(), SgTypeInt(), declPlace->controlParent());
auto* newVarExp = new SgVarRefExp(sym);
SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, newVarExp, st->expr(1)->copyPtr(), NULL);
2025-12-19 01:55:23 +03:00
2026-04-09 21:56:03 +03:00
newStatement->setFileId(st->getFileId());
2026-04-27 16:18:43 +03:00
newStatement->setProject(st->getProject());
st->insertStmtBefore(*newStatement, *st->controlParent());
2025-12-19 01:55:23 +03:00
newStatement->setlineNumber(getNextNegativeLineNumber());
newStatement->setLocalLineNumber(st->lineNumber());
2026-04-27 16:18:43 +03:00
2026-03-12 04:25:45 +03:00
changed.insert(st);
2026-05-01 12:03:41 +03:00
statementsToRemove[newStatement->fileName()].insert(newStatement);
2026-03-12 04:25:45 +03:00
}
2026-05-01 12:03:41 +03:00
static void transformBorder(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable)
2026-03-12 04:25:45 +03:00
{
2026-04-27 16:18:43 +03:00
if (!st || !exp)
return;
2026-03-12 04:25:45 +03:00
SgStatement* firstStatement = declPlace->lexPrev();
2026-04-27 16:18:43 +03:00
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
2026-05-01 12:03:41 +03:00
transformRightPart(st, exp, arrayToVariable);
2026-03-12 04:25:45 +03:00
st = st->lexPrev();
2026-04-27 16:18:43 +03:00
while (st &&st != firstStatement)
2026-03-12 04:25:45 +03:00
{
2026-04-27 16:18:43 +03:00
if (st->variant() == ASSIGN_STAT)
2026-03-12 04:25:45 +03:00
{
if (st->expr(1))
{
2026-05-01 12:03:41 +03:00
transformRightPart(st, st->expr(1), arrayToVariable);
2026-03-12 04:25:45 +03:00
}
2026-05-01 12:03:41 +03:00
if (st->expr(0) && isArrayRef(st->expr(0)) && checkConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
transformLeftPart(st, st->expr(0), arrayToVariable);
2026-03-12 04:25:45 +03:00
}
st = st->lexPrev();
}
}
2026-05-01 12:03:41 +03:00
static void checkVariable(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable)
2026-03-12 04:25:45 +03:00
{
SgStatement* firstStatement = declPlace->lexPrev();
st = st->lexPrev();
while (st != firstStatement)
{
if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol())
{
2026-05-01 12:03:41 +03:00
if (transformRightPart(st, st->expr(1), arrayToVariable))
2026-04-27 16:18:43 +03:00
{
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
}
2026-03-12 04:25:45 +03:00
}
2026-05-01 12:03:41 +03:00
2026-03-12 04:25:45 +03:00
if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{
if (st->expr(1))
{
2026-05-01 12:03:41 +03:00
if(transformRightPart(st, st->expr(1), arrayToVariable))
2026-04-27 16:18:43 +03:00
{
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
}
2026-03-12 04:25:45 +03:00
}
2026-05-01 12:03:41 +03:00
if (st->expr(0) && isArrayRef(st->expr(0)) && checkConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
2026-03-12 04:25:45 +03:00
{
2026-05-01 12:03:41 +03:00
transformLeftPart(st, st->expr(0), arrayToVariable);
2026-04-27 16:18:43 +03:00
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
2026-03-12 04:25:45 +03:00
}
}
st = st->lexPrev();
}
2025-12-19 01:55:23 +03:00
}
2026-05-01 12:03:41 +03:00
static void findConstValues(SgProject& project,
const map<string, map<string, SgStatement*>>& borderVars,
const map<string, SgExpression*>& arrayToVariable,
map<string, int>& hitCount,
map<string, map<SgStatement*, vector<pair<string, string>>>>& result)
2026-04-27 16:18:43 +03:00
{
for (int i = 0; i < project.numberOfFiles(); i++)
{
SgFile* file = &(project.file(i));
if (!file)
continue;
SgFile::switchToFile(file->filename());
const int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i)
{
SgStatement* st = file->functions(i);
SgStatement* lastNode = st->lastNodeOfStmt();
if (!st)
continue;
for (; st != lastNode; st = st->lexNext())
{
if (st && st->variant() == ASSIGN_STAT)
{
if (!st->expr(0) || !st->expr(1))
continue;
SgExpression* lhs = st->expr(0);
SgExpression* rhs = st->expr(1);
auto varIt = arrayToVariable.find(lhs->unparse());
string varName = (varIt != arrayToVariable.end()) ? varIt->second->unparse() : lhs->unparse();
if (rhs->variant() == INT_VAL)
hitCount[string(lhs->unparse())]++;
for (const auto& [filename, names] : borderVars)
{
if(names.find(string(lhs->unparse())) != names.end() && rhs->variant() == INT_VAL)
result[filename][names.at(lhs->unparse())].push_back({ varName, rhs->unparse()});
}
}
}
}
}
}
static void insertDefinition(map<string, map<SgStatement*, vector<pair<string, string>>>>& definitions, map<string, int>& hitCount)
{
for (const auto& [filename, variables] : definitions)
{
if (SgFile::switchToFile(filename) == -1)
continue;
for (const auto& [statement, values] : variables)
{
if (!statement)
continue;
SgStatement* insertBefore = statement, *st = statement;
while (st && !isSgExecutableStatement(st))
{
st = st->lexNext();
insertBefore = st;
}
for (const auto& [varName, value] : values)
{
if (hitCount.find(varName) == hitCount.end() || hitCount[varName] > 1)
continue;
SgSymbol* sym = new SgSymbol(VARIABLE_NAME, varName.c_str(), SgTypeInt(), statement);
SgExpression* lhs = new SgVarRefExp(sym);
SgExpression* rhs = new SgValueExp(stoi(value));
SgStatement* asg = new SgStatement(ASSIGN_STAT, NULL, NULL, lhs, rhs, NULL);
asg->setFileName(statement->fileName());
asg->setFileId(statement->getFileId());
asg->setProject(statement->getProject());
asg->setlineNumber(getNextNegativeLineNumber());
if (insertBefore && insertBefore->controlParent())
{
insertBefore->insertStmtBefore(*asg, *insertBefore->controlParent());
2026-05-01 12:03:41 +03:00
statementsToRemove[asg->fileName()].insert(asg);
2026-04-27 16:18:43 +03:00
}
}
}
}
}
2026-05-01 12:03:41 +03:00
static void applyLeftPartForUnchangedAssignments(SgProject& project, map<string, SgExpression*>& arrayToVariable)
2026-04-27 16:18:43 +03:00
{
for (int fi = 0; fi < project.numberOfFiles(); ++fi)
{
SgFile* file = &(project.file(fi));
if (!file)
continue;
const string fileName = file->filename();
if (SgFile::switchToFile(fileName) == -1)
continue;
const int funcNum = file->numberOfFunctions();
for (int fni = 0; fni < funcNum; ++fni)
{
SgStatement* funcStart = file->functions(fni);
if (!funcStart)
continue;
declPlace = funcStart;
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
SgStatement* endSt = funcStart->lastNodeOfStmt();
for (SgStatement* st = funcStart; st && st != endSt; st = st->lexNext())
{
if (st->variant() != ASSIGN_STAT)
continue;
if (!st->expr(0) || !st->expr(1))
continue;
if (changed.find(st) != changed.end())
continue;
SgExpression* lhs = st->expr(0);
if (!isArrayRef(lhs))
continue;
if (!lhs->symbol() || !lhs->symbol()->type())
continue;
if (!lhs->symbol()->type()->baseType())
continue;
2026-05-01 12:03:41 +03:00
if (!checkConstIndexes(lhs->lhs()))
2026-04-27 16:18:43 +03:00
continue;
const string lhsUnparsed = lhs->unparse();
if (arrayToVariable.find(lhsUnparsed) == arrayToVariable.end())
continue;
2026-05-01 12:03:41 +03:00
transformLeftPart(st, lhs, arrayToVariable);
2026-04-27 16:18:43 +03:00
}
}
}
}
2026-05-01 12:03:41 +03:00
static bool containsArrayRefRecursive(SgExpression* exp)
2026-04-27 16:18:43 +03:00
{
if (!exp)
return false;
2026-05-01 12:03:41 +03:00
if (isArrayRef(exp) && checkConstIndexes(exp->lhs()))
2026-04-27 16:18:43 +03:00
return true;
2026-05-01 12:03:41 +03:00
return containsArrayRefRecursive(exp->lhs()) || containsArrayRefRecursive(exp->rhs());
2026-04-27 16:18:43 +03:00
}
static void getBorderVars(SgExpression* exp, const string& filename, map<string, map<string, SgStatement*>>& borderVars)
{
if (!exp)
return;
2026-05-01 12:03:41 +03:00
if ((isArrayRef(exp) && checkConstIndexes(exp->lhs())) || exp->variant() == VAR_REF)
2026-04-27 16:18:43 +03:00
borderVars[filename][string(exp->unparse())] = declPlace;
getBorderVars(exp->lhs(), filename, borderVars);
getBorderVars(exp->rhs(), filename, borderVars);
}
2026-05-01 12:03:41 +03:00
static void processLoopBound(SgStatement* st,
SgExpression* bound,
const string& boundUnparsed,
bool isUpperBound,
map<string, SgExpression*>& arrayToVariable,
map<string, map<string, SgStatement*>>& borderVars)
2025-12-19 01:55:23 +03:00
{
2026-04-27 16:18:43 +03:00
if (!bound || !st)
return;
SgExpression* exp = isUpperBound ? bound->rhs() : bound->lhs();
getBorderVars(exp, st->fileName(), borderVars);
2026-05-01 12:03:41 +03:00
if (containsArrayRefRecursive(exp), borderVars, st->fileName())
2026-04-27 16:18:43 +03:00
{
copyStatement(st);
2026-05-01 12:03:41 +03:00
transformBorder(st, bound, arrayToVariable);
2026-04-27 16:18:43 +03:00
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
}
else if (bound->variant() == VAR_REF)
2026-05-01 12:03:41 +03:00
checkVariable(st, bound, arrayToVariable);
2026-04-27 16:18:43 +03:00
}
void arrayConstantPropagation(SgProject& project)
{
map<string, SgExpression*> arrayToVariable;
map<string, map<string, SgStatement*>> borderVars;
2026-05-01 12:03:41 +03:00
2026-04-27 16:18:43 +03:00
for (int i = 0; i < project.numberOfFiles(); i++)
2025-12-19 01:55:23 +03:00
{
2026-05-01 12:03:41 +03:00
SgFile *file = &(project.file(i));
2025-12-19 01:55:23 +03:00
if (!file)
2026-05-01 12:03:41 +03:00
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (SgFile::switchToFile(file->filename()) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
2025-12-19 01:55:23 +03:00
const int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i)
{
SgStatement* st = file->functions(i);
2026-04-27 16:18:43 +03:00
if (!st)
2026-05-01 12:03:41 +03:00
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
2026-04-27 16:18:43 +03:00
declPlace = st;
2025-12-19 01:55:23 +03:00
SgStatement* lastNode = st->lastNodeOfStmt();
for (; st != lastNode; st = st->lexNext())
{
2026-04-27 16:18:43 +03:00
if (st && st->variant() == FOR_NODE)
2025-12-19 01:55:23 +03:00
{
2026-04-27 16:18:43 +03:00
if (!st->expr(0))
continue;
if (!st->expr(0)->lhs() || !st->expr(0)->rhs())
continue;
2025-12-19 01:55:23 +03:00
SgExpression* lowerBound = st->expr(0)->lhs();
SgExpression* upperBound = st->expr(0)->rhs();
2026-04-27 16:18:43 +03:00
string lowerBoundUnparsed = lowerBound->unparse();
string upperBoundUnparsed = upperBound->unparse();
2026-05-01 12:03:41 +03:00
processLoopBound(st, st->expr(0), upperBoundUnparsed, true, arrayToVariable, borderVars);
processLoopBound(st, st->expr(0), lowerBoundUnparsed, false, arrayToVariable, borderVars);
2026-04-27 16:18:43 +03:00
2025-12-19 01:55:23 +03:00
}
}
}
2026-04-09 21:56:03 +03:00
}
2026-05-01 12:03:41 +03:00
applyLeftPartForUnchangedAssignments(project, arrayToVariable);
2026-04-27 16:18:43 +03:00
map<string, set<SgStatement*>> funcStarts;
for (const auto& [fileName, statements] : positionsToAdd)
2026-04-09 21:56:03 +03:00
{
2026-04-27 16:18:43 +03:00
int res = SgFile::switchToFile(fileName);
if (res == -1)
2026-05-01 12:03:41 +03:00
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
2026-04-27 16:18:43 +03:00
for (SgStatement* st : statements)
{
SgStatement* scope = isSgProgHedrStmt(st) ? st : st->controlParent();
if (scope)
funcStarts[fileName].insert(scope);
}
2026-04-09 21:56:03 +03:00
}
2026-05-01 12:03:41 +03:00
2026-04-27 16:18:43 +03:00
for (const auto& [fileName, statements] : funcStarts)
{
SgFile::switchToFile(fileName);
for (SgStatement* st : statements)
{
2026-05-01 12:03:41 +03:00
insertCommonAndDeclsForFunction(st, variablesToAdd);
2026-04-27 16:18:43 +03:00
}
}
2026-05-01 12:03:41 +03:00
2026-04-27 16:18:43 +03:00
map<string, map<SgStatement*, vector<pair<string, string>>>> result;
map<string, int> hitCount;
2026-05-01 12:03:41 +03:00
2026-04-27 16:18:43 +03:00
findConstValues(project, borderVars, arrayToVariable, hitCount, result);
insertDefinition(result, hitCount);
}
2026-05-01 12:03:41 +03:00
void arrayConstantPropagationRrestore()
2026-04-27 16:18:43 +03:00
{
for (auto& [filename, statements] : expToChange)
{
if (SgFile::switchToFile(filename) == -1)
2026-05-01 12:03:41 +03:00
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
2026-04-27 16:18:43 +03:00
for (auto& [statement, statementCopy] : statements)
{
if (statement && statementCopy)
for (int i = 0; i < 3; i++)
statement->setExpression(i, statementCopy->expr(i));
}
}
2026-05-01 12:03:41 +03:00
for (auto& [filename, statements] : statementsToRemove)
2026-04-09 21:56:03 +03:00
{
2026-05-01 12:03:41 +03:00
if (SgFile::switchToFile(filename) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& st : statements)
st->deleteStmt();
2025-12-19 01:55:23 +03:00
}
2026-04-27 16:18:43 +03:00
}