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; using namespace std;
static SgStatement* declPlace = NULL; static SgStatement* declPlace = NULL;
static unordered_set<SgStatement*> changed;;
static bool CheckConstIndexes(SgExpression* exp) static bool CheckConstIndexes(SgExpression* exp)
{ {
@@ -36,13 +37,13 @@ static bool CheckConstIndexes(SgExpression* exp)
static SgExpression* CreateVar(int& variableNumber, SgType* type) static SgExpression* CreateVar(int& variableNumber, SgType* type)
{ {
string varName = "__tmp_prop_var"; string varName = "tmp_prop_var";
string name = varName + std::to_string(variableNumber) + "__"; string name = varName + std::to_string(variableNumber) + "__";
variableNumber++; variableNumber++;
SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *declPlace->controlParent()); 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* funcStart = declPlace->controlParent();
SgStatement* commonStat = NULL; SgStatement* commonStat = NULL;
@@ -169,7 +170,6 @@ static SgExpression* CreateVar(int& variableNumber, SgType* type)
commonList->setLhs(varList); commonList->setLhs(varList);
} }
return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr()); return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr());
} }
@@ -227,6 +227,8 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map<
{ {
if (exp->symbol()->type()->variant() == T_STRING) if (exp->symbol()->type()->variant() == T_STRING)
return; return;
if (changed.find(st) != changed.end())
return;
string expUnparsed = exp->unparse(); string expUnparsed = exp->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType())
{ {
@@ -240,6 +242,56 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, unordered_map<
newStatement->setlineNumber(getNextNegativeLineNumber()); newStatement->setlineNumber(getNextNegativeLineNumber());
newStatement->setLocalLineNumber(st->lineNumber()); newStatement->setLocalLineNumber(st->lineNumber());
st->insertStmtBefore(*newStatement, *st->controlParent()); 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) void ArrayConstantPropagation(SgProject& project)
@@ -262,40 +314,29 @@ void ArrayConstantPropagation(SgProject& project)
for (; st != lastNode; st = st->lexNext()) for (; st != lastNode; st = st->lexNext())
{ {
if (st->variant() == ASSIGN_STAT) if (st->variant() == FOR_NODE)
{
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)
{ {
SgExpression* lowerBound = st->expr(0)->lhs(); SgExpression* lowerBound = st->expr(0)->lhs();
SgExpression* upperBound = st->expr(0)->rhs(); SgExpression* upperBound = st->expr(0)->rhs();
string lowerBoundUnparsed = lowerBound->unparse(), upperBoundUnparsed = upperBound->unparse(); string lowerBoundUnparsed = lowerBound->unparse(), upperBoundUnparsed = upperBound->unparse();
if (upperBound->variant() == ARRAY_REF && upperBound->symbol()->type()->baseType() && CheckConstIndexes(upperBound->lhs())) if (upperBound->variant() == ARRAY_REF && upperBound->symbol()->type()->baseType() && CheckConstIndexes(upperBound->lhs()))
{ {
if (arrayToVariable.find(upperBoundUnparsed) == arrayToVariable.end()) TransformBorder(st, upperBound, arrayToVariable, variableNumber);
{
arrayToVariable[upperBoundUnparsed] = CreateVar(variableNumber, upperBound->symbol()->type()->baseType());
}
st->expr(0)->setRhs(arrayToVariable[upperBoundUnparsed]->copyPtr()); 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 (lowerBound->variant() == ARRAY_REF && lowerBound->symbol()->type()->baseType() && CheckConstIndexes(lowerBound->lhs()))
{ {
if (arrayToVariable.find(lowerBoundUnparsed) == arrayToVariable.end()) TransformBorder(st, lowerBound, arrayToVariable, variableNumber);
{
arrayToVariable[lowerBoundUnparsed] = CreateVar(variableNumber, lowerBound->symbol()->type()->baseType());
}
st->expr(0)->setLhs(arrayToVariable[lowerBoundUnparsed]->copyPtr()); 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& byBlock : region->getBasickBlocks())
for (auto& [arrayName, arrayRanges] : byBlock->array_use) for (auto& [arrayName, _] : byBlock->array_use)
useUnion[arrayName] = useUnion[arrayName].Union(byBlock->array_use[arrayName]); 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()) for (Region* prevBlock : region->getHeader()->getPrevRegions())
prevBlock->replaceInNextRegions(region, region->getHeader()); prevBlock->replaceInNextRegions(region, region->getHeader());

View File

@@ -9,6 +9,7 @@
#include "range_structures.h" #include "range_structures.h"
#include "region.h" #include "region.h"
#include "..\Transformations\ExpressionSubstitution\expr_transform.h"
#include "SgUtils.h" #include "SgUtils.h"
using namespace std; using namespace std;
@@ -148,13 +149,27 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression());
int fillCount = 0; 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(); auto var = index_vars.back();
int currentVarPos = refPos.back(); int currentVarPos = refPos.back();
ArrayDimension current_dim; ArrayDimension current_dim;
if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST) 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 else
{ {
string name, full_name = var->getValue(); string name, full_name = var->getValue();
@@ -180,7 +195,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
return -1; 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 step = currentLoop->stepVal;
uint64_t iters = currentLoop->calculatedCountOfIters; uint64_t iters = currentLoop->calculatedCountOfIters;
current_dim = { start, step, iters, ref }; current_dim = { start, step, iters, ref };
@@ -193,6 +208,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
} }
index_vars.pop_back(); index_vars.pop_back();
refPos.pop_back(); refPos.pop_back();
coefsForDims.pop_back();
} }
if (fillCount == accessPoint.size()) if (fillCount == accessPoint.size())