23 Commits

Author SHA1 Message Date
ALEXks
a8ddc94734 version updated 2026-04-12 20:16:23 +03:00
db5062c416 REMOVE_DIST_ARRAYS_FROM_IO: find current FuncInfo properly 2026-04-12 15:32:09 +03:00
b71df882fb REMOVE_DIST_ARRAYS_FROM_IO: fix type, add TODO 2026-04-12 15:32:09 +03:00
ALEXks
2d25a61ee7 fixed analysis of arrays with type character in function parameters 2026-04-10 20:09:50 +03:00
3378ae5fbd Merge pull request 'private_arrays2' (#79) from private_arrays2 into master 2026-04-10 17:29:40 +03:00
ALEXks
446f4d54d7 vesion updated 2026-04-10 17:29:20 +03:00
7bca67b75c new changes 2026-04-10 17:24:59 +03:00
8632dfbf31 fixes 2026-04-10 17:24:59 +03:00
97e60e16be add ddot, change array propagation 2026-04-10 17:24:59 +03:00
ALEXks
39abbafb3a fixed intent insertion 2026-04-09 15:35:28 +03:00
a1e12f5c1c Merge pull request 'egormayorov' (#78) from egormayorov into master 2026-03-27 08:29:34 +03:00
ALEXks
cad8c0913d Merge branch 'master' into egormayorov 2026-03-27 08:28:44 +03:00
ALEXks
bde804cff6 updated 2026-03-27 08:27:25 +03:00
Egor Mayorov
589680a78b fix files usage 2026-03-26 14:18:45 +03:00
ALEXks
88bac54901 fixed function prototype 2026-03-26 14:18:45 +03:00
ALEXks
0d4d2b78d8 updated 2026-03-26 14:18:45 +03:00
Egor Mayorov
bbac07202d Add swith to file usage 2026-03-26 14:18:39 +03:00
ALEXks
9325723e69 updated projects 2026-03-20 15:32:24 +03:00
ALEXks
18ac53f342 fixed inliner 2026-03-19 13:04:26 +03:00
ALEXks
0bec2c6527 assign line number to intervals for loops 2026-03-10 20:33:02 +03:00
aa56778be1 Merge pull request 'Move operators pass fixes' (#77) from egormayorov into master 2026-03-10 10:03:36 +03:00
ALEXks
0a484e77de version updated 2026-03-10 10:03:27 +03:00
Egor Mayorov
4818884d48 Remove redundant functions 2026-03-08 18:34:36 +03:00
17 changed files with 544 additions and 955 deletions

View File

@@ -3,13 +3,35 @@
#include "../Utils/SgUtils.h" #include "../Utils/SgUtils.h"
#include <iostream> #include <iostream>
#include <functional>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
using namespace std; using namespace std;
static SgStatement* declPlace = NULL; namespace {
struct MyHash {
size_t operator()(const SgSymbol* s) const {
return std::hash<std::string_view>{}(s->identifier());
}
};
struct MyEq {
bool operator()(const SgSymbol* a, const SgSymbol* b) const {
return std::strcmp(a->identifier(), b->identifier()) == 0;
}
};
}
SgStatement* declPlace = NULL;
unordered_set<SgStatement*> changed;
unordered_set<SgSymbol*, MyHash, MyEq> variablesToAdd;
unordered_set<SgStatement*> positionsToAdd;
unordered_set<SgStatement*> statementsToRemove;
unordered_map<string, vector<pair<SgStatement*, SgStatement*>>> expToChange;
static bool CheckConstIndexes(SgExpression* exp) static bool CheckConstIndexes(SgExpression* exp)
{ {
@@ -40,158 +62,148 @@ static SgExpression* CreateVar(int& variableNumber, SgType* type)
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()); SgStatement* funcStart = declPlace->controlParent();
SgSymbol* varSymbol = new SgSymbol(VARIABLE_NAME, name.c_str(), *type, *funcStart);
variablesToAdd.insert(varSymbol);
positionsToAdd.insert(declPlace);
return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr());
}
static SgStatement* FindLastDeclStatement(SgStatement* funcStart)
{
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;
}
static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const unordered_set<SgSymbol*, MyHash, MyEq>& symbols)
{
if (symbols.empty())
return;
const string commonBlockName = "__propagation_common__"; const string commonBlockName = "__propagation_common__";
SgStatement* funcStart = declPlace->controlParent(); SgStatement* funcEnd = funcStart->lastNodeOfStmt();
SgStatement* commonStat = NULL; SgStatement* commonStat = NULL;
SgExpression* commonList = NULL; SgExpression* commonList = NULL;
SgStatement* funcEnd = funcStart->lastNodeOfStmt(); for (SgStatement* cur = funcStart->lexNext();
SgStatement* current = funcStart->lexNext(); cur && cur != funcEnd; cur = cur->lexNext())
while (current != funcEnd && current)
{ {
if (current->variant() == COMM_STAT) if (cur->variant() != COMM_STAT)
continue;
for (SgExpression* exp = cur->expr(0); exp; exp = exp->rhs())
{ {
for (SgExpression* exp = current->expr(0); exp; exp = exp->rhs()) 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)
{ {
if (exp->variant() == COMM_LIST) commonStat = cur;
{ commonList = exp;
string existingName = exp->symbol() ?
string(exp->symbol()->identifier()) :
string("spf_unnamed");
if (existingName == commonBlockName)
{
commonStat = current;
commonList = exp;
break;
}
}
}
if (commonStat)
break; break;
}
} }
current = current->lexNext(); if (commonStat)
break;
} }
vector<SgExpression*> varRefs; vector<SgExpression*> varRefs;
if (commonList) for (SgSymbol* sym : symbols)
{ {
SgExpression* varList = commonList->lhs(); if (!sym || sym->variant() != VARIABLE_NAME || string(sym->identifier()) == commonBlockName)
if (varList) continue;
{ SgSymbol* symToAdd = new SgSymbol(VARIABLE_NAME, sym->identifier(), *sym->type(), *funcStart);
auto extractSymbol = [](SgExpression* exp) -> SgSymbol* { varRefs.push_back(new SgVarRefExp(symToAdd));
if (!exp) }
return NULL; SgExpression* varList = makeExprList(varRefs, false);
if (exp->symbol())
return exp->symbol(); SgStatement* insertAfter = FindLastDeclStatement(funcStart);
if (exp->lhs() && exp->lhs()->symbol()) for (SgSymbol* sym : symbols)
return exp->lhs()->symbol(); {
return NULL; SgStatement* declStmt = sym->makeVarDeclStmt();
}; if (!declStmt)
if (varList->variant() == EXPR_LIST) continue;
{
for (SgExpression* exp = varList; exp; exp = exp->rhs()) if (SgVarDeclStmt* vds = isSgVarDeclStmt(declStmt))
{ vds->setVariant(VAR_DECL_90);
SgExpression* varExp = exp->lhs();
SgSymbol* sym = extractSymbol(varExp); declStmt->setFileName(funcStart->fileName());
if (sym) declStmt->setFileId(funcStart->getFileId());
{ declStmt->setProject(funcStart->getProject());
varRefs.push_back(new SgVarRefExp(sym)); declStmt->setlineNumber(getNextNegativeLineNumber());
}
} insertAfter->insertStmtAfter(*declStmt, *funcStart);
} insertAfter = declStmt;
else statementsToRemove.insert(declStmt);
{
for (SgExpression* varExp = varList; varExp; varExp = varExp->rhs())
{
SgSymbol* sym = extractSymbol(varExp);
if (sym)
{
varRefs.push_back(new SgVarRefExp(sym));
}
}
}
}
} }
if (!commonList) if (!commonList)
{ {
current = funcStart->lexNext();
while (current != funcEnd && current)
{
if (current->variant() == COMM_STAT)
{
commonStat = current;
break;
}
current = current->lexNext();
}
SgSymbol* commonSymbol = new SgSymbol(COMMON_NAME, commonBlockName.c_str()); SgSymbol* commonSymbol = new SgSymbol(COMMON_NAME, commonBlockName.c_str());
commonList = new SgExpression(COMM_LIST, NULL, NULL, commonSymbol); commonList = new SgExpression(COMM_LIST, varList, NULL, commonSymbol);
if (commonStat) commonStat = new SgStatement(COMM_STAT);
{ commonStat->setFileName(funcStart->fileName());
SgExpression* lastCommList = commonStat->expr(0); commonStat->setFileId(funcStart->getFileId());
if (lastCommList) commonStat->setProject(funcStart->getProject());
{ commonStat->setlineNumber(getNextNegativeLineNumber());
while (lastCommList->rhs()) commonStat->setExpression(0, commonList);
lastCommList = lastCommList->rhs();
lastCommList->setRhs(commonList);
}
else
{
commonStat->setExpression(0, commonList);
}
}
else
{
commonStat = new SgStatement(COMM_STAT);
commonStat->setFileName(declPlace->fileName());
commonStat->setFileId(declPlace->getFileId());
commonStat->setProject(declPlace->getProject());
commonStat->setlineNumber(getNextNegativeLineNumber());
commonStat->setExpression(0, commonList);
declPlace->insertStmtBefore(*commonStat, *declPlace->controlParent());
}
SgStatement* lastDecl = FindLastDeclStatement(funcStart);
lastDecl->insertStmtAfter(*commonStat, *funcStart);
statementsToRemove.insert(commonStat);
} }
varRefs.push_back(new SgVarRefExp(varSymbol)); else
if (varRefs.size() > 0)
{ {
std::reverse(varRefs.begin(), varRefs.end());
SgExpression* varList = makeExprList(varRefs, false);
commonList->setLhs(varList); commonList->setLhs(varList);
} }
return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr());
} }
static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map<string, SgExpression*>& arrayToVariable, int& variableNumber) static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map<string, SgExpression*>& arrayToVariable, int& variableNumber)
{ {
if (!exp) if (!exp)
{
return; return;
}
vector<SgExpression*> subnodes = { exp->lhs(), exp->rhs() }; vector<SgExpression*> subnodes = { exp->lhs(), exp->rhs() };
string expUnparsed; string expUnparsed;
SgExpression* toAdd = NULL; SgExpression* toAdd = NULL;
if (exp->variant() == ARRAY_REF && CheckConstIndexes(exp->lhs())) if (exp->variant() == ARRAY_REF && CheckConstIndexes(exp->lhs()))
{ {
cout << st->unparse() << endl; expUnparsed = exp->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType())
{ {
arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType());
} }
st->setExpression(1, arrayToVariable[expUnparsed]->copyPtr()); positionsToAdd.insert(declPlace);
SgSymbol* builder = arrayToVariable[expUnparsed]->symbol();
auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent());
auto* newVarExp = new SgVarRefExp(sym);
expToChange[st->fileName()].push_back({ st , st->copyPtr() });
st->setExpression(1, newVarExp);
return; return;
} }
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
@@ -199,27 +211,30 @@ static void TransformRightPart(SgStatement* st, SgExpression* exp, unordered_map
if (subnodes[i] && subnodes[i]->variant() == ARRAY_REF && subnodes[i]->symbol()->type()->baseType() && CheckConstIndexes(subnodes[i]->lhs())) if (subnodes[i] && subnodes[i]->variant() == ARRAY_REF && subnodes[i]->symbol()->type()->baseType() && CheckConstIndexes(subnodes[i]->lhs()))
{ {
expUnparsed = subnodes[i]->unparse(); expUnparsed = subnodes[i]->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) if (arrayToVariable.find(expUnparsed) == arrayToVariable.end())
{ arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType());
arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType());;
} positionsToAdd.insert(declPlace);
toAdd = arrayToVariable[expUnparsed]->copyPtr(); SgSymbol* builder = arrayToVariable[expUnparsed]->symbol();
auto* sym = new SgSymbol(builder->variant(), builder->identifier(), builder->type(), st->controlParent());
toAdd = new SgVarRefExp(sym);
if (toAdd) if (toAdd)
{ {
if (i == 0) if (i == 0)
{ {
expToChange[st->fileName()].push_back({ st , st->copyPtr() });;
exp->setLhs(toAdd); exp->setLhs(toAdd);
} }
else else
{ {
expToChange[st->fileName()].push_back({ st , st->copyPtr() });;
exp->setRhs(toAdd); exp->setRhs(toAdd);
} }
} }
} }
else else
{
TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber); TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber);
}
} }
} }
@@ -227,11 +242,14 @@ 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())
{ {
arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType());
} }
positionsToAdd.insert(declPlace);
SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, arrayToVariable[expUnparsed]->copyPtr(), st->expr(1)->copyPtr(), NULL); SgStatement* newStatement = new SgStatement(ASSIGN_STAT, NULL, NULL, arrayToVariable[expUnparsed]->copyPtr(), st->expr(1)->copyPtr(), NULL);
newStatement->setFileId(st->getFileId()); newStatement->setFileId(st->getFileId());
@@ -240,6 +258,59 @@ 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);
statementsToRemove.insert(newStatement);
}
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();
if (arrayToVariable.find(array) == arrayToVariable.end())
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);
positionsToAdd.insert(declPlace);
}
if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{
if (st->expr(1))
{
TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber);
positionsToAdd.insert(declPlace);
}
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);
positionsToAdd.insert(declPlace);
}
}
st = st->lexPrev();
}
} }
void ArrayConstantPropagation(SgProject& project) void ArrayConstantPropagation(SgProject& project)
@@ -252,7 +323,7 @@ void ArrayConstantPropagation(SgProject& project)
if (!file) if (!file)
continue; continue;
SgFile::switchToFile(file->filename());
const int funcNum = file->numberOfFunctions(); const int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i) for (int i = 0; i < funcNum; ++i)
{ {
@@ -262,40 +333,48 @@ 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();
SgStatement* boundCopy = NULL;
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()) boundCopy = st->copyPtr();
{ 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());
expToChange[st->fileName()].push_back({ st ,boundCopy });;
positionsToAdd.insert(declPlace);
} }
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()) boundCopy = st->copyPtr();
{ 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());
expToChange[st->fileName()].push_back({ st , boundCopy });;
positionsToAdd.insert(declPlace);
} }
else if (lowerBound->variant() == VAR_REF)
CheckVariable(st, lowerBound, arrayToVariable, variableNumber);
} }
} }
} }
} }
unordered_set<SgStatement*> funcStarts;
for (SgStatement* st : positionsToAdd)
{
SgFile::switchToFile(st->fileName());
SgStatement* scope = st->controlParent();
if (scope)
funcStarts.insert(scope);
}
for (const auto& st : funcStarts)
{
SgFile::switchToFile(st->fileName());
InsertCommonAndDeclsForFunction(st, variablesToAdd);
}
} }

