2025-06-02 19:08:09 +03:00
|
|
|
#include "leak_detector.h"
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
#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 "dvm.h"
|
|
|
|
|
#include "../LoopAnalyzer/loop_analyzer.h"
|
2025-06-04 13:08:38 +03:00
|
|
|
#include "types.h"
|
|
|
|
|
#include "errors.h"
|
|
|
|
|
#include "SgUtils.h"
|
2023-09-14 19:43:13 +03:00
|
|
|
#include "../Distribution/Arrays.h"
|
2025-06-02 19:08:09 +03:00
|
|
|
#include "graph_calls.h"
|
2025-06-04 13:08:38 +03:00
|
|
|
#include "graph_calls_func.h"
|
|
|
|
|
#include "graph_loops_func.h"
|
2023-09-14 19:43:13 +03:00
|
|
|
#include "remote_access.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;
|
|
|
|
|
|
|
|
|
|
void fillRemoteFromDir(SgExpression* ex, vector<SgExpression*>& remotes)
|
|
|
|
|
{
|
|
|
|
|
if (ex)
|
|
|
|
|
{
|
|
|
|
|
if (ex->variant() == ARRAY_REF)
|
|
|
|
|
remotes.push_back(ex);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fillRemoteFromDir(ex->lhs(), remotes);
|
|
|
|
|
fillRemoteFromDir(ex->rhs(), remotes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SgExpression* remoteAggregation(SgExpression* remote, const vector<SgExpression*>* newRemotes)
|
|
|
|
|
{
|
|
|
|
|
vector<SgExpression*> remotes;
|
|
|
|
|
fillRemoteFromDir(remote, remotes);
|
|
|
|
|
|
|
|
|
|
if (newRemotes)
|
|
|
|
|
for (auto elem : *newRemotes)
|
|
|
|
|
fillRemoteFromDir(elem, remotes);
|
|
|
|
|
|
|
|
|
|
if (remotes.size() == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
map<string, vector<SgExpression*>> remByName;
|
|
|
|
|
for (auto& rem : remotes)
|
|
|
|
|
remByName[rem->symbol()->identifier()].push_back(rem);
|
|
|
|
|
|
|
|
|
|
set<string> existsRemotes;
|
|
|
|
|
vector<SgExpression*> list;
|
|
|
|
|
for (auto& byName : remByName)
|
|
|
|
|
{
|
|
|
|
|
SgExpression* fullDot = NULL;
|
|
|
|
|
for (auto& rem : byName.second)
|
|
|
|
|
{
|
|
|
|
|
SgExpression* list = rem->lhs();
|
|
|
|
|
int countDim = 0;
|
|
|
|
|
int countDD = 0;
|
|
|
|
|
while (list)
|
|
|
|
|
{
|
|
|
|
|
countDim++;
|
|
|
|
|
if (list->lhs()->variant() == DDOT)
|
|
|
|
|
countDD++;
|
|
|
|
|
list = list->rhs();
|
|
|
|
|
}
|
|
|
|
|
if (countDim == countDD && countDD != 0)
|
|
|
|
|
fullDot = rem;
|
|
|
|
|
|
|
|
|
|
if (fullDot)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fullDot)
|
|
|
|
|
list.push_back(fullDot);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//TODO: group by the same parts, eg. A(:,N,:) + A(1,N,:) -> A(:,N,:)
|
|
|
|
|
for (auto& rem : byName.second)
|
|
|
|
|
{
|
|
|
|
|
const string curr = rem->unparse();
|
|
|
|
|
auto exist = existsRemotes.find(curr);
|
|
|
|
|
if (exist == existsRemotes.end())
|
|
|
|
|
{
|
|
|
|
|
existsRemotes.insert(exist, curr);
|
|
|
|
|
list.push_back(rem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isSgExprListExp(remote))
|
|
|
|
|
remote = makeExprList(list);
|
|
|
|
|
else
|
|
|
|
|
remote->setLhs(makeExprList(list));
|
|
|
|
|
|
|
|
|
|
return remote;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static DIST::Array* GetArrayByShortName(const DIST::Arrays<int> &allArrays, SgSymbol *name)
|
|
|
|
|
{
|
|
|
|
|
auto uniqKey = getFromUniqTable(name);
|
|
|
|
|
string nameFromUniq = getShortName(uniqKey);
|
|
|
|
|
return allArrays.GetArrayByName(nameFromUniq);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static SgExpression* getArrayRefCopyFromAttribute(SgExpression* ex)
|
|
|
|
|
{
|
|
|
|
|
SgExpression* copy = ex;
|
|
|
|
|
if (isArrayRef(ex))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ex->numberOfAttributes(); ++i)
|
|
|
|
|
if (ex->attributeType(i) == ARRAY_REF)
|
|
|
|
|
copy = (SgExpression*)(ex->getAttribute(i)->getAttributeData());
|
|
|
|
|
}
|
|
|
|
|
return copy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool checkArrayRef(SgExpression* arrayRef, vector<pair<SgExpression*, SgExpression*>>& remotes, const DIST::Arrays<int>& allArrays,
|
|
|
|
|
const DataDirective& data, const vector<int>& currVar, const uint64_t regionID,
|
|
|
|
|
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
|
|
|
|
|
{
|
|
|
|
|
bool retVal = false;
|
|
|
|
|
DIST::Array* currArray = GetArrayByShortName(allArrays, OriginalSymbol(arrayRef->symbol()));
|
|
|
|
|
|
|
|
|
|
set<DIST::Array*> realRefs;
|
|
|
|
|
getRealArrayRefs(currArray, currArray, realRefs, arrayLinksByFuncCalls);
|
|
|
|
|
|
|
|
|
|
for (auto array : realRefs)
|
|
|
|
|
{
|
|
|
|
|
if (array != NULL)
|
|
|
|
|
{
|
|
|
|
|
// find distributed dims
|
|
|
|
|
DIST::Array* templ = array->GetTemplateArray(regionID);
|
|
|
|
|
checkNull(templ, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
auto links = array->GetLinksWithTemplate(regionID);
|
|
|
|
|
|
|
|
|
|
bool needToAdd = false;
|
|
|
|
|
for (int i = 0; i < data.distrRules.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (data.distrRules[i].first == templ)
|
|
|
|
|
{
|
|
|
|
|
const vector<dist>& rule = data.distrRules[i].second[currVar[i]].distRule;
|
|
|
|
|
for (int k = 0; k < links.size(); ++k)
|
|
|
|
|
{
|
|
|
|
|
const int idx = links[k];
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
{
|
|
|
|
|
if (rule[idx] == BLOCK)
|
|
|
|
|
{
|
|
|
|
|
needToAdd = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//and add, if found any distributed dim
|
|
|
|
|
if (needToAdd)
|
|
|
|
|
{
|
|
|
|
|
remotes.push_back(make_pair(arrayRef->copyPtr(), getArrayRefCopyFromAttribute(arrayRef)));
|
|
|
|
|
retVal = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool findAllArraysForRemote(SgStatement* st, SgExpression* expr,
|
|
|
|
|
vector<pair<SgExpression*, SgExpression*>>& remotes, const DIST::Arrays<int>& allArrays,
|
|
|
|
|
const DataDirective& data, const vector<int>& currVar, const uint64_t regionID,
|
|
|
|
|
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
|
|
|
|
|
{
|
|
|
|
|
bool retVal = false;
|
|
|
|
|
|
|
|
|
|
if (expr == NULL)
|
|
|
|
|
return retVal;
|
|
|
|
|
|
|
|
|
|
bool isProcCall = st->variant() == PROC_STAT && st->expr(0) == expr;
|
|
|
|
|
if (expr->variant() == FUNC_CALL || isProcCall)
|
|
|
|
|
{
|
|
|
|
|
SgExpression* list = isProcCall ? expr : expr->lhs();
|
|
|
|
|
while (list)
|
|
|
|
|
{
|
|
|
|
|
auto arg = list->lhs();
|
|
|
|
|
if (isArrayRef(arg) && isSgArrayRefExp(arg)->numberOfSubscripts() != 0)
|
|
|
|
|
{
|
|
|
|
|
bool tmp = checkArrayRef(arg, remotes, allArrays, data, currVar, regionID, arrayLinksByFuncCalls);
|
|
|
|
|
retVal = retVal || tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (arg->lhs())
|
|
|
|
|
{
|
|
|
|
|
bool tmp = findAllArraysForRemote(st, arg->lhs(), remotes, allArrays, data, currVar, regionID, arrayLinksByFuncCalls);
|
|
|
|
|
retVal = retVal || tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (arg->rhs())
|
|
|
|
|
{
|
|
|
|
|
bool tmp = findAllArraysForRemote(st, arg->rhs(), remotes, allArrays, data, currVar, regionID, arrayLinksByFuncCalls);
|
|
|
|
|
retVal = retVal || tmp;
|
|
|
|
|
}
|
|
|
|
|
list = list->rhs();
|
|
|
|
|
}
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
else if (isArrayRef(expr))
|
|
|
|
|
{
|
|
|
|
|
bool tmp = checkArrayRef(expr, remotes, allArrays, data, currVar, regionID, arrayLinksByFuncCalls);
|
|
|
|
|
retVal = retVal || tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (expr->lhs())
|
|
|
|
|
{
|
|
|
|
|
bool tmp = findAllArraysForRemote(st, expr->lhs(), remotes, allArrays, data, currVar, regionID, arrayLinksByFuncCalls);
|
|
|
|
|
retVal = retVal || tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (expr->rhs())
|
|
|
|
|
{
|
|
|
|
|
bool tmp = findAllArraysForRemote(st, expr->rhs(), remotes, allArrays, data, currVar, regionID, arrayLinksByFuncCalls);
|
|
|
|
|
retVal = retVal || tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool checkExpr(SgExpression *ex, const set<int>& noSimpleVars, const set<string>& writeVars)
|
|
|
|
|
{
|
|
|
|
|
bool retVal = true;
|
|
|
|
|
if (ex == NULL)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
const int var = ex->variant();
|
|
|
|
|
if (noSimpleVars.find(var) != noSimpleVars.end())
|
|
|
|
|
{
|
|
|
|
|
if (var == VAR_REF)
|
|
|
|
|
{
|
|
|
|
|
if (writeVars.find(OriginalSymbol(ex->symbol())->identifier()) != writeVars.end())
|
|
|
|
|
return false;
|
|
|
|
|
else
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ex->lhs())
|
|
|
|
|
retVal = retVal && checkExpr(ex->lhs(), noSimpleVars, writeVars);
|
|
|
|
|
if (ex->rhs())
|
|
|
|
|
retVal = retVal && checkExpr(ex->rhs(), noSimpleVars, writeVars);
|
|
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void checkFuncCalls(SgExpression* ex, set<string>& writeVars, const map<string, FuncInfo*>& funcMap, SgStatement* st, vector<bool>& retVal)
|
|
|
|
|
{
|
|
|
|
|
if (ex)
|
|
|
|
|
{
|
|
|
|
|
if (ex->variant() == FUNC_CALL && !isIntrinsicFunctionName(ex->symbol()->identifier()))
|
|
|
|
|
{
|
|
|
|
|
auto it = funcMap.find(ex->symbol()->identifier());
|
|
|
|
|
if (it == funcMap.end())
|
|
|
|
|
{
|
|
|
|
|
__spf_print(1, "can not find func '%s' in %s:%d\n", ex->symbol()->identifier(), st->fileName(), st->lineNumber());
|
|
|
|
|
//printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
for (int z = 0; z < retVal.size(); ++z)
|
|
|
|
|
retVal[z] = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int num = 0;
|
|
|
|
|
for (auto fPar = ex->lhs(); fPar; fPar = fPar->rhs(), ++num)
|
|
|
|
|
if (fPar->lhs() && fPar->lhs()->variant() == VAR_REF && it->second->funcParams.isArgOut(num))
|
|
|
|
|
writeVars.insert(OriginalSymbol(fPar->lhs()->symbol())->identifier());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
checkFuncCalls(ex->lhs(), writeVars, funcMap, st, retVal);
|
|
|
|
|
checkFuncCalls(ex->rhs(), writeVars, funcMap, st, retVal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//TODO: check VAR_REF declaration in common block / module
|
|
|
|
|
vector<bool> isSimpleRef(SgStatement* stS, SgStatement* stE, SgExpression *subs, const set<int> noSimpleVars, const map<string, FuncInfo*>& funcMap,
|
|
|
|
|
const set<string>& usedVars)
|
|
|
|
|
{
|
|
|
|
|
vector<bool> retVal;
|
|
|
|
|
SgExpression* tmp = subs;
|
|
|
|
|
while (tmp)
|
|
|
|
|
{
|
|
|
|
|
retVal.push_back(true);
|
|
|
|
|
tmp = tmp->rhs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set<string> writeVars = usedVars;
|
|
|
|
|
if (noSimpleVars.find(VAR_REF) != noSimpleVars.end() && stS && stE)
|
|
|
|
|
{
|
|
|
|
|
if (stE == stS)
|
|
|
|
|
stE = stE->lexNext();
|
|
|
|
|
|
|
|
|
|
for (auto st = stS; st != stE; st = st->lexNext())
|
|
|
|
|
{
|
|
|
|
|
if (st->variant() == ASSIGN_STAT)
|
|
|
|
|
if (st->expr(0)->variant() == VAR_REF)
|
|
|
|
|
writeVars.insert(OriginalSymbol(st->expr(0)->symbol())->identifier());
|
|
|
|
|
|
|
|
|
|
if (st->variant() == PROC_STAT && !isIntrinsicFunctionName(st->symbol()->identifier()))
|
|
|
|
|
{
|
|
|
|
|
auto it = funcMap.find(st->symbol()->identifier());
|
|
|
|
|
if (it == funcMap.end())
|
|
|
|
|
{
|
|
|
|
|
__spf_print(1, "can not find proc '%s' in %s:%d\n", st->symbol()->identifier(), st->fileName(), st->lineNumber());
|
|
|
|
|
//printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
for (int z = 0; z < retVal.size(); ++z)
|
|
|
|
|
retVal[z] = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int num = 0;
|
|
|
|
|
for (auto ex = st->expr(0); ex; ex = ex->rhs(), ++num)
|
|
|
|
|
if (ex->lhs() && ex->lhs()->variant() == VAR_REF && it->second->funcParams.isArgOut(num))
|
|
|
|
|
writeVars.insert(OriginalSymbol(ex->lhs()->symbol())->identifier());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (st->variant() == FOR_NODE)
|
|
|
|
|
writeVars.insert(OriginalSymbol(isSgForStmt(st)->doName())->identifier());
|
|
|
|
|
|
|
|
|
|
for (int z = 0; z < 3; ++z)
|
|
|
|
|
checkFuncCalls(st->expr(z), writeVars, funcMap, st, retVal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int z = 0;
|
|
|
|
|
tmp = subs;
|
|
|
|
|
while (tmp)
|
|
|
|
|
{
|
|
|
|
|
if (retVal[z])
|
|
|
|
|
retVal[z] = checkExpr(tmp->lhs(), noSimpleVars, writeVars);
|
|
|
|
|
++z;
|
|
|
|
|
tmp = tmp->rhs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool inline hasDirs(SgStatement *st, const int var)
|
|
|
|
|
{
|
|
|
|
|
SgStatement *last = st->lastNodeOfStmt();
|
|
|
|
|
for ( ;st != last; st = st->lexNext())
|
|
|
|
|
if (st->variant() == var)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool isDistributed(SgSymbol *in)
|
|
|
|
|
{
|
|
|
|
|
SgSymbol *s = OriginalSymbol(in);
|
|
|
|
|
DIST::Array *decl = getArrayFromDeclarated(declaratedInStmt(s), s->identifier());
|
|
|
|
|
if (!decl)
|
|
|
|
|
return false;
|
|
|
|
|
else
|
|
|
|
|
return !(decl->IsNotDistribute());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//TODO: need to add IPA (functions)
|
|
|
|
|
static void fillRead(SgExpression *ex, SgStatement *cp, SgStatement *st,
|
|
|
|
|
map<string, map<string, pair<set<SgStatement*>, set<SgStatement*>>>> &readArrays)
|
|
|
|
|
{
|
|
|
|
|
if (ex)
|
|
|
|
|
{
|
|
|
|
|
if (ex->variant() == ARRAY_REF)
|
|
|
|
|
if (isDistributed(ex->symbol()))
|
|
|
|
|
{
|
|
|
|
|
readArrays[ex->symbol()->identifier()][string(ex->unparse())].first.insert(cp);
|
|
|
|
|
readArrays[ex->symbol()->identifier()][string(ex->unparse())].second.insert(st);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fillRead(ex->lhs(), cp, st, readArrays);
|
|
|
|
|
fillRead(ex->rhs(), cp, st, readArrays);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isNeedToConvertIfCondition(SgExpression *ex)
|
|
|
|
|
{
|
|
|
|
|
map<string, map<string, pair<set<SgStatement*>, set<SgStatement*>>>> readArrays;
|
|
|
|
|
fillRead(ex, NULL, NULL, readArrays);
|
|
|
|
|
return (readArrays.size() != 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool inline hasGoTo(SgStatement* stIn)
|
|
|
|
|
{
|
|
|
|
|
SgStatement* last = stIn->lastNodeOfStmt();
|
|
|
|
|
for (auto st = stIn; st != last; st = st->lexNext())
|
|
|
|
|
{
|
|
|
|
|
if (isSgGotoStmt(st) || isSgAssignedGotoStmt(st) || isSgComputedGotoStmt(st) ||
|
|
|
|
|
isSgExitStmt(st) || isSgCycleStmt(st))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool inline hasSpecialIfCond(SgStatement* stIn)
|
|
|
|
|
{
|
|
|
|
|
if (stIn->variant() != IF_NODE)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
auto ex = stIn->expr(0);
|
|
|
|
|
if (!ex)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (ex->variant() == NOT_OP)
|
|
|
|
|
{
|
|
|
|
|
ex = ex->lhs();
|
|
|
|
|
if (ex->variant() == VAR_REF && !ex->lhs() && !ex->rhs())
|
|
|
|
|
{
|
|
|
|
|
if (string(ex->symbol()->identifier()).find("spf_If_C") != string::npos)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool inline hasAssignsToArray(SgStatement *stIn)
|
|
|
|
|
{
|
|
|
|
|
// array -> unparse access -> pair [ control par, original stat]
|
|
|
|
|
map<string, map<string, pair<set<SgStatement*>, set<SgStatement*>>>> arrayAccessWrite;
|
|
|
|
|
map<string, map<string, pair<set<SgStatement*>, set<SgStatement*>>>> arrayAccessRead;
|
|
|
|
|
|
|
|
|
|
SgStatement *last = stIn->lastNodeOfStmt();
|
|
|
|
|
if (stIn->variant() == IF_NODE)
|
|
|
|
|
{
|
|
|
|
|
while (last->variant() != CONTROL_END)
|
|
|
|
|
last = last->lastNodeOfStmt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto st = stIn; st != last; st = st->lexNext())
|
|
|
|
|
{
|
|
|
|
|
if (st->variant() == ASSIGN_STAT)
|
|
|
|
|
{
|
|
|
|
|
SgExpression *ex = st->expr(0);
|
|
|
|
|
if (ex->variant() == ARRAY_REF)
|
|
|
|
|
{
|
|
|
|
|
SgSymbol *s = ex->symbol();
|
|
|
|
|
if (isDistributed(s))
|
|
|
|
|
{
|
|
|
|
|
arrayAccessWrite[s->identifier()][string(ex->unparse())].first.insert(st->controlParent());
|
|
|
|
|
arrayAccessWrite[s->identifier()][string(ex->unparse())].second.insert(st);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto st = stIn; st != last; st = st->lexNext())
|
|
|
|
|
{
|
|
|
|
|
SgStatement *cp = st->controlParent();
|
|
|
|
|
if (st->variant() != ASSIGN_STAT)
|
|
|
|
|
{
|
|
|
|
|
for (int z = 0; z < 3; ++z)
|
|
|
|
|
fillRead(st->expr(z), cp, st, arrayAccessRead);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int z = 1; z < 3; ++z)
|
|
|
|
|
fillRead(st->expr(z), cp, st, arrayAccessRead);
|
|
|
|
|
SgExpression *left = st->expr(0);
|
|
|
|
|
fillRead(left->lhs(), cp, st, arrayAccessRead);
|
|
|
|
|
fillRead(left->rhs(), cp, st, arrayAccessRead);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto &readPair : arrayAccessRead)
|
|
|
|
|
{
|
|
|
|
|
string arrayName = readPair.first;
|
|
|
|
|
auto it = arrayAccessWrite.find(arrayName);
|
|
|
|
|
|
|
|
|
|
//TODO:
|
|
|
|
|
if (it != arrayAccessWrite.end())
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
/*for (auto &read : readPair.second)
|
|
|
|
|
{
|
|
|
|
|
auto mapW = it->second.find(read.first);
|
|
|
|
|
|
|
|
|
|
if (mapW == it->second.end())
|
|
|
|
|
return true;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (auto &cpW : mapW->second.first)
|
|
|
|
|
{
|
|
|
|
|
for (auto &cpR : read.second.first)
|
|
|
|
|
if (cpW != cpR && cpW->variant() == FOR_NODE)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto &cpW : mapW->second.second)
|
|
|
|
|
if (read.second.second.find(cpW) == read.second.second.end())
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool converToDDOT(const vector<bool>& checkResult, SgExpression *spec)
|
|
|
|
|
{
|
|
|
|
|
bool done = false;
|
|
|
|
|
int currIdx = 0;
|
|
|
|
|
while (spec)
|
|
|
|
|
{
|
|
|
|
|
if (currIdx >= checkResult.size() && checkResult.size() > 0)
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
if (checkResult.size() == 0 || !checkResult[currIdx])
|
|
|
|
|
{
|
|
|
|
|
spec->setLhs(new SgExpression(DDOT));
|
|
|
|
|
done = true;
|
|
|
|
|
}
|
|
|
|
|
++currIdx;
|
|
|
|
|
spec = spec->rhs();
|
|
|
|
|
}
|
|
|
|
|
return done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void getAllSymbols(SgExpression *ex, set<string> &symbs)
|
|
|
|
|
{
|
|
|
|
|
if (ex)
|
|
|
|
|
{
|
|
|
|
|
if (ex->variant() == VAR_REF)
|
|
|
|
|
symbs.insert(ex->symbol()->identifier());
|
|
|
|
|
getAllSymbols(ex->lhs(), symbs);
|
|
|
|
|
getAllSymbols(ex->rhs(), symbs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool ifRange(SgExpression* spec)
|
|
|
|
|
{
|
|
|
|
|
while (spec)
|
|
|
|
|
{
|
|
|
|
|
if (spec->lhs()->variant() == DDOT)
|
|
|
|
|
{
|
|
|
|
|
if (!spec->lhs()->lhs() || !spec->lhs()->rhs())
|
|
|
|
|
return true;
|
|
|
|
|
if (string(spec->lhs()->lhs()->unparse()) != string(spec->lhs()->rhs()->unparse()))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
spec = spec->rhs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool isAlloc(SgStatement* st)
|
|
|
|
|
{
|
|
|
|
|
return st->variant() == ALLOCATE_STMT || st->variant() == DEALLOCATE_STMT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int numOfOperators(SgIfStmt* st)
|
|
|
|
|
{
|
|
|
|
|
int num = 0;
|
|
|
|
|
|
|
|
|
|
if (st && st->falseBody() == NULL)
|
|
|
|
|
{
|
|
|
|
|
for (auto it = st->lexNext(); it != st->lastNodeOfStmt(); it = it->lexNext())
|
|
|
|
|
num++;
|
|
|
|
|
return num;
|
|
|
|
|
}
|
|
|
|
|
return num;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int NUM>
|
|
|
|
|
bool createRemoteDir(SgStatement *st, const map<string, FuncInfo*>& funcMap, const map<int, LoopGraph*> &sortedLoopGraph, const DIST::Arrays<int> &allArrays,
|
|
|
|
|
const DataDirective &data, const vector<int> &currVar, const uint64_t regionId, vector<Messages> &currMessages,
|
|
|
|
|
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls)
|
|
|
|
|
{
|
|
|
|
|
//for parallel loops after vector assign convertion
|
|
|
|
|
if (st->lexPrev()->variant() == DVM_PARALLEL_ON_DIR)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (isAlloc(st))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (st->variant() == LOGIF_NODE)
|
|
|
|
|
if (((SgLogIfStmt*)st)->body())
|
|
|
|
|
if (isAlloc(((SgLogIfStmt*)st)->body()))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
vector<pair<SgExpression*, SgExpression*>> remotes; // <origRef, copyOfRefFromAttr>
|
|
|
|
|
string leftPartOfAssign = "";
|
|
|
|
|
if (st->variant() == ASSIGN_STAT)
|
|
|
|
|
leftPartOfAssign = getArrayRefCopyFromAttribute(st->expr(0))->unparse();
|
|
|
|
|
|
|
|
|
|
if (findAllArraysForRemote(st, st->expr(NUM), remotes, allArrays, data, currVar, regionId, arrayLinksByFuncCalls))
|
|
|
|
|
{
|
|
|
|
|
SgStatement *remoteDir = new SgStatement(DVM_REMOTE_ACCESS_DIR);
|
|
|
|
|
SgExpression *exprList = new SgExpression(EXPR_LIST);
|
|
|
|
|
remoteDir->setExpression(0, *exprList);
|
|
|
|
|
|
|
|
|
|
//exclude left part of assign: A(i,j,k) = A(i,j,k) + 5
|
|
|
|
|
if (leftPartOfAssign != "")
|
|
|
|
|
{
|
|
|
|
|
int z = 0;
|
|
|
|
|
while (z != remotes.size())
|
|
|
|
|
{
|
|
|
|
|
if (leftPartOfAssign == string(remotes[z].second->unparse()))
|
|
|
|
|
remotes.erase(remotes.begin() + z);
|
|
|
|
|
else
|
|
|
|
|
z++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector<SgExpression*> allSubs;
|
|
|
|
|
for (auto &rem : remotes)
|
|
|
|
|
allSubs.push_back(rem.first->lhs());
|
|
|
|
|
|
|
|
|
|
if (remotes.size() > 0)
|
|
|
|
|
{
|
|
|
|
|
//TODO: use CFG and RD analysis
|
|
|
|
|
set<string> usedSymbols;
|
|
|
|
|
for (auto &access : remotes)
|
|
|
|
|
getAllSymbols(access.first, usedSymbols);
|
|
|
|
|
|
|
|
|
|
SgStatement *toInsert = st;
|
|
|
|
|
vector<SgStatement*> allToInsert = { toInsert };
|
|
|
|
|
int lvlUp = 0;
|
|
|
|
|
bool througthForNode = false;
|
|
|
|
|
|
|
|
|
|
//find the uppest control parent
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
SgStatement *parent = toInsert->controlParent();
|
|
|
|
|
const int var = parent->variant();
|
|
|
|
|
if (var == FUNC_HEDR || var == PROC_HEDR || var == PROG_HEDR ||
|
|
|
|
|
hasDirs(parent, DVM_PARALLEL_ON_DIR) ||
|
|
|
|
|
hasDirs(parent, DVM_REMOTE_ACCESS_DIR) ||
|
|
|
|
|
hasAssignsToArray(parent) ||
|
|
|
|
|
hasSpecialIfCond(parent) ||
|
|
|
|
|
hasGoTo(parent))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toInsert = parent;
|
|
|
|
|
allToInsert.push_back(toInsert);
|
|
|
|
|
if (toInsert->variant() == FOR_NODE)
|
|
|
|
|
througthForNode = true;
|
|
|
|
|
++lvlUp;
|
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
|
|
for (int idx = allToInsert.size() - 1; idx >= 0; --idx)
|
|
|
|
|
{
|
|
|
|
|
const int var = allToInsert[idx]->variant();
|
|
|
|
|
if (var == ELSEIF_NODE)
|
|
|
|
|
{
|
|
|
|
|
if (idx != 0)
|
|
|
|
|
toInsert = allToInsert[idx - 1];
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
--lvlUp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (toInsert->variant() == FOR_NODE || toInsert->variant() == WHILE_NODE)
|
|
|
|
|
{
|
|
|
|
|
for (auto &elem : allSubs)
|
|
|
|
|
{
|
|
|
|
|
const vector<bool> checkRes = isSimpleRef(toInsert, toInsert->lastNodeOfStmt(), elem, { ARRAY_OP, ARRAY_REF, VAR_REF }, funcMap, set<string>());
|
|
|
|
|
converToDDOT(checkRes, elem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const int cpV = toInsert->controlParent()->variant();
|
|
|
|
|
const int varI = toInsert->variant();
|
|
|
|
|
|
|
|
|
|
for (auto& elem : allSubs)
|
|
|
|
|
{
|
|
|
|
|
set<int> varsToCheck = { ARRAY_OP, ARRAY_REF };
|
|
|
|
|
if (througthForNode)
|
|
|
|
|
varsToCheck.insert(VAR_REF);
|
|
|
|
|
|
|
|
|
|
const vector<bool> checkRes = isSimpleRef(toInsert, toInsert->lastNodeOfStmt(), elem, varsToCheck, funcMap, set<string>());
|
|
|
|
|
bool isSimple = true;
|
|
|
|
|
for (auto res : checkRes)
|
|
|
|
|
isSimple &= res;
|
|
|
|
|
|
|
|
|
|
if (ifRange(elem) || !isSimple)
|
|
|
|
|
converToDDOT(checkRes, elem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//create remote dir with uniq expressions
|
|
|
|
|
set<string> exist;
|
|
|
|
|
int add = 0;
|
|
|
|
|
for (int z = 0; z < remotes.size(); ++z, ++add)
|
|
|
|
|
{
|
|
|
|
|
string currRem = remotes[z].first->unparse();
|
|
|
|
|
auto itR = exist.find(currRem);
|
|
|
|
|
if (itR == exist.end())
|
|
|
|
|
{
|
|
|
|
|
if (add != 0)
|
|
|
|
|
{
|
|
|
|
|
exprList->setRhs(new SgExpression(EXPR_LIST));
|
|
|
|
|
exprList = exprList->rhs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exprList->setLhs(remotes[z].first);
|
|
|
|
|
exist.insert(itR, currRem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
exist.clear();
|
|
|
|
|
|
|
|
|
|
SgStatement *prev = toInsert->lexPrev();
|
|
|
|
|
if (prev)
|
|
|
|
|
{
|
|
|
|
|
if (prev->variant() != DVM_REMOTE_ACCESS_DIR)
|
|
|
|
|
{
|
|
|
|
|
remoteDir->setExpression(0, remoteAggregation(remoteDir->expr(0), NULL));
|
|
|
|
|
toInsert->insertStmtBefore(*remoteDir, *toInsert->controlParent());
|
|
|
|
|
}
|
|
|
|
|
else // aggregate this
|
|
|
|
|
{
|
|
|
|
|
vector<SgExpression*> tmpR;
|
|
|
|
|
for (auto& rem : remotes)
|
|
|
|
|
tmpR.push_back(rem.first);
|
|
|
|
|
prev->setExpression(0, remoteAggregation(prev->expr(0), &tmpR));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
remoteDir->setExpression(0, remoteAggregation(remoteDir->expr(0), NULL));
|
|
|
|
|
toInsert->insertStmtBefore(*remoteDir, *toInsert->controlParent());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template bool createRemoteDir<0>(SgStatement*, const map<string, FuncInfo*>&, const map<int, LoopGraph*>&, const DIST::Arrays<int>&, const DataDirective&, const vector<int>&, const uint64_t, vector<Messages>&, const map<DIST::Array*, set<DIST::Array*>>&);
|
|
|
|
|
template bool createRemoteDir<1>(SgStatement*, const map<string, FuncInfo*>&, const map<int, LoopGraph*>&, const DIST::Arrays<int>&, const DataDirective&, const vector<int>&, const uint64_t, vector<Messages>&, const map<DIST::Array*, set<DIST::Array*>>&);
|
|
|
|
|
|
|
|
|
|
void addRemoteLink(const LoopGraph* loop, const map<string, FuncInfo*>& funcMap, ArrayRefExp *expr, map<string, ArrayRefExp*> &uniqRemotes,
|
|
|
|
|
const set<string>& remotesInParallel, set<ArrayRefExp*> &addedRemotes, const vector<string>& mapToLoop,
|
|
|
|
|
vector<Messages> &messages, const int line, bool bindToLoopDistribution)
|
|
|
|
|
{
|
|
|
|
|
SgArrayRefExp* copyExpr = NULL;
|
|
|
|
|
|
|
|
|
|
bool isConv = false;
|
|
|
|
|
if (bindToLoopDistribution)
|
|
|
|
|
{
|
|
|
|
|
const LoopGraph* withDir = loop;
|
|
|
|
|
while (withDir && withDir->loop->GetOriginal()->lexPrev()->variant() != DVM_PARALLEL_ON_DIR)
|
|
|
|
|
withDir = withDir->parent;
|
|
|
|
|
|
2025-02-18 13:45:20 +03:00
|
|
|
checkNull(withDir, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
set<string> loopVars;
|
|
|
|
|
for (auto& elem : withDir->directive->parallel)
|
|
|
|
|
if (elem != "*")
|
|
|
|
|
loopVars.insert(elem);
|
|
|
|
|
|
|
|
|
|
copyExpr = (SgArrayRefExp*)(expr->copyPtr());
|
|
|
|
|
SgExpression* subs = copyExpr->subscripts();
|
|
|
|
|
set<string> tmp;
|
|
|
|
|
checkNull(loop->loop, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
//get uppest nested loop
|
|
|
|
|
const LoopGraph* UppestNested = loop;
|
|
|
|
|
while (UppestNested->parent && UppestNested->parent->children.size() == 1 &&
|
|
|
|
|
UppestNested->loop->GetOriginal()->lexPrev()->variant() != DVM_PARALLEL_ON_DIR)
|
|
|
|
|
UppestNested = UppestNested->parent;
|
|
|
|
|
|
|
|
|
|
vector<bool> isSimple = isSimpleRef(UppestNested->loop->GetOriginal(), UppestNested->loop->GetOriginal()->lastNodeOfStmt(), subs, {ARRAY_OP, ARRAY_REF, VAR_REF}, funcMap, loopVars);
|
|
|
|
|
SgExpression* ex = subs;
|
|
|
|
|
|
|
|
|
|
for (int z = 0; z < isSimple.size(); ++z, ex = ex->rhs())
|
|
|
|
|
{
|
|
|
|
|
if (!isSimple[z] && mapToLoop.size() && mapToLoop[z] != "")
|
|
|
|
|
{ // check for A*x + B
|
|
|
|
|
SgExpression* list = ex->lhs();
|
|
|
|
|
if (!list->lhs() && !list->rhs()) // I
|
|
|
|
|
{
|
|
|
|
|
if (list->variant() == VAR_REF && list->symbol() && list->symbol()->identifier() == mapToLoop[z])
|
|
|
|
|
isSimple[z] = true;
|
|
|
|
|
}
|
|
|
|
|
else if (list->variant() == ADD_OP) // I + B or B + I
|
|
|
|
|
{
|
|
|
|
|
if (list->lhs() && list->rhs())
|
|
|
|
|
{
|
|
|
|
|
SgExpression* left = list->lhs();
|
|
|
|
|
SgExpression* right = list->rhs();
|
|
|
|
|
if (right->variant() == VAR_REF && left->variant() != VAR_REF)
|
|
|
|
|
std::swap(left, right);
|
|
|
|
|
|
|
|
|
|
if (left->variant() == VAR_REF && right->variant() != VAR_REF)
|
|
|
|
|
{
|
|
|
|
|
if (left->variant() == VAR_REF && left->symbol() && left->symbol()->identifier() == mapToLoop[z])
|
|
|
|
|
{
|
|
|
|
|
int const rVar = right->variant();
|
|
|
|
|
if (rVar == CONST_REF || isSgValueExp(right))
|
|
|
|
|
isSimple[z] = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
isConv = converToDDOT(isSimple, subs);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
set<string> loopVars;
|
|
|
|
|
copyExpr = (SgArrayRefExp*)(expr->copyPtr());
|
|
|
|
|
SgExpression* subs = copyExpr->subscripts();
|
|
|
|
|
|
|
|
|
|
vector<bool> isSimple = isSimpleRef(loop->loop->GetOriginal(), loop->loop->GetOriginal()->lastNodeOfStmt(), subs, { ARRAY_OP, ARRAY_REF, VAR_REF }, funcMap, loopVars);
|
|
|
|
|
isConv = converToDDOT(isSimple, subs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string remoteExp(copyExpr->unparse());
|
|
|
|
|
auto rem = uniqRemotes.find(remoteExp);
|
|
|
|
|
if (rem == uniqRemotes.end() && remotesInParallel.find(remoteExp) == remotesInParallel.end())
|
|
|
|
|
{
|
|
|
|
|
rem = uniqRemotes.insert(rem, make_pair(remoteExp, new ArrayRefExp(copyExpr)));
|
|
|
|
|
addedRemotes.insert(new ArrayRefExp(copyExpr));
|
|
|
|
|
|
|
|
|
|
if (line > 0 && !isConv)
|
|
|
|
|
{
|
|
|
|
|
string remoteExp(expr->unparse());
|
|
|
|
|
__spf_print(1, "WARN: added remote access for array ref '%s' on line %d can significantly reduce performance\n", remoteExp.c_str(), line);
|
|
|
|
|
|
|
|
|
|
wstring bufE, bufR;
|
|
|
|
|
__spf_printToLongBuf(bufE, L"Added remote access for array ref '%s' can significantly reduce performance", to_wstring(remoteExp).c_str());
|
|
|
|
|
__spf_printToLongBuf(bufR, R129, to_wstring(remoteExp).c_str());
|
|
|
|
|
|
|
|
|
|
messages.push_back(Messages(WARR, line, bufR, bufE, 3009));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-21 15:07:16 +03:00
|
|
|
ArrayRefExp* createRemoteLink(const LoopGraph* currLoop, const DIST::Array* forArray)
|
2023-09-14 19:43:13 +03:00
|
|
|
{
|
2024-11-21 15:07:16 +03:00
|
|
|
SgFile* file = current_file;
|
|
|
|
|
|
|
|
|
|
const set<string> allFiles = getAllFilesInProject();
|
|
|
|
|
SgStatement* realStat = (SgStatement*)currLoop->getRealStat(file->filename());
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
SgExpression* ex = new SgExpression(EXPR_LIST);
|
|
|
|
|
SgExpression* p = ex;
|
|
|
|
|
for (int z = 0; z < forArray->GetDimSize(); ++z)
|
|
|
|
|
{
|
|
|
|
|
p->setLhs(new SgExpression(DDOT));
|
|
|
|
|
if (z != forArray->GetDimSize() - 1)
|
|
|
|
|
{
|
|
|
|
|
p->setRhs(new SgExpression(EXPR_LIST));
|
|
|
|
|
p = p->rhs();
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-18 13:45:20 +03:00
|
|
|
SgArrayRefExp* newRem = new SgArrayRefExp(*((SgSymbol*)forArray->GetNameInLocationS(realStat)), *ex);
|
2023-09-14 19:43:13 +03:00
|
|
|
return new ArrayRefExp(newRem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void addRemotesToDir(const pair<SgForStmt*, LoopGraph*> *under_dvm_dir, const map<string, ArrayRefExp*> &uniqRemotes)
|
|
|
|
|
{
|
|
|
|
|
SgStatement *dir = under_dvm_dir->first->lexPrev();
|
|
|
|
|
|
|
|
|
|
if (!dir)
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
if (dir->variant() != DVM_PARALLEL_ON_DIR)
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
SgExpression* list = NULL;
|
|
|
|
|
for (auto& rem : uniqRemotes)
|
|
|
|
|
{
|
|
|
|
|
list = dir->expr(1);
|
|
|
|
|
SgExpression *remoteList = NULL;
|
|
|
|
|
while (list)
|
|
|
|
|
{
|
|
|
|
|
if (list->lhs())
|
|
|
|
|
{
|
|
|
|
|
if (list->lhs()->variant() == REMOTE_ACCESS_OP)
|
|
|
|
|
{
|
|
|
|
|
remoteList = list->lhs();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
list = list->rhs();
|
|
|
|
|
}
|
|
|
|
|
list = dir->expr(1);
|
|
|
|
|
SgExpression *toAdd = new SgExpression(EXPR_LIST, rem.second, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
if (!remoteList)
|
|
|
|
|
{
|
|
|
|
|
remoteList = new SgExpression(REMOTE_ACCESS_OP, toAdd, NULL, NULL);
|
|
|
|
|
dir->setExpression(1, *new SgExpression(EXPR_LIST, remoteList, list, NULL));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SgExpression *lastLhs = remoteList->lhs();
|
|
|
|
|
remoteList->setLhs(toAdd);
|
|
|
|
|
toAdd->setRhs(lastLhs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list = dir->expr(1);
|
|
|
|
|
while (list)
|
|
|
|
|
{
|
|
|
|
|
if (list->lhs())
|
|
|
|
|
{
|
|
|
|
|
if (list->lhs()->variant() == REMOTE_ACCESS_OP)
|
|
|
|
|
{
|
|
|
|
|
remoteAggregation(list->lhs(), NULL);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
list = list->rhs();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static set<SgStatement*> addedDummyIf;
|
|
|
|
|
|
|
|
|
|
void groupActualAndRemote(SgFile *file, bool revert)
|
|
|
|
|
{
|
|
|
|
|
if (revert)
|
|
|
|
|
{
|
|
|
|
|
for (auto& dummyIf : addedDummyIf)
|
|
|
|
|
{
|
|
|
|
|
SgStatement* end = dummyIf->lastNodeOfStmt();
|
|
|
|
|
SgStatement* st = dummyIf->lexNext();
|
|
|
|
|
while (st != end)
|
|
|
|
|
{
|
|
|
|
|
SgStatement* toMove = st;
|
|
|
|
|
st = st->lexNext();
|
|
|
|
|
|
|
|
|
|
toMove = toMove->extractStmt();
|
|
|
|
|
dummyIf->insertStmtBefore(*toMove, *dummyIf->controlParent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dummyIf->extractStmt();
|
|
|
|
|
}
|
|
|
|
|
addedDummyIf.clear();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SgStatement* st = file->firstStatement();
|
|
|
|
|
while (st)
|
|
|
|
|
{
|
|
|
|
|
if (st->variant() == DVM_REMOTE_ACCESS_DIR)
|
|
|
|
|
{
|
|
|
|
|
auto next = st->lexNext();
|
|
|
|
|
auto nnext = next->lexNext();
|
|
|
|
|
|
|
|
|
|
if (next->expr(0) &&
|
|
|
|
|
next->expr(0)->variant() == ARRAY_REF &&
|
|
|
|
|
next->expr(0)->lhs()->lhs()->variant() == ARRAY_REF)
|
|
|
|
|
{
|
|
|
|
|
const string ref = next->expr(0)->unparse();
|
|
|
|
|
if (nnext && nnext->variant() == ACC_ACTUAL_DIR)
|
|
|
|
|
{
|
|
|
|
|
bool ifFullActual = false;
|
|
|
|
|
SgExpression* ex = nnext->expr(0);
|
|
|
|
|
while (ex)
|
|
|
|
|
{
|
|
|
|
|
if (ex->lhs() && ex->lhs()->unparse() == ref)
|
|
|
|
|
{
|
|
|
|
|
ifFullActual = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
ex = ex->rhs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ifRemote = false;
|
|
|
|
|
ex = st->expr(0);
|
|
|
|
|
while (ex)
|
|
|
|
|
{
|
|
|
|
|
if (ex->lhs() && ref.find(ex->lhs()->unparse()) != string::npos)
|
|
|
|
|
{
|
|
|
|
|
ifRemote = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
ex = ex->rhs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ifRemote && ifFullActual)
|
|
|
|
|
{
|
|
|
|
|
SgStatement* op = next->extractStmt();
|
|
|
|
|
SgStatement* act = nnext->extractStmt();
|
|
|
|
|
|
|
|
|
|
SgIfStmt* dummyIf = new SgIfStmt(*new SgValueExp(true), *act);
|
|
|
|
|
st->insertStmtAfter(*dummyIf, *st->controlParent());
|
|
|
|
|
dummyIf->insertStmtAfter(*op, *dummyIf);
|
|
|
|
|
|
|
|
|
|
addedDummyIf.insert(dummyIf);
|
|
|
|
|
st = dummyIf->lastNodeOfStmt();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
st = st->lexNext();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|