change propagation

This commit is contained in:
2025-12-27 13:30:25 +03:00
parent 032cdb9b03
commit 3eb09fe5cf
3 changed files with 92 additions and 33 deletions

View File

@@ -10,6 +10,7 @@
using namespace std;
static SgStatement* declPlace = NULL;
static unordered_set<SgStatement*> changed;;
static bool CheckConstIndexes(SgExpression* exp)
{
@@ -36,13 +37,13 @@ static bool CheckConstIndexes(SgExpression* exp)
static SgExpression* CreateVar(int& variableNumber, SgType* type)
{
string varName = "__tmp_prop_var";
string varName = "tmp_prop_var";
string name = varName + std::to_string(variableNumber) + "__";
variableNumber++;
SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *declPlace->controlParent());
const string commonBlockName = "__propagation_common__";
const string commonBlockName = "propagation_common__";
SgStatement* funcStart = declPlace->controlParent();
SgStatement* commonStat = NULL;
@@ -169,8 +170,7 @@ static SgExpression* CreateVar(int& variableNumber, SgType* type)
commonList->setLhs(varList);
}
return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr());
return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr());
}
static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map<string, SgExpression*>& arrayToVariable, int& variableNumber)
@@ -227,6 +227,8 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map<
{
if (exp->symbol()->type()->variant() == T_STRING)
return;
if (changed.find(st) != changed.end())
return;
string expUnparsed = exp->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType())
{
@@ -234,12 +236,62 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map<
}
SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, arrayToVariable[expUnparsed]->copyPtr(), st->expr(1)->copyPtr(), NULL);
newStatement->setFileId(st->getFileId());
newStatement->setFileId(st->getFileId());
newStatement->setProject(st->getProject());
newStatement->setlineNumber(getNextNegativeLineNumber());
newStatement->setLocalLineNumber(st->lineNumber());
st->insertStmtBefore(*newStatement, *st->controlParent());
changed.insert(st);
}
static void TransformBorder(SgStatement* st, SgExpression* exp, unordered_map<string, SgExpression*>& arrayToVariable, int& variableNumber)
{
SgStatement* firstStatement = declPlace->lexPrev();
st = st->lexPrev();
string array = exp->unparse();
arrayToVariable[array] = CreateVar(variableNumber, exp->symbol()->type()->baseType());
while (st != firstStatement)
{
if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{
if (st->expr(1))
{
TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber);
}
if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{
TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber);
}
}
st = st->lexPrev();
}
}
static void CheckVariable(SgStatement* st, SgExpression* exp, unordered_map<string, SgExpression*>& arrayToVariable, int& variableNumber)
{
SgStatement* firstStatement = declPlace->lexPrev();
st = st->lexPrev();
string varName = exp->unparse();
while (st != firstStatement)
{
if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol())
{
TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber);
}
if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{
if (st->expr(1))
{
TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber);
}
if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{
TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber);
}
}
st = st->lexPrev();
}
}
void ArrayConstantPropagation(SgProject& project)
@@ -262,40 +314,29 @@ void ArrayConstantPropagation(SgProject& project)
for (; st != lastNode; st = st->lexNext())
{
if (st->variant() == ASSIGN_STAT)
{
if (st->expr(1))
{
TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber);
}
if (st->expr(0) && st->expr(0)->variant() == ARRAY_REF && CheckConstIndexes(st->expr(0)->lhs()))
{
TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber);
}
}
else if (st->variant() == FOR_NODE)
if (st->variant() == FOR_NODE)
{
SgExpression* lowerBound = st->expr(0)->lhs();
SgExpression* upperBound = st->expr(0)->rhs();
string lowerBoundUnparsed = lowerBound->unparse(), upperBoundUnparsed = upperBound->unparse();
if (upperBound->variant() == ARRAY_REF && upperBound->symbol()->type()->baseType() && CheckConstIndexes(upperBound->lhs()))
{
if (arrayToVariable.find(upperBoundUnparsed) == arrayToVariable.end())
{
arrayToVariable[upperBoundUnparsed] = CreateVar(variableNumber, upperBound->symbol()->type()->baseType());
}
TransformBorder(st, upperBound, arrayToVariable, variableNumber);
st->expr(0)->setRhs(arrayToVariable[upperBoundUnparsed]->copyPtr());
}
else if (upperBound->variant() == VAR_REF)
CheckVariable(st, upperBound, arrayToVariable, variableNumber);
if (lowerBound->variant() == ARRAY_REF && lowerBound->symbol()->type()->baseType() && CheckConstIndexes(lowerBound->lhs()))
{
if (arrayToVariable.find(lowerBoundUnparsed) == arrayToVariable.end())
{
arrayToVariable[lowerBoundUnparsed] = CreateVar(variableNumber, lowerBound->symbol()->type()->baseType());
}
TransformBorder(st, lowerBound, arrayToVariable, variableNumber);
st->expr(0)->setLhs(arrayToVariable[lowerBoundUnparsed]->copyPtr());
}
else if (lowerBound->variant() == VAR_REF)
CheckVariable(st, lowerBound, arrayToVariable, variableNumber);
}
}
cout << file->functions(i)->unparse() << endl;
}
}
}

