improved ROUTINE insertion

This commit is contained in:
ALEXks
2025-01-11 09:32:17 +03:00
parent f3f7368bdc
commit b0df33e926
5 changed files with 222 additions and 32 deletions

View File

@@ -104,7 +104,7 @@ void DvmhRegionInserter::parFuncsInNode(LoopGraph *loop, bool isParallel)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
else
parallel_functions.insert(it->second);
parallel_functions[it->second].insert(loop);
}
}
else
@@ -133,23 +133,36 @@ void DvmhRegionInserter::updateParallelFunctions(const map<string, vector<LoopGr
while (changes_done)
{
changes_done = false;
set<FuncInfo*> newList;
map<FuncInfo*, set<LoopGraph*>> newList;
for (auto& funcPair : allFunctions)
{
FuncInfo* func = funcPair.second;
for (auto& callsTo : func->callsTo)
{
if (parallel_functions.find(callsTo) != parallel_functions.end() &&
parallel_functions.find(func) == parallel_functions.end())
auto itF = parallel_functions.find(func);
set<LoopGraph*> added;
if (itF != parallel_functions.end())
added = itF->second;
auto itTo = parallel_functions.find(callsTo);
if (itTo != parallel_functions.end())
{
newList.insert(func);
changes_done = true;
for (auto& loop : itTo->second)
{
if (added.find(loop) == added.end())
{
changes_done = true;
newList[func].insert(loop);
}
}
}
}
}
for (auto& newElem : newList)
parallel_functions.insert(newElem);
for (auto& loop : newElem.second)
parallel_functions[newElem.first].insert(loop);
}
}
@@ -1040,7 +1053,156 @@ static void insertInterface(SgStatement* func, const string& iface, const string
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
static void insertRoutine(SgStatement* func)
static LoopGraph* getParallelLoop(LoopGraph* loop)
{
auto prev_st = loop->loop->lexPrev();
while (prev_st && isDVM_stat(prev_st))
{
if (prev_st->variant() == DVM_PARALLEL_ON_DIR)
return loop;
prev_st = prev_st->lexPrev();
loop = loop->parent;
}
return NULL;
}
static set<LoopGraph*> getParallelLoops(const std::set<LoopGraph*>& loops)
{
set<LoopGraph*> retVal;
for (auto& elem : loops)
{
string oldFile = current_file->filename();
if (!elem->loop->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto parLoop = getParallelLoop(elem);
checkNull(parLoop, convertFileName(__FILE__).c_str(), __LINE__);
retVal.insert(parLoop);
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
return retVal;
}
static set<DIST::Array*> getPrivateArrays(const set<LoopGraph*>& parLoops,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
set<DIST::Array*> retVal;
for (auto& loop : parLoops)
{
string oldFile = current_file->filename();
if (!loop->loop->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& priv : loop->directive->privates)
{
bool isArray = false;
if (isArrayType(priv->type()))
{
auto type = isSgArrayType(priv->type());
if (type && type->dimension())
isArray = true;
}
if (!isArray)
continue;
DIST::Array* arr = getArrayFromDeclarated(declaratedInStmt(priv), priv->identifier());
checkNull(arr, convertFileName(__FILE__).c_str(), __LINE__);
set<DIST::Array*> realArrayRefs;
getRealArrayRefs(arr, arr, realArrayRefs, arrayLinksByFuncCalls);
for (auto& elem : realArrayRefs)
retVal.insert(elem);
}
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
return retVal;
}
static SgExpression* getPrivateArraysInPar(const FuncInfo* funcInfo, const std::set<LoopGraph*>& inLoops,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
SgExpression* addedPrivList)
{
if (!funcInfo)
return NULL;
map<string, SgExpression*> addedPriv;
SgExpression* ex = addedPrivList;
while (ex)
{
if (ex->lhs() && ex->lhs()->variant() == ACC_PRIVATE_OP)
{
ex = ex->lhs()->lhs();
while (ex)
{
if (ex->lhs() && ex->lhs()->variant() == VAR_REF)
addedPriv[ex->lhs()->symbol()->identifier()] = ex->lhs();
ex = ex->rhs();
}
break;
}
ex = ex->rhs();
}
SgStatement* func = funcInfo->funcPointer->GetOriginal();
auto prog = isSgProgHedrStmt(func);
checkNull(prog, convertFileName(__FILE__).c_str(), __LINE__);
set<LoopGraph*> inParLoops = getParallelLoops(inLoops);
set<DIST::Array*> privArrays = getPrivateArrays(inLoops, arrayLinksByFuncCalls);
for (int z = 0; z < prog->numberOfParameters(); ++z)
{
SgSymbol* par = prog->parameter(z);
bool isArray = false;
if (isArrayType(par->type()))
{
auto type = isSgArrayType(par->type());
if (type && type->dimension())
isArray = true;
}
if (isArray && addedPriv.count(par->identifier()) == 0)
{
DIST::Array* arr = getArrayFromDeclarated(declaratedInStmt(par), par->identifier());
checkNull(arr, convertFileName(__FILE__).c_str(), __LINE__);
set<DIST::Array*> realArrayRefs;
getRealArrayRefs(arr, arr, realArrayRefs, arrayLinksByFuncCalls);
bool found = false;
for (auto& elem : realArrayRefs)
if (privArrays.find(elem) != privArrays.end())
found = true;
if (found)
addedPriv[par->identifier()] = new SgVarRefExp(par);
}
}
if (addedPriv.size())
{
vector<SgExpression*> list;
for (auto& elem : addedPriv)
list.push_back(elem.second);
return makeExprList(list, false);
}
else
return NULL;
}
static void insertRoutine(SgStatement* func, const FuncInfo* funcInfo, const std::set<LoopGraph*>& inLoops,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
string oldFile = current_file->filename();
if (!func->switchToFile())
@@ -1048,26 +1210,34 @@ static void insertRoutine(SgStatement* func)
SgStatement* st = func->lexNext();
SgStatement* last = func->lastNodeOfStmt();
bool has = false;
SgStatement* routine = NULL;
while (st != last)
{
if (st->variant() == ACC_ROUTINE_DIR)
{
has = true;
routine = st;
break;
}
st = st->lexNext();
}
if (has == false)
if (!routine)
{
st = func->lexNext();
st->insertStmtBefore(*new SgStatement(ACC_ROUTINE_DIR), *st->controlParent());
routine = new SgStatement(ACC_ROUTINE_DIR);
st->insertStmtBefore(*routine, *st->controlParent());
}
SgExpression* list = getPrivateArraysInPar(funcInfo, inLoops, arrayLinksByFuncCalls, routine->expr(0));
if (list)
{
list = new SgExpression(EXPR_LIST, new SgExpression(ACC_PRIVATE_OP, list));
routine->setExpression(0, list);
}
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
static bool isPure(SgStatement* func)
@@ -1089,15 +1259,23 @@ void DvmhRegionInserter::createInterfaceBlockForOutCall(FuncInfo* func, FuncInfo
insertInterface(func->funcPointer, getInterfaceBlock(callFrom->funcPointer->GetOriginal(), callFrom->funcParams), callFrom->funcName);
}
void DvmhRegionInserter::createInterfaceBlockForParallelFunctions()
void DvmhRegionInserter::createInterfaceBlockForParallelFunctions(bool onlyRoutine)
{
for (auto& parF : parallel_functions)
{
for (auto& func_pair : parallel_functions)
{
const auto& parF = func_pair.first;
const auto& inLoops = func_pair.second;
for (auto& callTo : parF->callsTo)
{
if (callTo->fileName != parF->fileName && isPure(parF->funcPointer->GetOriginal()))
{
insertRoutine(parF->funcPointer->GetOriginal());
if (onlyRoutine)
{
insertRoutine(parF->funcPointer->GetOriginal(), parF, inLoops, arrayLinksByFuncCalls);
continue;
}
auto it = callTo->interfaceBlocks.find(parF->funcName);
if (it == callTo->interfaceBlocks.end())
{
@@ -1124,7 +1302,7 @@ void DvmhRegionInserter::createInterfaceBlockForParallelFunctions()
st->symbol()->identifier() == parF->funcName)
{
iface = st;
insertRoutine(iface);
insertRoutine(iface, parF, inLoops, arrayLinksByFuncCalls);
break;
}
}
@@ -1362,15 +1540,16 @@ void insertDvmhRegions(SgProject& project, int files, const vector<ParallelRegio
for (int i = files - 1, k = 0; i >= 0; --i, ++k)
{
SgFile* file = &(project.file(i));
DvmhRegionInserter* regionInserter = inserters[k];
for (auto& func : regionInserter->getParallelFunctions())
createInterfacesForOutCalls(func);
// create interface for 'parallel' functions and
// insert ROUTINE directive if needed
regionInserter->createInterfaceBlockForParallelFunctions();
inserters[k]->createInterfaceBlockForParallelFunctions();
}
for (int i = files - 1, k = 0; i >= 0; --i, ++k)
{
SgFile* file = &(project.file(i));
// create interface for 'parallel' functions
inserters[k]->createInterfaceBlockForParallelFunctions(false);
}
for (auto& regionInserter : inserters)

View File

@@ -30,7 +30,7 @@ class DvmhRegionInserter
bool isMpiProgram;
ReadWriteAnalyzer& rw_analyzer;
std::set<FuncInfo*> parallel_functions;
std::map<FuncInfo*, std::set<LoopGraph*>> parallel_functions;
std::set<DIST::Array*> writesToArraysInParallelLoops;
std::set<DIST::Array*> usedArraysInParallelLoops;
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls;
@@ -76,7 +76,7 @@ public:
void insertActualDirectives(const std::vector<ParallelRegion*>* regs);
void updateParallelFunctions(const std::map<std::string, std::vector<LoopGraph*>>& loopGraphs);
void createInterfaceBlockForParallelFunctions();
void createInterfaceBlockForParallelFunctions(bool onlyRoutine = true);
void removePrivatesFromParallelLoops();
void addPrivatesToParallelLoops();
void addUsedArrays(std::set<DIST::Array*>& arrays);
@@ -95,7 +95,12 @@ public:
usedArraysInParallelLoops = newSet;
}
const std::set<FuncInfo*>& getParallelFunctions() const { return parallel_functions; }
const std::set<FuncInfo*> getParallelFunctions() const {
std::set<FuncInfo*> retVal;
for (auto& elem : parallel_functions)
retVal.insert(elem.first);
return retVal;
}
static void createInterfaceBlockForOutCall(FuncInfo* func, FuncInfo* callFrom);
static void createInterfaceBlockForOutCalls(FuncInfo* func);

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2375"
#define VERSION_SPF "2379"