View File

@@ -1,4 +1,20 @@
#pragma once #pragma once
#include "../Utils/SgUtils.h" #include "../Utils/SgUtils.h"
#include <string>
#include <vector>
using namespace std;
struct ExprRestoreEntry
{
enum Kind { kStatementExpr, kExprChild };
Kind kind;
SgStatement* stmt;
int stmtExprIndex;
SgExpression* parent;
bool childIsRhs;
SgExpression* savedCopy;
};
void ArrayConstantPropagation(SgProject& project); void ArrayConstantPropagation(SgProject& project);

View File

@@ -17,7 +17,7 @@ using std::fstream;
static long int getNextTag() static long int getNextTag()
{ {
static long int INTERVAL_TAG = 0; static long int INTERVAL_TAG = 0;
return INTERVAL_TAG++; return -(INTERVAL_TAG++);
} }
//Debug funcs //Debug funcs
@@ -413,7 +413,7 @@ static void findIntervals(SpfInterval *interval, map<int, int> &labelsRef, map<i
inter->lineFile = std::make_pair(currentSt->lineNumber(), currentSt->fileName()); inter->lineFile = std::make_pair(currentSt->lineNumber(), currentSt->fileName());
inter->parent = interval; inter->parent = interval;
inter->exit_levels.push_back(0); inter->exit_levels.push_back(0);
inter->tag = getNextTag(); inter->tag = currentSt->lineNumber();//getNextTag();
interval->nested.push_back(inter); interval->nested.push_back(inter);
findIntervals(inter, labelsRef, gotoStmts, currentSt); findIntervals(inter, labelsRef, gotoStmts, currentSt);

View File

@@ -723,7 +723,7 @@ static void fillIn(FuncInfo *currF, SgExpression *ex, const map<string, int> &pa
{ {
if (ex) if (ex)
{ {
if (!isInFuncPar && (ex->variant() == VAR_REF || isArrayRef(ex))) if (!isInFuncPar && (ex->variant() == VAR_REF || ex->variant() == ARRAY_REF))
{ {
const char *name = ex->symbol()->identifier(); const char *name = ex->symbol()->identifier();
if (name && name != string("")) if (name && name != string(""))
@@ -800,29 +800,58 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co
static map<string, vector<int>> supportedKeyWordArg = { {"system_clock", { OUT_BIT, OUT_BIT, OUT_BIT } } }; static map<string, vector<int>> supportedKeyWordArg = { {"system_clock", { OUT_BIT, OUT_BIT, OUT_BIT } } };
map<string, int> parNames; map<string, int> parNamesMain;
map<string, int> parNamesContains;
for (int i = 0; i < currF->funcParams.identificators.size(); ++i) for (int i = 0; i < currF->funcParams.identificators.size(); ++i)
parNames[currF->funcParams.identificators[i]] = i; parNamesMain[currF->funcParams.identificators[i]] = i;
map<string, int>& parNames = parNamesMain;
bool isContainsFunctions = false;
for (auto st = start; st != last; st = st->lexNext()) for (auto st = start; st != last; st = st->lexNext())
{ {
if (st->variant() == CONTAINS_STMT) if (st->variant() == CONTAINS_STMT) {
break; isContainsFunctions = true;
continue;
}
if (isContainsFunctions) {
if (st->variant() == PROC_HEDR || st->variant() == FUNC_HEDR) {
parNamesContains = parNamesMain;
SgProgHedrStmt* hedr = (SgProgHedrStmt*)st;
int numOfParams = hedr->numberOfParameters();
if (numOfParams > 0)
{
for (int i = 0; i < numOfParams; ++i)
{
auto it = parNamesContains.find(hedr->parameter(i)->identifier());
if (it != parNamesContains.end())
parNamesContains.erase(it);
}
}
parNames = parNamesContains;
}
}
if (st->variant() == ENTRY_STAT) if (st->variant() == ENTRY_STAT)
continue; continue;
if (isSgExecutableStatement(st) == NULL) { if (isSgExecutableStatement(st) == NULL) {
checkInTypeDescription(st->expr(0), currF, parNames); if (!isContainsFunctions)
checkInTypeDescription(st->expr(0), currF, parNames);
continue; continue;
} }
if (st->lineNumber() <= 0) if (st->lineNumber() <= 0)
continue; continue;
if (activeOps.size() && activeOps.find(st) == activeOps.end()) //XXX: use parameters removing in block ... isContainsFunctions ...
continue; //TODO need to use IR for parameters checking
/*if (activeOps.size() && activeOps.find(st) == activeOps.end())
continue; */
if (st->variant() == ASSIGN_STAT) if (st->variant() == ASSIGN_STAT)
{ {
@@ -851,7 +880,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co
for (auto ex = read->itemList(); ex; ex = ex->rhs()) for (auto ex = read->itemList(); ex; ex = ex->rhs())
{ {
SgExpression* item = ex->lhs(); SgExpression* item = ex->lhs();
if (item->variant() == VAR_REF || isArrayRef(item)) if (item && (item->variant() == VAR_REF || item->variant() == ARRAY_REF))
{ {
string symb = ""; string symb = "";
if (item->symbol()) if (item->symbol())
@@ -872,7 +901,7 @@ static void fillInOut(FuncInfo *currF, SgStatement *start, SgStatement *last, co
if (item->rhs()) if (item->rhs())
queue.push(item->rhs()); queue.push(item->rhs());
if (item->variant() == VAR_REF || isArrayRef(item)) if (item->variant() == VAR_REF || item->variant() == ARRAY_REF)
{ {
string symb = ""; string symb = "";
if (item->symbol()) if (item->symbol())

View File

@@ -7,16 +7,24 @@
#include <numeric> #include <numeric>
#include <iostream> #include <iostream>
#include "ArrayConstantPropagation/propagation.h"
#include "CFGraph/CFGraph.h"
#include "Distribution/Array.h"
#include "graph_loops.h"
#include "private_arrays_search.h" #include "private_arrays_search.h"
#include "range_structures.h" #include "range_structures.h"
#include "region.h" #include "region.h"
#include "SgUtils.h" #include "SgUtils.h"
#include "graph_loops.h"
#include "CFGraph/CFGraph.h"
#include "utils.h" #include "utils.h"
#include "Utils/AstWrapper.h"
using namespace std; using namespace std;
extern std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays;
extern unordered_set<SgStatement*> statementsToRemove;
extern unordered_map<string, vector<pair<SgStatement*, SgStatement*>>> expToChange;
static unordered_set<Region*> collapsed; static unordered_set<Region*> collapsed;
static void RemoveEmptyPoints(ArrayAccessingIndexes& container) static void RemoveEmptyPoints(ArrayAccessingIndexes& container)
@@ -33,10 +41,9 @@ static void RemoveEmptyPoints(ArrayAccessingIndexes& container)
points.push_back(arrayPoint); points.push_back(arrayPoint);
} }
if (points.size() < accessingSet.GetElements().size() && !points.empty()) if (!points.empty())
resultContainer[arrayName] = points; resultContainer[arrayName] = points;
else
if (points.empty())
toRemove.insert(arrayName); toRemove.insert(arrayName);
} }
@@ -281,7 +288,6 @@ static void SolveDataFlow(Region* DFG)
static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>& declaredDims) static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>& declaredDims)
{ {
declaredDims.clear();
if (!arrayRef || !arrayRef->symbol() || !isSgArrayType(arrayRef->symbol()->type())) if (!arrayRef || !arrayRef->symbol() || !isSgArrayType(arrayRef->symbol()->type()))
return false; return false;
SgArrayType* arrayType = (SgArrayType*)arrayRef->symbol()->type(); SgArrayType* arrayType = (SgArrayType*)arrayRef->symbol()->type();
@@ -290,43 +296,83 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>
{ {
SgExpression* sizeExpr = arrayType->sizeInDim(i); SgExpression* sizeExpr = arrayType->sizeInDim(i);
SgConstantSymb* constValSymb = isSgConstantSymb(sizeExpr->symbol()); SgConstantSymb* constValSymb = isSgConstantSymb(sizeExpr->symbol());
string strDimLength; SgSubscriptExp* subscriptExpr = isSgSubscriptExp(sizeExpr);
uint64_t dimLength;
if (sizeExpr && sizeExpr->variant() == INT_VAL) if (sizeExpr && sizeExpr->variant() == INT_VAL)
strDimLength = sizeExpr->unparse(); dimLength = stol(sizeExpr->unparse());
else if (constValSymb) else if (constValSymb)
strDimLength = constValSymb->constantValue()->unparse(); dimLength = stol(constValSymb->constantValue()->unparse());
else if (subscriptExpr)
{
dimLength = stol(subscriptExpr->rhs()->unparse()) - stol(subscriptExpr->lhs()->unparse());
}
else else
return false; return false;
if (strDimLength == "0") if (dimLength == 0)
return false; return false;
declaredDims.push_back((uint64_t)stoi(strDimLength)); declaredDims.push_back(dimLength);
} }
return true; return true;
} }
static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym)
{
if (!arrSym)
return nullptr;
for (auto& [key, val] : declaredArrays)
{
DIST::Array* distArr = val.first;
if (!distArr)
continue;
Symbol* declSym = distArr->GetDeclSymbol();
if (!declSym)
continue;
SgSymbol* sgDecl = declSym->GetOriginal();
if (sgDecl && isEqSymbols(sgDecl, arrSym))
return distArr;
}
return nullptr;
}
static bool CheckDimensionLength(const AccessingSet& array) static bool CheckDimensionLength(const AccessingSet& array)
{ {
if (array.GetElements().empty()) if (array.GetElements().empty())
return false; return false;
size_t dimCount = array.GetElements()[0].size(); size_t dimCount = array.GetElements()[0].size();
SgArrayRefExp* arrayRef = array.GetElements()[0][0].array; SgArrayRefExp* arrayRef = array.GetElements()[0][0].array;
if (!arrayRef) if (!arrayRef || !arrayRef->symbol())
return false; return false;
vector<uint64_t> declaredDims(dimCount);
if (!getArrayDeclaredDimensions(arrayRef, declaredDims)) vector<uint64_t> declaredDims;
return false; declaredDims.reserve(dimCount);
vector<ArrayDimension> testArray(dimCount);
for (size_t i = 0; i < dimCount; i++) DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol());
if (distArr && distArr->GetDimSize() == (int)dimCount)
{ {
testArray[i] = { 1, 1, declaredDims[i], nullptr }; const auto& sizes = distArr->GetSizes();
bool valid = true;
for (size_t i = 0; i < dimCount && valid; ++i)
{
int lo = sizes[i].first;
int hi = sizes[i].second;
if (lo > hi)
valid = false;
else
declaredDims.push_back((uint64_t)(hi - lo + 1));
}
if (valid && declaredDims.size() == dimCount)
{
vector<ArrayDimension> testArray(dimCount);
for (size_t i = 0; i < dimCount; i++)
testArray[i] = { 1, 1, declaredDims[i], nullptr };
return AccessingSet({ testArray }).Diff(array).GetElements().empty();
}
} }
AccessingSet diff = AccessingSet({ testArray }).Diff(array);
return diff.GetElements().empty(); return false;
} }
static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set<SgStatement*>& insertedPrivates) static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set<SgStatement*>& insertedPrivates)
{ {
SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR); SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR);
@@ -334,6 +380,7 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes&
spfStat->setFileName(loop->loop->fileName()); spfStat->setFileName(loop->loop->fileName());
SgExpression* toAdd = new SgExpression(EXPR_LIST, new SgExpression(ACC_PRIVATE_OP), NULL, NULL); SgExpression* toAdd = new SgExpression(EXPR_LIST, new SgExpression(ACC_PRIVATE_OP), NULL, NULL);
set<SgSymbol*> arraysToInsert; set<SgSymbol*> arraysToInsert;
std::cout << "First bp\n";
for (const auto& [_, accessingSet] : privates) for (const auto& [_, accessingSet] : privates)
{ {
if (!CheckDimensionLength(accessingSet)) if (!CheckDimensionLength(accessingSet))
@@ -391,7 +438,15 @@ void FindPrivateArrays(map<string, vector<LoopGraph*>>& loopGraph, map<FuncInfo*
{ {
if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func) if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func)
{ {
Region* loopRegion = new Region(loop, blocks); Region* loopRegion;
try
{
loopRegion = new Region(loop, blocks);
}
catch (...)
{
continue;
}
if (loopRegion->getBasickBlocks().size() <= 1) if (loopRegion->getBasickBlocks().size() <= 1)
{ {
delete(loopRegion); delete(loopRegion);
@@ -403,9 +458,24 @@ void FindPrivateArrays(map<string, vector<LoopGraph*>>& loopGraph, map<FuncInfo*
delete(loopRegion); delete(loopRegion);
} }
} }
if (result.find(loop) != result.end() && !result[loop].empty()) if (result.find(loop) != result.end() && !result[loop].empty())
AddPrivateArraysToLoop(loop, result[loop], insertedPrivates); AddPrivateArraysToLoop(loop, result[loop], insertedPrivates);
} }
} }
for (SgStatement* st : statementsToRemove)
{
SgFile::switchToFile(st->fileName());
st->deleteStmt();
}
for (auto& [filename, statements] : expToChange)
{
SgFile::switchToFile(filename);
for (auto& [statement, statementCopy] : statements)
{
statement->insertStmtBefore(*statementCopy, *statement->controlParent());
statement->deleteStmt();
}
}
} }

View File

@@ -150,6 +150,8 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
vector<ArrayDimension> accessPoint(n); vector<ArrayDimension> accessPoint(n);
auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression());
if (!ref)
continue;
int fillCount = 0; int fillCount = 0;
vector<pair<int, int>> coeffsForDims; vector<pair<int, int>> coeffsForDims;
@@ -204,7 +206,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
current_dim = { start, step, iters, ref }; current_dim = { start, step, iters, ref };
} }
if (current_dim.start != 0 && current_dim.step != 0 && current_dim.tripCount != 0) if (current_dim.step != 0 && current_dim.tripCount != 0)
{ {
accessPoint[n - index_vars.size()] = current_dim; accessPoint[n - index_vars.size()] = current_dim;
fillCount++; fillCount++;
@@ -267,13 +269,30 @@ static void DFS(Region* block, vector<Region*>& result, unordered_set<Region*> c
result.push_back(block); result.push_back(block);
} }
void TopologySort(std::vector<Region*>& basikBlocks, Region* header) bool HasCycle(Region* block, const std::unordered_set<Region*>& cycleBlocks, std::unordered_set<Region*>& visitedBlocks)
{
if (visitedBlocks.find(block) != visitedBlocks.end())
return true;
visitedBlocks.insert(block);
for (Region* nextBlock : block->getNextRegions())
{
if (cycleBlocks.find(nextBlock) != cycleBlocks.end() && HasCycle(nextBlock, cycleBlocks, visitedBlocks))
return true;
}
return false;
}
bool TopologySort(std::vector<Region*>& basikBlocks, Region* header)
{ {
vector<Region*> result;
unordered_set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end()); unordered_set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end());
unordered_set<Region*> visitedBlocks;
if (HasCycle(header, cycleBlocks, visitedBlocks))
return false;
vector<Region*> result;
DFS(header, result, cycleBlocks); DFS(header, result, cycleBlocks);
reverse(result.begin(), result.end()); reverse(result.begin(), result.end());
basikBlocks = result; basikBlocks = move(result);
return true;
} }
static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet) static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet)
@@ -313,7 +332,8 @@ static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*
continue; continue;
region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion));
} }
TopologySort(region->getBasickBlocks(), region->getHeader()); if (!TopologySort(region->getBasickBlocks(), region->getHeader()))
throw std::runtime_error("Unnoticed cycle");
return region; return region;
} }
@@ -337,6 +357,7 @@ Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks)
if (!childLoop->isFor()) if (!childLoop->isFor())
continue; continue;
subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion));
} }
TopologySort(basickBlocks, this->header); if (!TopologySort(basickBlocks, this->header))
throw std::runtime_error("Unnoticed cycle");
} }