View File

@@ -67,12 +67,14 @@ static void Collapse(Region* region)
}
}
ArrayAccessingIndexes useUnion;
ArrayAccessingIndexes useUnionB;
for (auto& byBlock : region->getBasickBlocks())
for (auto& [arrayName, arrayRanges] : byBlock->array_use)
useUnion[arrayName] = useUnion[arrayName].Union(byBlock->array_use[arrayName]);
for (auto& [arrayName, _] : byBlock->array_use)
useUnionB[arrayName] = useUnionB[arrayName].Union(byBlock->array_use[arrayName]);
for (auto& [arrayName, _] : useUnionB)
region->array_priv[arrayName] = useUnionB[arrayName].Diff(region->array_use[arrayName]);
region->array_priv = region->array_use;
for (Region* prevBlock : region->getHeader()->getPrevRegions())
prevBlock->replaceInNextRegions(region, region->getHeader());

View File

@@ -9,6 +9,7 @@
#include "range_structures.h"
#include "region.h"
#include "..\Transformations\ExpressionSubstitution\expr_transform.h"
#include "SgUtils.h"
using namespace std;
@@ -131,7 +132,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
{
vector<SAPFOR::Argument*> index_vars;
vector<int> refPos;
string array_name = instruction->getInstruction()->getArg1()->getValue();
string array_name = instruction->getInstruction()->getArg1()->getValue();
int j = i - 1;
while (j >= 0 && instructions[j]->getInstruction()->getOperation() == SAPFOR::CFG_OP::REF)
@@ -148,13 +149,27 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression());
int fillCount = 0;
while (!index_vars.empty() && !refPos.empty())
vector<pair<int, int>> coefsForDims;
int subs = ref->numberOfSubscripts();
for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i)
{
const vector<int*>& coefs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
if (coefs.size() == 1)
{
const pair<int, int> coef(coefs[0][0], coefs[0][1]);
coefsForDims.push_back(coef);
}
}
coefsForDims = {coefsForDims.rbegin(), coefsForDims.rend()};
while (!index_vars.empty() && !refPos.empty() && !coefsForDims.empty())
{
auto var = index_vars.back();
int currentVarPos = refPos.back();
ArrayDimension current_dim;
if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST)
current_dim = { stoul(var->getValue()), 1, 1, ref};
current_dim = { stoul(var->getValue()), 1, 1, ref };
else
{
string name, full_name = var->getValue();
@@ -180,7 +195,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
return -1;
}
uint64_t start = currentLoop->startVal;
uint64_t start = coefsForDims.back().second * currentLoop->startVal + coefsForDims.back().first;
uint64_t step = currentLoop->stepVal;
uint64_t iters = currentLoop->calculatedCountOfIters;
current_dim = { start, step, iters, ref };
@@ -193,6 +208,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
}
index_vars.pop_back();
refPos.pop_back();
coefsForDims.pop_back();
}
if (fillCount == accessPoint.size())