finalyze moving
This commit is contained in:
241
src/LoopAnalyzer/allocations_prepoc.cpp
Normal file
241
src/LoopAnalyzer/allocations_prepoc.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <assert.h>
|
||||
#include <set>
|
||||
|
||||
#include "dvm.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/errors.h"
|
||||
|
||||
using std::set;
|
||||
using std::pair;
|
||||
using std::map;
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
void preprocess_allocates(SgFile *file)
|
||||
{
|
||||
const string currfile = file->filename();
|
||||
int funcNum = file->numberOfFunctions();
|
||||
|
||||
set<SgStatement*> allStats;
|
||||
for (auto st = file->firstStatement(); st != NULL; st = st->lexNext())
|
||||
allStats.insert(st);
|
||||
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement *st = file->functions(i);
|
||||
SgStatement *lastNode = st->lastNodeOfStmt();
|
||||
|
||||
while (st != lastNode)
|
||||
{
|
||||
if (st == NULL)
|
||||
{
|
||||
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (st->variant() == CONTAINS_STMT)
|
||||
break;
|
||||
|
||||
// save SgStatement PROC call to declaration attribute
|
||||
if (st->variant() == ALLOCATE_STMT || st->variant() == DEALLOCATE_STMT)
|
||||
{
|
||||
SgExpression *list = st->expr(0);
|
||||
set<SgStatement*> decls;
|
||||
while (list)
|
||||
{
|
||||
if (list->lhs()->variant() == ARRAY_REF)
|
||||
decls.insert(declaratedInStmt(OriginalSymbol(isSgArrayRefExp(list->lhs())->symbol())));
|
||||
else if (list->lhs()->variant() == RECORD_REF)
|
||||
{
|
||||
SgExpression* field = list->lhs()->lhs();
|
||||
if (field->variant() == ARRAY_REF)
|
||||
decls.insert(declaratedInStmt(OriginalSymbol(field->symbol())));
|
||||
else if (field->variant() == VAR_REF)
|
||||
decls.insert(declaratedInStmt(OriginalSymbol(field->symbol())));
|
||||
else
|
||||
printf(""); // TODO
|
||||
}
|
||||
|
||||
list = list->rhs();
|
||||
}
|
||||
|
||||
set<SgStatement*> altDecls;
|
||||
for (auto& decl : decls)
|
||||
{
|
||||
if (decl->fileName() != currfile)
|
||||
{
|
||||
const string fIncl = decl->fileName();
|
||||
for (auto& stat : allStats)
|
||||
if (stat->lineNumber() == decl->lineNumber() && stat->fileName() == fIncl && decl != stat)
|
||||
altDecls.insert(stat);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& alt : altDecls)
|
||||
decls.insert(alt);
|
||||
|
||||
char buf[256];
|
||||
for (auto& decl : decls)
|
||||
{
|
||||
decl->addAttribute(st->variant(), st, sizeof(SgStatement*));
|
||||
sprintf(buf, " attribute (%d %s) is added to declaration on line %d of %s file\n",
|
||||
st->lineNumber(), st->fileName(), decl->lineNumber(), decl->fileName());
|
||||
addToGlobalBufferAndPrint(buf);
|
||||
}
|
||||
|
||||
if (decls.size() == 0)
|
||||
{
|
||||
sprintf(buf, "ERROR at line %d %s: Can not find declarations for allocation on line %d\n", __LINE__, convertFileName(__FILE__).c_str(), st->lineNumber());
|
||||
addToGlobalBufferAndPrint(buf);
|
||||
throw(-1);
|
||||
}
|
||||
}
|
||||
st = st->lexNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: extend ALLOC/DEALLOC moving
|
||||
//TODO: add support of different files
|
||||
// only one level of call is supported
|
||||
void moveAllocatesInterproc(const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls)
|
||||
{
|
||||
for (auto &array : arrayLinksByFuncCalls)
|
||||
{
|
||||
if (array.first->GetLocation().first == DIST::l_PARAMETER)
|
||||
{
|
||||
//check one level of calls
|
||||
bool ok = true;
|
||||
for (auto &elem : array.second)
|
||||
if (elem->GetLocation().first == DIST::l_PARAMETER)
|
||||
ok = false;
|
||||
|
||||
//move to all real arrays
|
||||
if (ok)
|
||||
{
|
||||
auto allPlaces = array.first->GetDeclInfo();
|
||||
for (auto &place : allPlaces)
|
||||
{
|
||||
if (SgFile::switchToFile(place.first) != -1)
|
||||
{
|
||||
SgStatement *decl = SgStatement::getStatementByFileAndLine(place.first, place.second);
|
||||
checkNull(decl, convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
map<SgStatement*, set<SgStatement*>> needToAdd;
|
||||
for (auto &data : getAttributes<SgStatement*, SgStatement*>(decl, set<int>{ ALLOCATE_STMT }))
|
||||
{
|
||||
for (auto &realArray : array.second)
|
||||
{
|
||||
auto allPlacesR = realArray->GetDeclInfo();
|
||||
for (auto &placeR : allPlacesR)
|
||||
{
|
||||
//the same file
|
||||
if (placeR.first == place.first)
|
||||
{
|
||||
SgStatement* declR = SgStatement::getStatementByFileAndLine(placeR.first, placeR.second);
|
||||
checkNull(declR, convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
needToAdd[declR].insert(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& toAdd : needToAdd)
|
||||
{
|
||||
for (auto& list : toAdd.second)
|
||||
{
|
||||
char buf[256];
|
||||
toAdd.first->addAttribute(list->variant(), list, sizeof(SgStatement*));
|
||||
sprintf(buf, " [INTERPROC] attribute is added to declaration on line %d\n", toAdd.first->lineNumber());
|
||||
addToGlobalBufferAndPrint(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map<string, map<int, set<SgStatement*>>> attrsForModules; // mod -> [ line -> decls]
|
||||
|
||||
//get module declarations
|
||||
for (int z = 0; z < CurrentProject->numberOfFiles(); ++z)
|
||||
{
|
||||
SgFile* file = &(CurrentProject->file(z));
|
||||
|
||||
vector<SgStatement*> modules;
|
||||
findModulesInFile(file, modules);
|
||||
|
||||
for (auto& mod : modules)
|
||||
{
|
||||
SgStatement* st = mod;
|
||||
SgStatement* end = mod->lastNodeOfStmt();
|
||||
string modName = mod->symbol()->identifier();
|
||||
|
||||
while (st != end)
|
||||
{
|
||||
if (st->variant() == CONTAINS_STMT)
|
||||
break;
|
||||
|
||||
for (auto& data : getAttributes<SgStatement*, SgStatement*>(st, set<int>{ ALLOCATE_STMT, DEALLOCATE_STMT }))
|
||||
attrsForModules[modName][st->lineNumber()].insert(data);
|
||||
st = st->lexNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//synchronize module declarations
|
||||
for (int z = 0; z < CurrentProject->numberOfFiles(); ++z)
|
||||
{
|
||||
SgFile* file = &(CurrentProject->file(z));
|
||||
|
||||
vector<SgStatement*> modules;
|
||||
findModulesInFile(file, modules);
|
||||
|
||||
for (auto& mod : modules)
|
||||
{
|
||||
SgStatement* st = mod;
|
||||
SgStatement* end = mod->lastNodeOfStmt();
|
||||
string modName = mod->symbol()->identifier();
|
||||
|
||||
if (attrsForModules.find(modName) == attrsForModules.end())
|
||||
continue;
|
||||
|
||||
auto& info = attrsForModules[modName];
|
||||
while (st != end)
|
||||
{
|
||||
if (st->variant() == CONTAINS_STMT)
|
||||
break;
|
||||
|
||||
if (info.find(st->lineNumber()) != info.end())
|
||||
{
|
||||
const set<SgStatement*>& decls = info[st->lineNumber()];
|
||||
|
||||
auto attrs = getAttributes<SgStatement*, SgStatement*>(st, set<int>{ ALLOCATE_STMT, DEALLOCATE_STMT });
|
||||
const set<SgStatement*> inAttr(attrs.begin(), attrs.end());
|
||||
|
||||
for (auto& data : decls)
|
||||
{
|
||||
if (inAttr.find(data) == inAttr.end())
|
||||
{
|
||||
char buf[256];
|
||||
st->addAttribute(data->variant(), data, sizeof(SgStatement*));
|
||||
|
||||
sprintf(buf, " [MODULE SYNC] attribute (%d %s) is added to declaration on line %d of %s file\n",
|
||||
data->lineNumber(), data->fileName(), st->lineNumber(), st->fileName());
|
||||
addToGlobalBufferAndPrint(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
st = st->lexNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
448
src/LoopAnalyzer/dep_analyzer.cpp
Normal file
448
src/LoopAnalyzer/dep_analyzer.cpp
Normal file
@@ -0,0 +1,448 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <assert.h>
|
||||
#include <chrono>
|
||||
|
||||
#include "dvm.h"
|
||||
#include "loop_analyzer.h"
|
||||
|
||||
#include "../Utils/utils.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../ParallelizationRegions/ParRegions_func.h"
|
||||
#include "../SageAnalysisTool/depGraph.h"
|
||||
#include "../SageAnalysisTool/OmegaForSage/include/lang-interf.h"
|
||||
|
||||
using std::vector;
|
||||
using std::pair;
|
||||
using std::tuple;
|
||||
using std::map;
|
||||
using std::set;
|
||||
using std::make_pair;
|
||||
using std::make_tuple;
|
||||
using std::get;
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::chrono::high_resolution_clock;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::milliseconds;
|
||||
|
||||
extern map<LoopGraph*, depGraph*> depInfoForLoopGraph;
|
||||
extern void initializeDepAnalysisForFunction(SgFile *file, SgStatement *func, const map<string, FuncInfo*> &allFuncs, vector<Messages> &messagesForFile);
|
||||
extern int staticPrivateAnalysis;
|
||||
extern bool fullDepGraph;
|
||||
|
||||
static const set<string> *currentNonDistrArrays = NULL;
|
||||
static map<SgSymbol*, string> varInOut;
|
||||
static map<SgExpression*, string> *currentCollection = NULL;
|
||||
|
||||
bool isRemovableDependence(const depNode *currNode, const set<string> &privVars)
|
||||
{
|
||||
bool result = true;
|
||||
bool varIn = false, varOut = false;
|
||||
|
||||
switch (currNode->typedep)
|
||||
{
|
||||
case WRONGDEP:
|
||||
result = false;
|
||||
break;
|
||||
case ARRAYDEP:
|
||||
if (currentNonDistrArrays && currentNonDistrArrays->size() > 0)
|
||||
{
|
||||
SgSymbol *vIn = OriginalSymbol(currNode->varin->symbol());
|
||||
SgSymbol *vOut = OriginalSymbol(currNode->varout->symbol());
|
||||
|
||||
auto found = varInOut.find(vIn);
|
||||
if (found == varInOut.end())
|
||||
found = varInOut.insert(found, make_pair(vIn, vIn->identifier()));
|
||||
varIn = currentNonDistrArrays->find(found->second) != currentNonDistrArrays->end();
|
||||
|
||||
found = varInOut.find(vOut);
|
||||
if (found == varInOut.end())
|
||||
found = varInOut.insert(found, make_pair(vOut, vOut->identifier()));
|
||||
varOut = currentNonDistrArrays->find(found->second) != currentNonDistrArrays->end();
|
||||
}
|
||||
//dont check if textual identically
|
||||
if ((!isEqExpressions(currNode->varin, currNode->varout, *currentCollection) || varIn || varOut) && (currNode->varin != currNode->varout))
|
||||
{
|
||||
// TODO: process all loop, not only top loop
|
||||
if (currNode->knowndist[1] == 0 || currNode->distance[1] != 0)
|
||||
{
|
||||
if (currNode->knowndist[1] == 0)
|
||||
result = false;
|
||||
}
|
||||
else if (varIn || varOut) // found dependencies between non ditributed arrays
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case PRIVATEDEP:
|
||||
case REDUCTIONDEP:
|
||||
break;
|
||||
case SCALARDEP:
|
||||
if (privVars.find(currNode->varin->symbol()->identifier()) == privVars.end())
|
||||
result = false;
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static SgStatement* getCurrentFunc(SgStatement *st)
|
||||
{
|
||||
while (st && st->variant() != PROG_HEDR && st->variant() != PROC_HEDR && st->variant() != FUNC_HEDR)
|
||||
st = st->controlParent();
|
||||
checkNull(st, convertFileName(__FILE__).c_str(), __LINE__);
|
||||
return st;
|
||||
}
|
||||
|
||||
depGraph *getDependenciesGraph(const LoopGraph *currLoop, SgFile *file, const set<string> *privVars)
|
||||
{
|
||||
SgForStmt *currLoopRef = (SgForStmt*)currLoop->loop->GetOriginal();
|
||||
auto t = high_resolution_clock::now();
|
||||
|
||||
map<SgExpression*, string> tmpCollection;
|
||||
currentCollection = &tmpCollection;
|
||||
|
||||
set<string> tmpPriv;
|
||||
depGraph *depg = new depGraph(file, getCurrentFunc(currLoopRef), currLoopRef, privVars ? *privVars : tmpPriv);
|
||||
float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - t).count() / 1000.;
|
||||
if (elapsed > 1.0f)
|
||||
printf("SAPFOR: time of graph bulding for loop %d = %f sec\n", currLoop->lineNum, elapsed);
|
||||
currentCollection = NULL;
|
||||
return depg;
|
||||
}
|
||||
|
||||
//TODO: remove?
|
||||
static int isOnlyDef(SgStatement *loopSt, const map<SgStatement*, vector<DefUseList>> &defUseByPlace, const string &symb)
|
||||
{
|
||||
SgStatement *last = loopSt->lastNodeOfStmt();
|
||||
bool wasFoundSome = false;
|
||||
int count = 0;
|
||||
for (auto st = loopSt; st != last; st = st->lexNext())
|
||||
{
|
||||
auto it = defUseByPlace.find(st);
|
||||
if (it != defUseByPlace.end())
|
||||
{
|
||||
for (auto &elem : it->second)
|
||||
{
|
||||
if (elem.getVar() == symb)
|
||||
{
|
||||
wasFoundSome = true;
|
||||
if (elem.isUse())
|
||||
return -1;
|
||||
if (elem.isDef())
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!wasFoundSome)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static set<string> fillNestedReduction(LoopGraph* currLoop)
|
||||
{
|
||||
set<string> redVars;
|
||||
tryToFindPrivateInAttributes(currLoop->loop, redVars, true, true);
|
||||
|
||||
int lastPerfect = currLoop->perfectLoop;
|
||||
currLoop = currLoop->parent;
|
||||
|
||||
while (currLoop && currLoop->perfectLoop == lastPerfect + 1)
|
||||
{
|
||||
tryToFindPrivateInAttributes(currLoop->loop, redVars, true, true);
|
||||
|
||||
lastPerfect = currLoop->perfectLoop;
|
||||
currLoop = currLoop->parent;
|
||||
}
|
||||
|
||||
return redVars;
|
||||
}
|
||||
|
||||
static SgExpression *startS = NULL, *endS = NULL;
|
||||
static SgExpression *startS_save = NULL, *endS_save = NULL;
|
||||
|
||||
// try to find dependencies: reductions and privates for scalar
|
||||
// and regular and other for arrrays
|
||||
//TODO: add optimization - dont call omega test for arrays many times
|
||||
void tryToFindDependencies(LoopGraph *currLoop, const map<int, pair<SgForStmt*, pair<set<string>, set<string>>>> &allLoops,
|
||||
set<SgStatement*> &funcWasInit, SgFile *file, vector<ParallelRegion*> regions,
|
||||
vector<Messages> *currMessages,
|
||||
map<SgExpression*, string> &collection,
|
||||
const map<string, FuncInfo*> &allFuncs, const map<SgStatement*, vector<DefUseList>> &defUseByPlace)
|
||||
{
|
||||
auto it = allLoops.find(currLoop->lineNum);
|
||||
if (it == allLoops.end())
|
||||
return;
|
||||
|
||||
map<int, SgForStmt*> localAllLoopMap;
|
||||
for (auto &elem : allLoops)
|
||||
localAllLoopMap.insert(make_pair(elem.first, elem.second.first));
|
||||
|
||||
ParallelRegion *currReg = getRegionByLine(regions, it->second.first->fileName(), currLoop->lineNum);
|
||||
|
||||
if (currReg && currLoop->hasLimitsToParallel() == false || fullDepGraph)
|
||||
{
|
||||
SgForStmt *currLoopRef = it->second.first;
|
||||
set<string> redVars = fillNestedReduction(currLoop);
|
||||
|
||||
bool onlyOneStep = false;
|
||||
// if identical
|
||||
/*string startL = string(currLoopRef->start()->unparse());
|
||||
string endL = string(currLoopRef->end()->unparse());
|
||||
if (startL == endL)
|
||||
onlyOneStep = true;*/
|
||||
// XXX: turn off this "optimization"
|
||||
|
||||
//make unknown iters count for better analysis
|
||||
bool interChanged = false;
|
||||
if (currLoop->countOfIters == 1)
|
||||
{
|
||||
interChanged = true;
|
||||
if (!startS)
|
||||
startS = new SgExpression(VAR_REF, new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "_tmp1_")));
|
||||
if (!endS)
|
||||
endS = new SgExpression(VAR_REF, new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "_tmp2_")));
|
||||
|
||||
startS_save = currLoopRef->start();
|
||||
endS_save = currLoopRef->end();
|
||||
|
||||
currLoopRef->setStart(*startS);
|
||||
currLoopRef->setEnd(*endS);
|
||||
}
|
||||
|
||||
const set<string> &privVars = it->second.second.first;
|
||||
const set<string> &nonDistrArrays = it->second.second.second;
|
||||
|
||||
SgStatement *func = getFuncStat(currLoopRef);
|
||||
if (funcWasInit.find(func) == funcWasInit.end())
|
||||
{
|
||||
funcWasInit.insert(func);
|
||||
initializeDepAnalysisForFunction(file, func, allFuncs, *currMessages);
|
||||
}
|
||||
|
||||
currentNonDistrArrays = &nonDistrArrays;
|
||||
currentCollection = &collection;
|
||||
depGraph *depg = getDependenciesGraph(currLoop, file, &privVars);
|
||||
|
||||
if (interChanged)
|
||||
{
|
||||
currLoopRef->setStart(*startS_save);
|
||||
currLoopRef->setEnd(*endS_save);
|
||||
}
|
||||
|
||||
currentNonDistrArrays = NULL;
|
||||
currentCollection = NULL;
|
||||
|
||||
/*auto t = high_resolution_clock::now();
|
||||
depGraph *depg = new depGraph(file, getCurrentFunc(currLoopRef), currLoopRef, privVars);
|
||||
float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - t).count() / 1000.;
|
||||
if (elapsed > 1.0f)
|
||||
printf("SAPFOR: time of graph bulding for loop %d = %f sec\n", currLoop->lineNum, elapsed);*/
|
||||
|
||||
if (depg)
|
||||
{
|
||||
const std::vector<depNode*> &nodes = depg->getNodes();
|
||||
//vector<const depNode*> privatesToAdd;
|
||||
vector<const depNode*> reductionsToAdd;
|
||||
vector<const depNode*> unknownScalarDep;
|
||||
|
||||
bool findUnknownDepLen = false;
|
||||
map<SgSymbol*, tuple<int, int, int>> acrossToAdd;
|
||||
|
||||
bool varIn = false, varOut = false;
|
||||
bool isEqual = false;
|
||||
|
||||
for (int k = 0; k < nodes.size(); ++k)
|
||||
{
|
||||
const depNode *currNode = nodes[k];
|
||||
switch (currNode->typedep)
|
||||
{
|
||||
case WRONGDEP:
|
||||
break;
|
||||
case ARRAYDEP:
|
||||
if (nonDistrArrays.size() > 0)
|
||||
{
|
||||
SgSymbol *vIn = OriginalSymbol(currNode->varin->symbol());
|
||||
SgSymbol *vOut = OriginalSymbol(currNode->varout->symbol());
|
||||
|
||||
auto found = varInOut.find(vIn);
|
||||
if (found == varInOut.end())
|
||||
found = varInOut.insert(found, make_pair(vIn, vIn->identifier()));
|
||||
varIn = nonDistrArrays.find(found->second) != nonDistrArrays.end();
|
||||
|
||||
found = varInOut.find(vOut);
|
||||
if (found == varInOut.end())
|
||||
found = varInOut.insert(found, make_pair(vOut, vOut->identifier()));
|
||||
varOut = nonDistrArrays.find(found->second) != nonDistrArrays.end();
|
||||
}
|
||||
|
||||
isEqual = isEqExpressions(currNode->varin, currNode->varout, collection);
|
||||
//dont check if textual identically
|
||||
if ((!isEqual || varIn || varOut) && (currNode->varin != currNode->varout))
|
||||
{
|
||||
// TODO: process all loop, not only top loop
|
||||
if (currNode->knowndist[1] == 0 || currNode->distance[1] != 0)
|
||||
{
|
||||
if (currNode->knowndist[1] == 0)
|
||||
{
|
||||
if (!findUnknownDepLen)
|
||||
{
|
||||
auto message = currNode->createDepMessagebetweenArrays();
|
||||
wstring depMessageEng = to_wstring(message.first), depMessageRus = to_wstring(message.second);
|
||||
|
||||
depMessageEng += L" with unknown distance in loop on line " + std::to_wstring(currLoopRef->lineNumber()) + L" prevents parallelization";
|
||||
depMessageRus += L"#" + std::to_wstring(currLoopRef->lineNumber());
|
||||
|
||||
currMessages->push_back(Messages(NOTE, currNode->stmtin->lineNumber(), L"R124:" + depMessageRus, depMessageEng, 3006));
|
||||
|
||||
// __spf_print only first unknown dep length
|
||||
findUnknownDepLen = true;
|
||||
if (!onlyOneStep)
|
||||
currLoop->hasUnknownArrayDep = true;
|
||||
}
|
||||
}
|
||||
else if (!findUnknownDepLen) //currNode->distance[1] != 0
|
||||
{
|
||||
const ddnature nature = (ddnature)currNode->kinddep;
|
||||
int position = -1;
|
||||
if (nature == ddflow)
|
||||
position = 0;
|
||||
else if (nature == ddanti)
|
||||
position = 1;
|
||||
|
||||
if (position != -1)
|
||||
{
|
||||
SgSymbol *arrayS = OriginalSymbol(currNode->varin->symbol());
|
||||
SgArrayRefExp *arrayRef = (SgArrayRefExp*)(currNode->varin);
|
||||
|
||||
bool existSubs = false;
|
||||
|
||||
auto it = acrossToAdd.find(arrayS);
|
||||
if (it == acrossToAdd.end())
|
||||
{
|
||||
int subsPos = -1;
|
||||
SgSymbol *doName = currLoopRef->symbol();
|
||||
for (int z = 0; z < arrayRef->numberOfSubscripts() && !existSubs; ++z)
|
||||
{
|
||||
existSubs = checkExistence(arrayRef->subscript(z), doName->identifier());
|
||||
if (existSubs)
|
||||
subsPos = z;
|
||||
}
|
||||
|
||||
if (existSubs)
|
||||
it = acrossToAdd.insert(it, make_pair(arrayS, make_tuple(0, 0, subsPos)));
|
||||
}
|
||||
else
|
||||
existSubs = true;
|
||||
|
||||
if (existSubs)
|
||||
{
|
||||
if (position == 0)
|
||||
get<0>(it->second) = std::max(get<0>(it->second), abs((int)currNode->distance[1]));
|
||||
else
|
||||
get<1>(it->second) = std::max(get<1>(it->second), abs((int)currNode->distance[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!isEqual && (varIn || varOut)) // found dependencies between non ditributed arrays
|
||||
{
|
||||
if (currNode->knowndist[1] == 0 || currNode->distance[1] != 0)
|
||||
{
|
||||
if (!findUnknownDepLen)
|
||||
{
|
||||
auto message = currNode->createDepMessagebetweenArrays();
|
||||
wstring depMessageEng = to_wstring(message.first), depMessageRus = to_wstring(message.second);
|
||||
depMessageEng += L" prevents parallelization";
|
||||
currMessages->push_back(Messages(NOTE, currNode->stmtin->lineNumber(), L"R124:" + depMessageRus, depMessageEng, 3006));
|
||||
|
||||
// __spf_print only first unknown dep length
|
||||
findUnknownDepLen = true;
|
||||
if (!onlyOneStep)
|
||||
currLoop->hasUnknownArrayDep = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//currNode->displayDep();
|
||||
break;
|
||||
case PRIVATEDEP: //privates detected by PRIVATE_ANALYSIS_IR
|
||||
/*if (privVars.find(currNode->varin->symbol()->identifier()) == privVars.end())
|
||||
privatesToAdd.push_back(currNode);
|
||||
//unknownScalarDep.push_back(currNode); */
|
||||
break;
|
||||
case REDUCTIONDEP:
|
||||
if (currLoop->privateScalars.find(currNode->varin->symbol()->identifier()) == currLoop->privateScalars.end() &&
|
||||
redVars.find(currNode->varin->symbol()->identifier()) == redVars.end())
|
||||
reductionsToAdd.push_back(currNode);
|
||||
break;
|
||||
case SCALARDEP:
|
||||
if (currLoop->privateScalars.find(currNode->varin->symbol()->identifier()) == currLoop->privateScalars.end() &&
|
||||
redVars.find(currNode->varin->symbol()->identifier()) == redVars.end())
|
||||
unknownScalarDep.push_back(currNode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!onlyOneStep)
|
||||
{
|
||||
//NOTE: do it via PRIVATE_ANALYSIS_IR
|
||||
//addPrivatesToLoops(currLoop, privatesToAdd, localAllLoopMap, *currMessages);
|
||||
addReductionsToLoops(currLoop, reductionsToAdd, localAllLoopMap, *currMessages);
|
||||
if (!findUnknownDepLen && !currLoop->hasLimitsToParallel())
|
||||
addAcrossToLoops(currLoop, acrossToAdd, localAllLoopMap, *currMessages);
|
||||
|
||||
currLoop->hasUnknownScalarDep = (unknownScalarDep.size() != 0);
|
||||
for (int k = 0; k < unknownScalarDep.size(); ++k)
|
||||
{
|
||||
__spf_print(1, " unknown scalar dependencies by '%s' on line %d (try to specify its type)\n",
|
||||
unknownScalarDep[k]->varin->symbol()->identifier(), unknownScalarDep[k]->stmtin->lineNumber());
|
||||
|
||||
wstring messageE, messageR;
|
||||
__spf_printToLongBuf(messageE, L"unknown scalar dependencies by '%s' (try to specify its type)", to_wstring(unknownScalarDep[k]->varin->symbol()->identifier()).c_str());
|
||||
__spf_printToLongBuf(messageR, R112, to_wstring(unknownScalarDep[k]->varin->symbol()->identifier()).c_str());
|
||||
|
||||
currMessages->push_back(Messages(WARR, unknownScalarDep[k]->stmtin->lineNumber(), messageR, messageE, 3005));
|
||||
|
||||
currLoop->linesOfScalarDep.push_back(unknownScalarDep[k]->stmtin->lineNumber());
|
||||
}
|
||||
}
|
||||
|
||||
depInfoForLoopGraph[currLoop] = depg;
|
||||
if (currLoop->hasLimitsToParallel())
|
||||
currLoop->addConflictMessages(currMessages);
|
||||
}
|
||||
}
|
||||
else if (currReg && currLoop->hasLimitsToParallel())
|
||||
{
|
||||
// loop has limits
|
||||
currLoop->addConflictMessages(currMessages);
|
||||
}
|
||||
|
||||
for (int k = 0; k < currLoop->children.size(); ++k)
|
||||
tryToFindDependencies(currLoop->children[k], allLoops, funcWasInit, file, regions, currMessages, collection, allFuncs, defUseByPlace);
|
||||
}
|
||||
2641
src/LoopAnalyzer/loop_analyzer.cpp
Normal file
2641
src/LoopAnalyzer/loop_analyzer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
104
src/LoopAnalyzer/loop_analyzer.h
Normal file
104
src/LoopAnalyzer/loop_analyzer.h
Normal file
@@ -0,0 +1,104 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include "../GraphLoop/graph_loops.h"
|
||||
#include "../GraphCall/graph_calls.h"
|
||||
#include "../ParallelizationRegions/ParRegions.h"
|
||||
#include "../SageAnalysisTool/depInterfaceExt.h"
|
||||
#include "../Utils/AstWrapper.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
|
||||
#include "dvm.h"
|
||||
|
||||
typedef std::pair<std::pair<int, int>, std::pair<int, int>> attrType;
|
||||
namespace DIST = Distribution;
|
||||
|
||||
enum REGIME { DATA_DISTR, COMP_DISTR, REMOTE_ACC, ARRAY_ACC_CORNER, SHARED_MEMORY_PAR, UNDEF };
|
||||
|
||||
// loop_analyzer.cpp
|
||||
bool checkExistence(SgExpression *exp, const std::string& doName);
|
||||
|
||||
void loopAnalyzer(SgFile *file,
|
||||
std::vector<ParallelRegion*> ®ions,
|
||||
std::map<std::tuple<int, std::string, std::string>, DIST::Array*> &createdArrays,
|
||||
std::vector<Messages> &messagesForFile,
|
||||
REGIME regime,
|
||||
const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo,
|
||||
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays,
|
||||
const std::map<SgStatement*, std::set<std::tuple<int, std::string, std::string>>> &declaratedArraysSt,
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls,
|
||||
const std::map<SgStatement*, std::vector<DefUseList>> &defUseByPlace,
|
||||
bool skipDeps, std::vector<LoopGraph*> *loopGraph = NULL);
|
||||
|
||||
void fillFromModule(SgSymbol* s, const std::map<std::string, std::set<std::string>>& privatesByModule, std::set<std::string>& privates);
|
||||
|
||||
std::vector<std::pair<Expression*, Expression*>> getArraySizes(std::vector<std::pair<int, int>>& sizes, SgSymbol* symb, SgStatement* decl,
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
|
||||
const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
|
||||
|
||||
void arrayAccessAnalyzer(SgFile *file, std::vector<Messages> &messagesForFile,
|
||||
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays,
|
||||
REGIME regime);
|
||||
|
||||
void processLoopInformationForFunction(std::map<LoopGraph*, std::map<DIST::Array*, ArrayInfo*>> &loopInfo);
|
||||
void addToDistributionGraph(const std::map<LoopGraph*, std::map<DIST::Array*, ArrayInfo*>> &loopInfo, const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls);
|
||||
|
||||
void printBlanks(const int sizeOfBlank, const int countOfBlanks);
|
||||
bool isIntrinsic(const char *funName);
|
||||
|
||||
std::tuple<int, std::string, std::string> getUniqName(const std::map<std::string, SgStatement*> &commonBlocks, SgStatement *decl, SgSymbol *symb);
|
||||
std::string getShortName(const std::tuple<int, std::string, std::string> &uniqKey);
|
||||
|
||||
void insertSpfAnalysisBeforeParalleLoops(const std::vector<LoopGraph*> &loops);
|
||||
void recalculateArraySizes(std::set<DIST::Array*> &arraysDone, const std::set<DIST::Array*> &allArrays, const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
|
||||
int getSizeOfType(SgType* t);
|
||||
|
||||
// dep_analyzer.cpp
|
||||
void tryToFindDependencies(LoopGraph *currLoop, const std::map<int, std::pair<SgForStmt*, std::pair<std::set<std::string>, std::set<std::string>>>> &allLoops,
|
||||
std::set<SgStatement*> &funcWasInit, SgFile *file, std::vector<ParallelRegion*> regions, std::vector<Messages> *currMessages,
|
||||
std::map<SgExpression*, std::string> &collection, const std::map<std::string, FuncInfo*> &allFuncs,
|
||||
const std::map<SgStatement*, std::vector<DefUseList>> &defUseByPlace);
|
||||
depGraph *getDependenciesGraph(const LoopGraph *currLoop, SgFile *file, const std::set<std::string> *privVars = NULL);
|
||||
|
||||
// allocations_prepoc.cpp
|
||||
void preprocess_allocates(SgFile *file);
|
||||
void moveAllocatesInterproc(const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
|
||||
|
||||
// spf_directive_preproc.cpp
|
||||
bool preprocess_spf_dirs(SgFile *file, const std::map<std::string, CommonBlock*> &commonBlocks, std::vector<Messages> &messagesForFile, const std::set<std::string>& allFileNames, std::map<std::pair<std::string, int>, std::set<SgStatement*>>& usersDirectives);
|
||||
bool check_par_reg_dirs(SgFile *file, std::vector<Messages> &messagesForFile);
|
||||
|
||||
void revertion_spf_dirs(SgFile *file,
|
||||
std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays,
|
||||
std::map<SgStatement*, std::set<std::tuple<int, std::string, std::string>>> declaratedArraysSt);
|
||||
void addAcrossToLoops(LoopGraph *topLoop, const std::map<SgSymbol*, std::tuple<int, int, int>> &acrossToAdd,
|
||||
const std::map<int, SgForStmt*> &allLoops,
|
||||
std::vector<Messages> &currMessages);
|
||||
void addPrivatesToLoops(LoopGraph *currLoop, const std::vector<const depNode*> &privatesToAdd,
|
||||
const std::map<int, SgForStmt*> &allLoops,
|
||||
std::vector<Messages> &currMessages);
|
||||
void addReductionsToLoops(LoopGraph *currLoop, const std::vector<const depNode*> &reductionsToAdd,
|
||||
const std::map<int, SgForStmt*> &allLoops,
|
||||
std::vector<Messages> &currMessages);
|
||||
void fillVars(SgExpression *exp, const std::set<int> &types, std::set<SgSymbol*> &identifierList, std::vector<SgExpression*> &funcCalls);
|
||||
|
||||
// TODO: from remote_access.cpp, may be need to move
|
||||
bool isNeedToConvertIfCondition(SgExpression* ex);
|
||||
void addRemotesToDir(const std::pair<SgForStmt*, LoopGraph*> *under_dvm_dir, const std::map<std::string, ArrayRefExp*> &uniqRemotes);
|
||||
void fillRemoteFromDir(SgExpression* ex, std::vector<SgExpression*>& remotes);
|
||||
|
||||
template<int NUM> bool createRemoteDir(SgStatement *st, const std::map<std::string, FuncInfo*>& funcMap, const std::map<int, LoopGraph*> &sortedLoopGraph, const DIST::Arrays<int> &allArrays,
|
||||
const DataDirective &data, const std::vector<int> &currVar, const uint64_t regionId, std::vector<Messages> &currMessages,
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls);
|
||||
void groupActualAndRemote(SgFile* file, bool revert = false);
|
||||
|
||||
std::vector<SgStatement*> filterUserSpf(const std::vector<SgStatement*>& toFilter, bool with_omp = true);
|
||||
|
||||
// ArrayAnalysis.cpp
|
||||
int getAllDeclaredArrays(SgFile *file, std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays,
|
||||
std::map<SgStatement*, std::set<std::tuple<int, std::string, std::string>>> &declaratedArraysSt, std::map<std::string, std::vector<Messages>> &currMessages,
|
||||
const std::vector<ParallelRegion*> ®ions, const std::map<std::string, int>& distrStateFromGUI);
|
||||
Reference in New Issue
Block a user