View File

@@ -79,4 +79,6 @@ private:
Region* header; Region* header;
}; };
void TopologySort(std::vector<Region*>& basikBlocks, Region* header); bool HasCycle(Region* block, const std::unordered_set<Region*>& cycleBlocks, std::unordered_set<Region*>& visitedBlocks);
bool TopologySort(std::vector<Region*>& basikBlocks, Region* header);

View File

@@ -1,4 +1,4 @@
#include "Utils/leak_detector.h" #include "Utils/leak_detector.h"
#pragma comment(linker, "/STACK:536870912") // 512 МБ #pragma comment(linker, "/STACK:536870912") // 512 МБ
@@ -943,7 +943,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, loopGraph, fullIR, countOfTransform); moveOperators(file, fullIR, 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

@@ -1089,6 +1089,8 @@ static int clean(const string& funcName, SgStatement* funcSt, const map<string,
} }
SgGotoStmt* gotoSt = new SgGotoStmt(*contLab); SgGotoStmt* gotoSt = new SgGotoStmt(*contLab);
if (st->label())
gotoSt->setLabel(*st->label());
st->insertStmtBefore(*gotoSt, *st->controlParent()); st->insertStmtBefore(*gotoSt, *st->controlParent());
toDelete.push_back(st); toDelete.push_back(st);

View File

@@ -1,10 +1,8 @@
#include <map> #include <map>
#include <set> #include <set>
#include <vector> #include <vector>
#include <queue>
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
#include <limits>
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
@@ -19,7 +17,10 @@
using namespace std; using namespace std;
string getNameByArg(SAPFOR::Argument* arg); set<int> loop_tags = {FOR_NODE};
set<int> control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE};
set<int> control_end_tags = {CONTROL_END};
static vector<SAPFOR::IR_Block*> findInstructionsFromStatement(SgStatement* st, const vector<SAPFOR::BasicBlock*>& blocks) static vector<SAPFOR::IR_Block*> findInstructionsFromStatement(SgStatement* st, const vector<SAPFOR::BasicBlock*>& blocks)
{ {
@@ -49,642 +50,27 @@ static vector<SAPFOR::IR_Block*> findInstructionsFromStatement(SgStatement* st,
return result; return result;
} }
set<int> loop_tags = {FOR_NODE};
set<int> control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE};
set<int> control_end_tags = {CONTROL_END};
static bool isBarrierIR(const SAPFOR::Instruction* instr)
{
if (!instr)
return true;
using SAPFOR::CFG_OP;
const auto op = instr->getOperation();
switch (op)
{
case CFG_OP::F_CALL:
case CFG_OP::STORE:
case CFG_OP::REC_REF_STORE:
case CFG_OP::IO_PARAM:
case CFG_OP::DVM_DIR:
case CFG_OP::SPF_DIR:
case CFG_OP::POINTER_ASS:
case CFG_OP::EXIT:
return true;
default:
return false;
}
}
static bool isMovableStmtIR(const vector<SAPFOR::IR_Block*>& irs,
set<SAPFOR::Argument*>& uses,
set<SAPFOR::Argument*>& defs,
bool& spansMultipleBB)
{
uses.clear();
defs.clear();
spansMultipleBB = false;
if (irs.empty())
return false;
SAPFOR::BasicBlock* bb = irs.front()->getBasicBlock();
for (auto* ir : irs)
if (ir && ir->getBasicBlock() != bb)
spansMultipleBB = true;
for (auto* ir : irs)
{
if (!ir || !ir->getInstruction())
return false;
const auto* instr = ir->getInstruction();
if (isBarrierIR(instr))
return false;
auto addUse = [&](SAPFOR::Argument* a)
{
if (!a)
return;
if (a->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
uses.insert(a);
else if (a->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY || a->getType() == SAPFOR::CFG_ARG_TYPE::RECORD)
uses.insert(a);
};
auto addDef = [&](SAPFOR::Argument* a)
{
if (!a)
return;
if (a->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
defs.insert(a);
else if (a->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY || a->getType() == SAPFOR::CFG_ARG_TYPE::RECORD)
defs.insert(a);
};
addUse(instr->getArg1());
addUse(instr->getArg2());
addDef(instr->getResult());
}
for (auto* a : uses)
if (a && (a->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY || a->getType() == SAPFOR::CFG_ARG_TYPE::RECORD))
return false;
for (auto* a : defs)
if (a && (a->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY || a->getType() == SAPFOR::CFG_ARG_TYPE::RECORD))
return false;
if (spansMultipleBB)
return false;
if (defs.empty())
return false;
return true;
}
static bool isStatementEmbedded(SgStatement* stmt, SgStatement* parent) {
if (!stmt || !parent || stmt == parent)
return false;
if (parent->variant() == LOGIF_NODE) {
if (stmt->lineNumber() == parent->lineNumber())
return true;
SgStatement* current = parent;
SgStatement* lastNode = parent->lastNodeOfStmt();
while (current && current != lastNode) {
if (current == stmt)
return true;
if (current->isIncludedInStmt(*stmt))
return true;
current = current->lexNext();
}
}
if (parent->isIncludedInStmt(*stmt))
return true;
return false;
}
static bool isLoopBoundary(SgStatement* stmt) {
if (!stmt)
return false;
if (stmt->variant() == FOR_NODE || stmt->variant() == CONTROL_END)
return true;
return false;
}
static bool isPartOfNestedLoop(SgStatement* stmt, SgForStmt* loop) {
if (!stmt || !loop)
return false;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (!loopStart || !loopEnd)
return false;
if (stmt->lineNumber() < loopStart->lineNumber() || stmt->lineNumber() > loopEnd->lineNumber())
return false;
SgStatement* current = loopStart;
while (current && current != loopEnd) {
if (current->variant() == FOR_NODE && current != loop) {
SgForStmt* nestedLoop = (SgForStmt*)current;
SgStatement* nestedStart = nestedLoop->lexNext();
SgStatement* nestedEnd = nestedLoop->lastNodeOfStmt();
if (nestedStart && nestedEnd &&
stmt->lineNumber() >= nestedStart->lineNumber() &&
stmt->lineNumber() <= nestedEnd->lineNumber()) {
return true;
}
}
current = current->lexNext();
}
return false;
}
static bool canSafelyExtract(SgStatement* stmt, SgForStmt* loop) {
if (!stmt || !loop)
return false;
if (isLoopBoundary(stmt))
return false;
if (control_tags.find(stmt->variant()) != control_tags.end())
return false;
if (isPartOfNestedLoop(stmt, loop))
return false;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (!loopStart || !loopEnd)
return false;
SgStatement* current = loopStart;
while (current && current != loopEnd) {
if (current->variant() == LOGIF_NODE && current->lineNumber() == stmt->lineNumber())
return false;
if (control_tags.find(current->variant()) != control_tags.end())
if (isStatementEmbedded(stmt, current))
return false;
if (current == stmt)
break;
current = current->lexNext();
}
return true;
}
namespace
{
struct StmtInfo
{
SgStatement* stmt = nullptr;
SAPFOR::BasicBlock* bb = nullptr;
int firstInstr = std::numeric_limits<int>::max();
int lastInstr = std::numeric_limits<int>::min();
vector<SAPFOR::IR_Block*> irs;
set<SAPFOR::Argument*> uses;
set<SAPFOR::Argument*> defs;
};
using RDState = map<SAPFOR::Argument*, set<int>>;
static void killGlobalsAndParams(RDState& st)
{
for (auto it = st.begin(); it != st.end();)
{
SAPFOR::Argument* a = it->first;
if (!a)
{
it = st.erase(it);
continue;
}
const bool kill = a->isMemGlobal() || a->isParameter();
if (kill)
it = st.erase(it);
else
++it;
}
}
static void transferRD(RDState& st, const SAPFOR::Instruction* instr)
{
if (!instr)
return;
if (isBarrierIR(instr))
{
killGlobalsAndParams(st);
return;
}
using SAPFOR::CFG_OP;
const auto op = instr->getOperation();
if (op == CFG_OP::ASSIGN || op == CFG_OP::LOAD)
{
SAPFOR::Argument* res = instr->getResult();
if (res && res->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
st[res] = { instr->getNumber() };
}
}
static RDState computeRD_BeforeInstr(const SAPFOR::BasicBlock* bb, int beforeInstrNum)
{
RDState st;
if (!bb)
return st;
st = bb->getRD_In();
for (auto* ir : bb->getInstructions())
{
if (!ir || !ir->getInstruction())
continue;
if (ir->getNumber() >= beforeInstrNum)
break;
transferRD(st, ir->getInstruction());
}
return st;
}
static bool topoSchedule(const vector<SgStatement*>& original,
const vector<vector<int>>& succ,
const vector<int>& indegInit,
vector<SgStatement*>& scheduled)
{
const int n = (int)original.size();
scheduled.clear();
scheduled.reserve(n);
vector<int> indeg = indegInit;
vector<int> maxPredPos(n, 0);
struct Node
{
int idx;
int keyMaxPredPos;
};
struct Cmp
{
bool operator()(const Node& a, const Node& b) const
{
if (a.keyMaxPredPos != b.keyMaxPredPos)
return a.keyMaxPredPos < b.keyMaxPredPos;
return a.idx > b.idx;
}
};
std::priority_queue<Node, vector<Node>, Cmp> ready;
for (int i = 0; i < n; ++i)
if (indeg[i] == 0)
ready.push(Node{ i, 0 });
int outPos = 0;
while (!ready.empty())
{
Node cur = ready.top();
ready.pop();
const int u = cur.idx;
scheduled.push_back(original[u]);
++outPos;
for (int v : succ[u])
{
maxPredPos[v] = std::max(maxPredPos[v], outPos);
if (--indeg[v] == 0)
ready.push(Node{ v, maxPredPos[v] });
}
}
return (int)scheduled.size() == n;
}
static bool applyReorderContiguous(SgForStmt* loop,
const vector<SgStatement*>& oldOrder,
const vector<SgStatement*>& newOrder)
{
if (!loop || oldOrder.size() != newOrder.size() || oldOrder.size() < 2)
return false;
bool changed = false;
for (size_t i = 0; i < oldOrder.size(); ++i)
if (oldOrder[i] != newOrder[i])
{
changed = true;
break;
}
if (!changed)
return false;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (!loopStart || !loopEnd)
return false;
SgStatement* first = oldOrder.front();
SgStatement* anchor = loop;
for (SgStatement* cur = loopStart; cur && cur != loopEnd; cur = cur->lexNext())
{
if (cur == first)
break;
anchor = cur;
}
map<SgStatement*, int> savedLine;
map<SgStatement*, char*> savedComments;
map<SgStatement*, SgStatement*> extracted;
for (SgStatement* st : oldOrder)
{
if (!st || st == loop || st == loopEnd)
return false;
if (!canSafelyExtract(st, loop))
return false;
savedLine[st] = st->lineNumber();
savedComments[st] = st->comments() ? strdup(st->comments()) : nullptr;
SgStatement* ex = st->extractStmt();
if (!ex)
return false;
extracted[st] = ex;
}
SgStatement* insertAfter = anchor;
for (SgStatement* st : newOrder)
{
SgStatement* ex = extracted[st];
if (!ex)
continue;
auto itC = savedComments.find(st);
if (itC != savedComments.end() && itC->second)
ex->setComments(itC->second);
auto itL = savedLine.find(st);
if (itL != savedLine.end())
ex->setlineNumber(itL->second);
insertAfter->insertStmtAfter(*ex, *loop);
insertAfter = ex;
}
for (auto& kv : savedComments)
if (kv.second)
free(kv.second);
return true;
}
}
static bool reorderMovableRegionsInLoop(SgForStmt* loop, const vector<SAPFOR::BasicBlock*>& blocks)
{
if (!loop)
return false;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (!loopStart || !loopEnd)
return false;
bool anyChange = false;
vector<SgStatement*> region;
auto flushRegion = [&]() {
if (region.size() < 2)
{
region.clear();
return;
}
vector<StmtInfo> infos;
infos.reserve(region.size());
map<SgStatement*, int> idxOf;
map<int, int> defInstrToIdx;
for (int i = 0; i < (int)region.size(); ++i)
{
SgStatement* st = region[i];
idxOf[st] = i;
StmtInfo info;
info.stmt = st;
info.irs = findInstructionsFromStatement(st, blocks);
if (info.irs.empty())
{
infos.clear();
region.clear();
return;
}
info.bb = info.irs.front()->getBasicBlock();
for (auto* ir : info.irs)
{
info.firstInstr = std::min(info.firstInstr, ir->getNumber());
info.lastInstr = std::max(info.lastInstr, ir->getNumber());
const auto* instr = ir->getInstruction();
if (!instr)
continue;
if (instr->getResult() && instr->getResult()->getType() == SAPFOR::CFG_ARG_TYPE::VAR &&
(instr->getOperation() == SAPFOR::CFG_OP::ASSIGN || instr->getOperation() == SAPFOR::CFG_OP::LOAD))
{
defInstrToIdx[instr->getNumber()] = i;
}
}
bool spansMultiple = false;
if (!isMovableStmtIR(info.irs, info.uses, info.defs, spansMultiple) || spansMultiple)
{
infos.clear();
region.clear();
return;
}
infos.push_back(std::move(info));
}
const int n = (int)infos.size();
vector<vector<int>> succ(n);
vector<int> indeg(n, 0);
auto addEdge = [&](int u, int v) {
if (u == v)
return;
succ[u].push_back(v);
indeg[v]++;
};
for (int i = 0; i < n; ++i)
{
const StmtInfo& cur = infos[i];
RDState stRD = computeRD_BeforeInstr(cur.bb, cur.firstInstr);
for (SAPFOR::Argument* use : cur.uses)
{
if (!use || use->getType() != SAPFOR::CFG_ARG_TYPE::VAR)
continue;
auto it = stRD.find(use);
if (it == stRD.end())
continue;
for (int defInstr : it->second)
{
if (defInstr < 0)
continue;
auto itDef = defInstrToIdx.find(defInstr);
if (itDef != defInstrToIdx.end())
addEdge(itDef->second, i);
}
}
}
map<SAPFOR::Argument*, vector<int>> defsByVar;
for (int i = 0; i < n; ++i)
for (auto* d : infos[i].defs)
if (d && d->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
defsByVar[d].push_back(i);
for (auto& kv : defsByVar)
{
auto& list = kv.second;
sort(list.begin(), list.end());
list.erase(unique(list.begin(), list.end()), list.end());
for (int k = 0; k + 1 < (int)list.size(); ++k)
addEdge(list[k], list[k + 1]);
}
map<SAPFOR::Argument*, vector<int>> defPositions;
for (auto& kv : defsByVar)
defPositions[kv.first] = kv.second;
for (int i = 0; i < n; ++i)
{
for (SAPFOR::Argument* use : infos[i].uses)
{
if (!use || use->getType() != SAPFOR::CFG_ARG_TYPE::VAR)
continue;
auto itDefs = defPositions.find(use);
if (itDefs == defPositions.end())
continue;
const auto& dpos = itDefs->second;
auto it = std::upper_bound(dpos.begin(), dpos.end(), i);
if (it != dpos.end())
addEdge(i, *it);
}
}
for (int u = 0; u < n; ++u)
{
auto& out = succ[u];
sort(out.begin(), out.end());
out.erase(unique(out.begin(), out.end()), out.end());
}
fill(indeg.begin(), indeg.end(), 0);
for (int u = 0; u < n; ++u)
for (int v : succ[u])
indeg[v]++;
vector<SgStatement*> scheduled;
vector<SgStatement*> original = region;
if (!topoSchedule(original, succ, indeg, scheduled))
{
region.clear();
return;
}
if (applyReorderContiguous(loop, original, scheduled))
anyChange = true;
region.clear();
};
SgStatement* current = loopStart;
set<SgStatement*> visited;
while (current && current != loopEnd)
{
if (!visited.insert(current).second)
break;
if (isLoopBoundary(current))
{
flushRegion();
current = current->lexNext();
continue;
}
if (current->variant() == FOR_NODE && current != loop)
{
flushRegion();
SgStatement* nestedEnd = current->lastNodeOfStmt();
current = nestedEnd ? nestedEnd->lexNext() : current->lexNext();
continue;
}
if (!isSgExecutableStatement(current) || control_tags.count(current->variant()))
{
flushRegion();
current = current->lexNext();
continue;
}
const bool isTopLevel = (current->controlParent() == loop);
if (isTopLevel && current->variant() == ASSIGN_STAT && canSafelyExtract(current, loop))
{
auto irs = findInstructionsFromStatement(current, blocks);
set<SAPFOR::Argument*> uses, defs;
bool spansMultiple = false;
if (isMovableStmtIR(irs, uses, defs, spansMultiple) && !spansMultiple)
{
region.push_back(current);
current = current->lexNext();
continue;
}
}
flushRegion();
current = current->lexNext();
}
flushRegion();
return anyChange;
}
vector<SAPFOR::BasicBlock*> findFuncBlocksByFuncStatement(SgStatement *st, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) { vector<SAPFOR::BasicBlock*> findFuncBlocksByFuncStatement(SgStatement *st, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) {
vector<SAPFOR::BasicBlock*> result; vector<SAPFOR::BasicBlock*> result;
if (!st)
return result;
Statement* forSt = (Statement*)st; Statement* forSt = (Statement*)st;
const string stmtFile = st->fileName();
const int stmtLine = st->lineNumber();
for (auto& func: FullIR) { for (auto& func: FullIR) {
if (func.first->funcPointer->getCurrProcessFile() == forSt->getCurrProcessFile() if (!func.first || !func.first->funcPointer)
&& func.first->funcPointer->lineNumber() == forSt->lineNumber()) continue;
const string funcFile = func.first->fileName;
const int funcLine = func.first->funcPointer->lineNumber();
// Important: select CFG blocks only for the same file and function header.
if (funcFile == stmtFile && funcLine == stmtLine)
{ {
result = func.second; result = func.second;
break;
} }
} }
return result; return result;
@@ -721,34 +107,6 @@ map<SgForStmt*, vector<SAPFOR::BasicBlock*>> findAndAnalyzeLoops(SgStatement *st
return result; return result;
} }
static void processLoopRecursively(SgForStmt* loop, const vector<SAPFOR::BasicBlock*>& blocks,
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) {
if (!loop)
return;
SgStatement* loopStart = loop->lexNext();
SgStatement* loopEnd = loop->lastNodeOfStmt();
if (loopStart && loopEnd) {
SgStatement* current = loopStart;
while (current && current != loopEnd) {
if (current->variant() == FOR_NODE && current != loop) {
SgForStmt* nestedLoop = (SgForStmt*)current;
processLoopRecursively(nestedLoop, blocks, FullIR);
SgStatement* nestedEnd = nestedLoop->lastNodeOfStmt();
if (nestedEnd)
current = nestedEnd->lexNext();
else
current = current->lexNext();
}
else
current = current->lexNext();
}
}
reorderMovableRegionsInLoop(loop, blocks);
}
vector<SAPFOR::BasicBlock*> findBlocksInLoopsByFullIR( vector<SAPFOR::BasicBlock*> findBlocksInLoopsByFullIR(
SgStatement* funcStmt, SgStatement* funcStmt,
@@ -813,40 +171,60 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
if (!instr) if (!instr)
return string(); return string();
SgExpression* ex = instr->getExpression(); SgExpression* ex = instr->getExpression();
if (!ex || !ex->unparse()) if (!ex)
return string(); return string();
auto normalizeExprText = [](const string& raw) -> string
{
string t;
t.reserve(raw.size());
for (unsigned char c : raw)
if (!std::isspace(c))
t.push_back((char)c);
auto stripOneLayer = [](const string& x) -> string auto exprKey = [&](auto&& self, SgExpression* e) -> string
{
if (!e)
return string("_");
if (auto* ar = isSgArrayRefExp(e))
{ {
if (x.size() < 2 || x.front() != '(' || x.back() != ')') SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr;
return x; string key = string("A(") + (sym ? sym->identifier() : "?");
int bal = 0; const int n = ar->numberOfSubscripts();
for (size_t i = 0; i + 1 < x.size(); ++i) for (int i = 0; i < n; ++i)
{ {
if (x[i] == '(') bal++; key += ",";
else if (x[i] == ')') bal--; key += self(self, ar->subscript(i));
if (bal == 0 && i + 1 < x.size() - 1)
return x;
} }
return x.substr(1, x.size() - 2); key += ")";
}; return key;
while (true)
{
const string stripped = stripOneLayer(t);
if (stripped == t)
break;
t = stripped;
} }
return t;
if (e->variant() == VAR_REF || e->variant() == CONST_REF)
{
SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr;
return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")";
}
if (auto* v = isSgValueExp(e))
{
if (e->variant() == INT_VAL)
return string("I(") + to_string(v->intValue()) + ")";
if (e->variant() == BOOL_VAL)
return string("B(") + (v->boolValue() ? "1" : "0") + ")";
if (e->variant() == CHAR_VAL)
return string("CH(") + string(1, v->charValue()) + ")";
if (e->variant() == FLOAT_VAL)
return string("F(") + (v->floatValue() ? v->floatValue() : "") + ")";
if (e->variant() == DOUBLE_VAL)
return string("D(") + (v->doubleValue() ? v->doubleValue() : "") + ")";
if (e->variant() == STRING_VAL)
return string("S(") + (v->stringValue() ? v->stringValue() : "") + ")";
}
string key = string("N(") + to_string(e->variant());
if (e->lhs())
key += ",L=" + self(self, e->lhs());
if (e->rhs())
key += ",R=" + self(self, e->rhs());
key += ")";
return key;
}; };
return "MEMEX#" + normalizeExprText(ex->unparse());
return "MEMEX#" + exprKey(exprKey, ex);
}; };
auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool
@@ -949,6 +327,9 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
addDep(instr->getArg1()); addDep(instr->getArg1());
addDep(instr->getArg2()); addDep(instr->getArg2());
if (instr->getOperation() == SAPFOR::CFG_OP::RANGE)
addDep(instr->getResult());
if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)
addDep(instr->getResult()); addDep(instr->getResult());
@@ -996,7 +377,7 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
return result; return result;
} }
static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb) static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const char* expectedFile)
{ {
if (!bb) if (!bb)
return false; return false;
@@ -1026,6 +407,18 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
if (ops.size() < 2) if (ops.size() < 2)
return false; return false;
// Check that analyzed BB is in the same file as the expected file
const char* bbFile = ops.front()->fileName();
if (!bbFile)
bbFile = "(unknown)";
if (expectedFile && strcmp(expectedFile, bbFile) != 0)
return false;
for (auto* st : ops)
{
if (!st || !st->fileName() || strcmp(st->fileName(), bbFile) != 0)
return false;
}
SgStatement* parent = ops.front()->controlParent(); SgStatement* parent = ops.front()->controlParent();
if (!parent) if (!parent)
return false; return false;
@@ -1078,59 +471,45 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
const auto depsMap = analyzeBasicBlockIntraDependencies(bb); const auto depsMap = analyzeBasicBlockIntraDependencies(bb);
vector<SgStatement*> order = ops; vector<SgStatement*> order = ops;
auto buildPos = [&](const vector<SgStatement*>& v) auto indexIn = [](const vector<SgStatement*>& v, SgStatement* s) -> int
{ {
map<SgStatement*, int> pos;
for (int i = 0; i < (int)v.size(); ++i) for (int i = 0; i < (int)v.size(); ++i)
pos[v[i]] = i; if (v[i] == s)
return pos; return i;
return -1;
}; };
const int maxIterations = (int)order.size() * (int)order.size() + 10; for (SgStatement* s : ops)
bool anyMove = false;
for (int iter = 0; iter < maxIterations; ++iter)
{ {
bool movedThisIter = false; auto itDeps = depsMap.find(s);
const auto pos = buildPos(order); if (itDeps == depsMap.end() || itDeps->second.empty())
continue;
for (int i = 0; i < (int)order.size(); ++i) int posS = indexIn(order, s);
if (posS < 0)
continue;
int lastDepIdx = -1;
for (SgStatement* dep : itDeps->second)
{ {
SgStatement* curSt = order[i]; const int j = indexIn(order, dep);
auto it = depsMap.find(curSt); if (j >= 0)
if (it == depsMap.end() || it->second.empty()) lastDepIdx = max(lastDepIdx, j);
continue;
int lastDepIdx = -1;
for (SgStatement* dep : it->second)
{
auto itP = pos.find(dep);
if (itP != pos.end())
lastDepIdx = max(lastDepIdx, itP->second);
}
if (lastDepIdx < 0)
continue;
int target = lastDepIdx + 1;
if (target == i)
continue;
SgStatement* moved = order[i];
order.erase(order.begin() + i);
if (target > i)
target -= 1;
if (target < 0)
target = 0;
if (target > (int)order.size())
target = (int)order.size();
order.insert(order.begin() + target, moved);
movedThisIter = true;
anyMove = true;
break;
} }
if (lastDepIdx < 0)
continue;
if (!movedThisIter) if (posS == lastDepIdx + 1)
break; continue;
order.erase(order.begin() + posS);
int lp = lastDepIdx;
if (posS < lastDepIdx)
lp = lastDepIdx - 1;
const int insertAt = lp + 1;
order.insert(order.begin() + insertAt, s);
} }
bool changed = false; bool changed = false;
@@ -1201,17 +580,14 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
return true; return true;
} }
void moveOperators(SgFile *file, map<string, vector<LoopGraph*>>& loopGraph, void moveOperators(SgFile* file, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform) {
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR,
int& countOfTransform) {
// countOfTransform += 1;
if (!file) if (!file)
return; return;
if (SgFile::switchToFile(file->filename()) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const int funcNum = file->numberOfFunctions(); const int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i)
for (int i = 0; i < funcNum; ++i) { {
SgStatement* st = file->functions(i); SgStatement* st = file->functions(i);
const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR); const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR);
@@ -1219,14 +595,8 @@ void moveOperators(SgFile *file, map<string, vector<LoopGraph*>>& loopGraph,
{ {
if (!bb) if (!bb)
continue; continue;
if (reorderOperatorsInBasicBlockUsingDeps(bb)) if (reorderOperatorsInBasicBlockUsingDeps(bb, file->filename()))
countOfTransform += 1; countOfTransform += 1;
} }
// vector<SAPFOR::BasicBlock*> blocks = findFuncBlocksByFuncStatement(st, FullIR);
// map<SgForStmt*, vector<SAPFOR::BasicBlock*>> loopsMapping = findAndAnalyzeLoops(st, blocks);
// for (auto& loopForAnalyze : loopsMapping)
// processLoopRecursively(loopForAnalyze.first, loopForAnalyze.second, FullIR);
} }
} }

View File

@@ -3,4 +3,4 @@
#include "../../GraphLoop/graph_loops.h" #include "../../GraphLoop/graph_loops.h"
#include "../../CFGraph/CFGraph.h" #include "../../CFGraph/CFGraph.h"
void moveOperators(SgFile *file, std::map<std::string, std::vector<LoopGraph*>>& loopGraph, const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform); void moveOperators(SgFile* file, const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform);

View File

@@ -504,7 +504,7 @@ static void replaceArrayInFragment(SgSymbol* replace_symb,
} }
} }
static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound) static bool ioRegionBorder(SgStatement* stat, SgStatement* last_io_bound)
{ {
auto var = stat->variant(); auto var = stat->variant();
@@ -535,14 +535,24 @@ static bool ioReginBorder(SgStatement* stat, SgStatement* last_io_bound)
if (last_io_bound && last_io_bound->lastNodeOfStmt() && last_io_bound->lastNodeOfStmt() == stat) if (last_io_bound && last_io_bound->lastNodeOfStmt() && last_io_bound->lastNodeOfStmt() == stat)
return true; return true;
int parent_var;
if (var == CONTROL_END && border_stats.find(stat->controlParent()->variant()) != border_stats.end()) if (var == CONTROL_END && border_stats.find(stat->controlParent()->variant()) != border_stats.end())
return true; return true;
return false; return false;
} }
FuncInfo* getCurrentFuncInfo(const vector<FuncInfo*>& fileFuncInfo, int line)
{
for (auto* func : fileFuncInfo)
{
if (func->linesNum.first <= line && line <= func->linesNum.second)
return func;
}
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return NULL;
}
void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions, void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
const map<string, vector<FuncInfo*>>& allFuncInfo, const map<string, vector<FuncInfo*>>& allFuncInfo,
map<string, vector<Messages>>& SPF_messages, map<string, vector<Messages>>& SPF_messages,
@@ -562,6 +572,8 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
if (SgFile::switchToFile(current_file_name) == -1) if (SgFile::switchToFile(current_file_name) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
FuncInfo *current_func_info = NULL;
auto func_info_it = allFuncInfo.find(current_file_name); auto func_info_it = allFuncInfo.find(current_file_name);
if (func_info_it == allFuncInfo.end()) if (func_info_it == allFuncInfo.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -588,13 +600,12 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
{ {
curr_stmt = lines.stats.first->GetOriginal(); curr_stmt = lines.stats.first->GetOriginal();
end = lines.stats.second->GetOriginal()->lexNext(); end = lines.stats.second->GetOriginal()->lexNext();
current_func_info = getCurrentFuncInfo(func_info_it->second, curr_stmt->lineNumber());
} }
map<SgSymbol*, set<SgStatement*>> need_replace; map<SgSymbol*, set<SgStatement*>> need_replace;
SgStatement* last_io_bound = NULL; SgStatement* last_io_bound = NULL;
FuncInfo *current_func_info = NULL;
while (curr_stmt != end) while (curr_stmt != end)
{ {
if (!curr_stmt) if (!curr_stmt)
@@ -604,18 +615,7 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
if (var == PROC_HEDR || var == PROG_HEDR || var == FUNC_HEDR) if (var == PROC_HEDR || var == PROG_HEDR || var == FUNC_HEDR)
{ {
current_func_info = NULL; current_func_info = getCurrentFuncInfo(func_info_it->second, curr_stmt->lineNumber());
for (auto *func_info : func_info_it->second)
{
if (func_info->funcName == curr_stmt->symbol()->identifier())
{
current_func_info = func_info;
break;
}
}
if (!current_func_info)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
curr_stmt = curr_stmt->lexNext(); curr_stmt = curr_stmt->lexNext();
while (curr_stmt && !isSgExecutableStatement(curr_stmt)) while (curr_stmt && !isSgExecutableStatement(curr_stmt))
@@ -628,7 +628,7 @@ void replaceDistributedArraysInIO(vector<ParallelRegion*>& regions,
break; break;
} }
if (ioReginBorder(curr_stmt, last_io_bound)) if (ioRegionBorder(curr_stmt, last_io_bound))
{ {
for (const auto& by_array_to_copy : need_replace) for (const auto& by_array_to_copy : need_replace)
{ {

View File

@@ -318,7 +318,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE); list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE);
list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS); list({ ARRAY_PROPAGATION, CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS_ANALYSIS);
list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS); list({ FIND_PRIVATE_ARRAYS_ANALYSIS, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(FIND_PRIVATE_ARRAYS);
list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS); list({ BUILD_IR, CALL_GRAPH2, RESTORE_LOOP_FROM_ASSIGN, REVERT_SUBST_EXPR_RD }) <= Pass(MOVE_OPERATORS);

View File

@@ -658,7 +658,7 @@ string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const ch
if (wasDeleted) if (wasDeleted)
{ {
if (str.size() || str.back() != '\n') if (str.size() && str.back() != '\n')
str += '\n'; str += '\n';
st->setComments(str.c_str()); st->setComments(str.c_str());
} }

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_SPF "2468" #define VERSION_SPF "2476"