Compare commits
12 Commits
bb50340b2b
...
4e16638c36
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e16638c36 | |||
| 6742932862 | |||
| 8b2e59356a | |||
| f9d52c0c3e | |||
| 537d60222f | |||
| 4eb057731f | |||
| 402ae91c33 | |||
| ba632b29ce | |||
| 18edf55d15 | |||
| 738f2c5d12 | |||
|
|
29a8c30370 | ||
|
|
99f5febd58 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -74,6 +74,7 @@ Sapfor/Sapc++/Sapc++/x64/
|
|||||||
Sapfor/Sapc++/x64/
|
Sapfor/Sapc++/x64/
|
||||||
|
|
||||||
/build
|
/build
|
||||||
|
/cmake-build-debug
|
||||||
|
|
||||||
Sapfor/out/
|
Sapfor/out/
|
||||||
Sapfor/_bin/*
|
Sapfor/_bin/*
|
||||||
|
|||||||
Submodule projects/dvm updated: 3a567d7582...6a86c96abe
@@ -24,7 +24,7 @@ namespace SAPFOR
|
|||||||
|
|
||||||
std::vector<BasicBlock*> next;
|
std::vector<BasicBlock*> next;
|
||||||
std::vector<BasicBlock*> prev;
|
std::vector<BasicBlock*> prev;
|
||||||
|
BasicBlock* idom{};
|
||||||
//reaching definition
|
//reaching definition
|
||||||
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
|
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
|
||||||
|
|
||||||
@@ -42,6 +42,7 @@ namespace SAPFOR
|
|||||||
void addInstruction(IR_Block* item);
|
void addInstruction(IR_Block* item);
|
||||||
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
||||||
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
||||||
|
void setIdom(BasicBlock* idom_) { idom = idom_; }
|
||||||
|
|
||||||
int removePrev(BasicBlock* removed);
|
int removePrev(BasicBlock* removed);
|
||||||
int removeNext(BasicBlock* removed);
|
int removeNext(BasicBlock* removed);
|
||||||
@@ -69,6 +70,7 @@ namespace SAPFOR
|
|||||||
const std::vector<IR_Block*>& getInstructions() const { return instructions; }
|
const std::vector<IR_Block*>& getInstructions() const { return instructions; }
|
||||||
const std::vector<BasicBlock*>& getNext() const { return next; }
|
const std::vector<BasicBlock*>& getNext() const { return next; }
|
||||||
const std::vector<BasicBlock*>& getPrev() const { return prev; }
|
const std::vector<BasicBlock*>& getPrev() const { return prev; }
|
||||||
|
BasicBlock* getIdom() const { return idom; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FOR LIVE ANALYSIS
|
* FOR LIVE ANALYSIS
|
||||||
|
|||||||
@@ -1635,9 +1635,9 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> ®ions, map<tuple<int,
|
|||||||
string fName = file->functions(i)->symbol()->identifier();
|
string fName = file->functions(i)->symbol()->identifier();
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
if (file->functions(i)->variant() != MODULE_STMT)
|
if (file->functions(i)->variant() != MODULE_STMT)
|
||||||
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(fName.begin(), fName.end()) + L"'");
|
sendMessage_2lvl(wstring(L"обработка функции '") + wstring(fName.begin(), fName.end()) + L"'");
|
||||||
else
|
else
|
||||||
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(fName.begin(), fName.end()) + L"'");
|
sendMessage_2lvl(wstring(L"обработка модуля '") + wstring(fName.begin(), fName.end()) + L"'");
|
||||||
#else
|
#else
|
||||||
if (file->functions(i)->variant() != MODULE_STMT)
|
if (file->functions(i)->variant() != MODULE_STMT)
|
||||||
sendMessage_2lvl(wstring(L"processing function '") + wstring(fName.begin(), fName.end()) + L"'");
|
sendMessage_2lvl(wstring(L"processing function '") + wstring(fName.begin(), fName.end()) + L"'");
|
||||||
@@ -1710,7 +1710,10 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> ®ions, map<tuple<int,
|
|||||||
map<string, pair<SgSymbol*, SgStatement*>> notMappedDistributedArrays;
|
map<string, pair<SgSymbol*, SgStatement*>> notMappedDistributedArrays;
|
||||||
set<string> mappedDistrbutedArrays;
|
set<string> mappedDistrbutedArrays;
|
||||||
|
|
||||||
|
const ParallelRegionLines* prevParLines = NULL;
|
||||||
|
double prevLinesWeight = 1.0;
|
||||||
double currentWeight = 1.0;
|
double currentWeight = 1.0;
|
||||||
|
|
||||||
while (st != lastNode)
|
while (st != lastNode)
|
||||||
{
|
{
|
||||||
createNeededException();
|
createNeededException();
|
||||||
@@ -1733,13 +1736,31 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> ®ions, map<tuple<int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int currentLine = st->lineNumber() < -1 ? st->localLineNumber() : st->lineNumber();
|
const int currentLine = st->lineNumber() < -1 ? st->localLineNumber() : st->lineNumber();
|
||||||
ParallelRegion *currReg = getRegionByLine(regions, st->fileName(), currentLine);
|
auto regAndLines = getRegionAndLinesByLine(regions, st->fileName(), currentLine);
|
||||||
|
|
||||||
|
auto *currReg = regAndLines.first;
|
||||||
|
auto *parLines = regAndLines.second;
|
||||||
if (currReg == NULL)
|
if (currReg == NULL)
|
||||||
{
|
{
|
||||||
st = st->lexNext();
|
st = st->lexNext();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parLines != prevParLines)
|
||||||
|
{
|
||||||
|
prevParLines = parLines;
|
||||||
|
auto newParLinesWeight = parLines ? parLines->weight : 1.0;
|
||||||
|
|
||||||
|
if (prevParLines)
|
||||||
|
currentWeight /= prevLinesWeight;
|
||||||
|
|
||||||
|
if (parLines)
|
||||||
|
currentWeight *= newParLinesWeight;
|
||||||
|
|
||||||
|
prevLinesWeight = newParLinesWeight;
|
||||||
|
prevParLines = parLines;
|
||||||
|
}
|
||||||
|
|
||||||
if (isSgExecutableStatement(st) == NULL)
|
if (isSgExecutableStatement(st) == NULL)
|
||||||
delcsStatViewed.insert(st);
|
delcsStatViewed.insert(st);
|
||||||
else if (!sharedMemoryParallelization &&
|
else if (!sharedMemoryParallelization &&
|
||||||
@@ -2168,7 +2189,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> ®ions, map<tuple<int,
|
|||||||
{
|
{
|
||||||
string fName = file->functions(i)->symbol()->identifier();
|
string fName = file->functions(i)->symbol()->identifier();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
|
sendMessage_2lvl(wstring(L"обработка цикла ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
|
||||||
#else
|
#else
|
||||||
sendMessage_2lvl(wstring(L"processing loop ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
|
sendMessage_2lvl(wstring(L"processing loop ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -93,8 +93,10 @@ static inline SgStatement* getParentStat(SgStatement *st)
|
|||||||
return iterator;
|
return iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateRegionInfo(SgStatement *st, map<string, pair<Statement*, Statement*>> &startEnd, map<string, pair<int, int>> &lines_,
|
static void updateRegionInfo(SgStatement *st, map<string, pair<Statement*, Statement*>> &startEnd,
|
||||||
set<string> &funcCallFromReg, const map<string, FuncInfo*> &mapFuncs)
|
map<string, pair<int, int>> &lines_,
|
||||||
|
map<string, map<string, set<int>>> &funcCallFromReg,
|
||||||
|
const map<string, FuncInfo*> &mapFuncs)
|
||||||
{
|
{
|
||||||
string containsPrefix = "";
|
string containsPrefix = "";
|
||||||
SgStatement *st_ps = getParentStat(st);
|
SgStatement *st_ps = getParentStat(st);
|
||||||
@@ -103,17 +105,26 @@ static void updateRegionInfo(SgStatement *st, map<string, pair<Statement*, State
|
|||||||
containsPrefix = st_ps->symbol()->identifier() + string(".");
|
containsPrefix = st_ps->symbol()->identifier() + string(".");
|
||||||
|
|
||||||
extendRegionInfo(st, startEnd, lines_);
|
extendRegionInfo(st, startEnd, lines_);
|
||||||
|
|
||||||
|
set<string> callsFromStatement;
|
||||||
|
|
||||||
if (st->variant() == PROC_STAT)
|
if (st->variant() == PROC_STAT)
|
||||||
{
|
{
|
||||||
string fullName = st->symbol()->identifier();
|
string fullName = st->symbol()->identifier();
|
||||||
//check contains
|
//check contains
|
||||||
if (mapFuncs.find(containsPrefix + fullName) != mapFuncs.end())
|
if (mapFuncs.find(containsPrefix + fullName) != mapFuncs.end())
|
||||||
fullName = containsPrefix + fullName;
|
fullName = containsPrefix + fullName;
|
||||||
funcCallFromReg.insert(fullName);
|
callsFromStatement.insert(fullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int z = 0; z < 3; ++z)
|
for (int z = 0; z < 3; ++z)
|
||||||
findFuncCalls(st->expr(z), funcCallFromReg, containsPrefix, mapFuncs);
|
findFuncCalls(st->expr(z), callsFromStatement, containsPrefix, mapFuncs);
|
||||||
|
|
||||||
|
string filename = st->fileName();
|
||||||
|
int line = st->lineNumber();
|
||||||
|
|
||||||
|
for (const auto &func_name : callsFromStatement)
|
||||||
|
funcCallFromReg[func_name][filename].insert(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fillArrayNamesInReg(set<string> &usedArrayInRegion, SgExpression *exp)
|
static void fillArrayNamesInReg(set<string> &usedArrayInRegion, SgExpression *exp)
|
||||||
@@ -318,8 +329,9 @@ void fillRegionLines(SgFile *file, vector<ParallelRegion*> ®ions, vector<Mess
|
|||||||
string regionName = "";
|
string regionName = "";
|
||||||
map<string, pair<Statement*, Statement*>> startEnd;
|
map<string, pair<Statement*, Statement*>> startEnd;
|
||||||
map<string, pair<int, int>> lines_;
|
map<string, pair<int, int>> lines_;
|
||||||
set<string> funcCallFromReg;
|
map<string, map<string, set<int>>> funcCallFromReg;
|
||||||
bool regionStarted = false;
|
bool regionStarted = false;
|
||||||
|
double fragmentWeight = 1.0;
|
||||||
|
|
||||||
vector<SgStatement*> toDel;
|
vector<SgStatement*> toDel;
|
||||||
for (int i = 0; i < funcNum; ++i)
|
for (int i = 0; i < funcNum; ++i)
|
||||||
@@ -368,6 +380,33 @@ void fillRegionLines(SgFile *file, vector<ParallelRegion*> ®ions, vector<Mess
|
|||||||
itFunc->second->callRegions.insert(0);
|
itFunc->second->callRegions.insert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse SPF_APPLY_FRAGMENT clause
|
||||||
|
auto *apply_fragment = data->expr(1);
|
||||||
|
fragmentWeight = 1.0;
|
||||||
|
|
||||||
|
while (apply_fragment)
|
||||||
|
{
|
||||||
|
auto *curr = apply_fragment->lhs();
|
||||||
|
if (curr)
|
||||||
|
{
|
||||||
|
__spf_print(1, "%s %d\n", curr->unparse(), curr->variant());
|
||||||
|
|
||||||
|
if (curr->variant() == SPF_WEIGHT_OP)
|
||||||
|
{
|
||||||
|
if (curr->lhs() &&
|
||||||
|
isSgValueExp(curr->lhs()) &&
|
||||||
|
isSgValueExp(curr->lhs())->doubleValue())
|
||||||
|
{
|
||||||
|
fragmentWeight = strtod(isSgValueExp(curr->lhs())->doubleValue(), NULL);
|
||||||
|
__spf_print(1, "->> %lf\n", fragmentWeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
__spf_print(1, "WEIGHT clause without double argument\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apply_fragment = apply_fragment->rhs();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next && next->variant() == SPF_END_PARALLEL_REG_DIR)
|
if (next && next->variant() == SPF_END_PARALLEL_REG_DIR)
|
||||||
@@ -400,10 +439,12 @@ void fillRegionLines(SgFile *file, vector<ParallelRegion*> ®ions, vector<Mess
|
|||||||
|
|
||||||
extendRegionInfo(st, startEnd, lines_, true);
|
extendRegionInfo(st, startEnd, lines_, true);
|
||||||
for (auto itRegInfo = startEnd.begin(); itRegInfo != startEnd.end(); ++itRegInfo)
|
for (auto itRegInfo = startEnd.begin(); itRegInfo != startEnd.end(); ++itRegInfo)
|
||||||
currReg->AddLines(lines_[itRegInfo->first], itRegInfo->first, &itRegInfo->second);
|
currReg->AddLines(lines_[itRegInfo->first], itRegInfo->first, &itRegInfo->second, fragmentWeight);
|
||||||
|
|
||||||
for (auto &func : funcCallFromReg)
|
for (auto &by_func : funcCallFromReg)
|
||||||
currReg->AddFuncCalls(func);
|
for (auto &by_file : by_func.second)
|
||||||
|
for(auto &by_line : by_file.second)
|
||||||
|
currReg->AddFuncCalls(by_func.first, by_file.first, by_line);
|
||||||
|
|
||||||
filterUserDirectives(currReg, usedArrayInRegion, userDvmRedistrDirs, userDvmRealignDirs, userDvmShadowDirs);
|
filterUserDirectives(currReg, usedArrayInRegion, userDvmRedistrDirs, userDvmRealignDirs, userDvmShadowDirs);
|
||||||
currReg->AddUserDirectives(userDvmRealignDirs, DVM_REALIGN_DIR);
|
currReg->AddUserDirectives(userDvmRealignDirs, DVM_REALIGN_DIR);
|
||||||
@@ -496,34 +537,48 @@ void fillRegionLinesStep2(vector<ParallelRegion*> ®ions, const map<string, ve
|
|||||||
{
|
{
|
||||||
if (regions[i]->GetName() != "DEFAULT")
|
if (regions[i]->GetName() != "DEFAULT")
|
||||||
for (auto &func : regions[i]->GetFuncCalls())
|
for (auto &func : regions[i]->GetFuncCalls())
|
||||||
setExplicitFlag(func, funcMap);
|
setExplicitFlag(func.first, funcMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < regions.size(); ++i)
|
for (int i = 0; i < regions.size(); ++i)
|
||||||
{
|
{
|
||||||
if (regions[i]->GetName() != "DEFAULT")
|
if (regions[i]->GetName() != "DEFAULT")
|
||||||
{
|
{
|
||||||
set<string> uniqFuncCalls;
|
map<string, double> uniqFuncCalls;
|
||||||
for (auto &elem : regions[i]->GetFuncCalls())
|
map<string, map<string, set<int>>> callPlaces;
|
||||||
uniqFuncCalls.insert(elem);
|
|
||||||
|
for (auto &elem : regions[i]->GetFuncCalls())
|
||||||
|
{
|
||||||
|
double max_weight = 0;
|
||||||
|
for (auto* fragment : elem.second)
|
||||||
|
if (fragment->weight > max_weight)
|
||||||
|
max_weight = fragment->weight;
|
||||||
|
|
||||||
|
uniqFuncCalls[elem.first] = max_weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wasChanged = true;
|
||||||
|
auto funcsBefore = uniqFuncCalls;
|
||||||
|
|
||||||
bool wasChanged = 1;
|
|
||||||
while (wasChanged)
|
while (wasChanged)
|
||||||
{
|
{
|
||||||
wasChanged = 0;
|
wasChanged = false;
|
||||||
|
auto updated = uniqFuncCalls;
|
||||||
|
|
||||||
for (auto &uniqF : uniqFuncCalls)
|
for (auto &uniqF : uniqFuncCalls)
|
||||||
{
|
{
|
||||||
auto func = funcMap.find(uniqF);
|
auto func = funcMap.find(uniqF.first);
|
||||||
if (func != funcMap.end())
|
if (func != funcMap.end())
|
||||||
{
|
{
|
||||||
for (auto &calls : func->second->callsFrom)
|
for (auto &call : func->second->callsFromDetailed)
|
||||||
{
|
{
|
||||||
auto it = uniqFuncCalls.find(calls);
|
auto it = updated.find(call.detailCallsFrom.first);
|
||||||
if (it == uniqFuncCalls.end())
|
if (it == updated.end())
|
||||||
{
|
updated.insert({call.detailCallsFrom.first, uniqF.second});
|
||||||
uniqFuncCalls.insert(it, calls);
|
else
|
||||||
wasChanged = 1;
|
it->second = std::max(it->second, uniqF.second);
|
||||||
}
|
|
||||||
|
callPlaces[call.detailCallsFrom.first][func->second->fileName].insert(call.detailCallsFrom.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -532,21 +587,27 @@ void fillRegionLinesStep2(vector<ParallelRegion*> ®ions, const map<string, ve
|
|||||||
string toPrint = "";
|
string toPrint = "";
|
||||||
for (auto &elem : uniqFuncCalls)
|
for (auto &elem : uniqFuncCalls)
|
||||||
{
|
{
|
||||||
auto it = funcMap.find(elem);
|
auto it = funcMap.find(elem.first);
|
||||||
if (it != funcMap.end())
|
if (it != funcMap.end())
|
||||||
{
|
{
|
||||||
regions[i]->AddLines(it->second->linesNum, it->second->fileName);
|
regions[i]->AddLines(it->second->linesNum, it->second->fileName, NULL, elem.second);
|
||||||
regions[i]->AddFuncCallsToAllCalls(it->second);
|
|
||||||
|
|
||||||
if (it->second->inRegion == 0)
|
if (it->second->inRegion == 0)
|
||||||
it->second->inRegion = 2;
|
it->second->inRegion = 2;
|
||||||
|
|
||||||
it->second->callRegions.insert(i);
|
it->second->callRegions.insert(i);
|
||||||
|
|
||||||
toPrint += elem + " ";
|
toPrint += elem.first + " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &elem : callPlaces)
|
||||||
|
{
|
||||||
|
for (const auto &byFile : elem.second)
|
||||||
|
for (auto byLine : byFile.second)
|
||||||
|
regions[i]->AddFuncCalls(elem.first, byFile.first, byLine);
|
||||||
|
}
|
||||||
|
|
||||||
if (toPrint != "")
|
if (toPrint != "")
|
||||||
__spf_print(1, "[%s]: funcs: %s\n", regions[i]->GetName().c_str(), toPrint.c_str());
|
__spf_print(1, "[%s]: funcs: %s\n", regions[i]->GetName().c_str(), toPrint.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
struct ParallelRegionLines
|
struct ParallelRegionLines
|
||||||
{
|
{
|
||||||
ParallelRegionLines()
|
ParallelRegionLines(double weight = 1.0) : weight(weight)
|
||||||
{
|
{
|
||||||
lines = std::make_pair(-1, -1);
|
lines = std::make_pair(-1, -1);
|
||||||
stats = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
stats = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
||||||
@@ -27,14 +27,15 @@ struct ParallelRegionLines
|
|||||||
intervalAfter = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
intervalAfter = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ParallelRegionLines(const std::pair<int, int> &lines) : lines(lines)
|
ParallelRegionLines(const std::pair<int, int> &lines, double weight = 1.0) : lines(lines), weight(weight)
|
||||||
{
|
{
|
||||||
stats = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
stats = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
||||||
intervalBefore = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
intervalBefore = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
||||||
intervalAfter = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
intervalAfter = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ParallelRegionLines(const std::pair<int, int> &lines, const std::pair<Statement*, Statement*> stats) : lines(lines), stats(stats)
|
ParallelRegionLines(const std::pair<int, int> &lines, const std::pair<Statement*, Statement*> stats, double weight = 1.0)
|
||||||
|
: lines(lines), stats(stats), weight(weight)
|
||||||
{
|
{
|
||||||
intervalBefore = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
intervalBefore = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
||||||
intervalAfter = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
intervalAfter = std::make_pair<Statement*, Statement*>(NULL, NULL);
|
||||||
@@ -62,6 +63,8 @@ struct ParallelRegionLines
|
|||||||
// <start, end> interval
|
// <start, end> interval
|
||||||
std::pair<Statement*, Statement*> intervalBefore;
|
std::pair<Statement*, Statement*> intervalBefore;
|
||||||
std::pair<Statement*, Statement*> intervalAfter;
|
std::pair<Statement*, Statement*> intervalAfter;
|
||||||
|
|
||||||
|
double weight; // weight of the fragment among all fragments of this region
|
||||||
};
|
};
|
||||||
|
|
||||||
#if __SPF
|
#if __SPF
|
||||||
@@ -116,7 +119,7 @@ public:
|
|||||||
currentVariant = copy.currentVariant;
|
currentVariant = copy.currentVariant;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AddLines(const std::pair<int, int> &linesToAdd, const std::string &file, const std::pair<Statement*, Statement*> *startEnd = NULL)
|
int AddLines(const std::pair<int, int> &linesToAdd, const std::string &file, const std::pair<Statement*, Statement*> *startEnd = NULL, double weight = 1.0)
|
||||||
{
|
{
|
||||||
if (linesToAdd.first > linesToAdd.second)
|
if (linesToAdd.first > linesToAdd.second)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -126,17 +129,29 @@ public:
|
|||||||
it = lines.insert(it, make_pair(file, std::vector<ParallelRegionLines>()));
|
it = lines.insert(it, make_pair(file, std::vector<ParallelRegionLines>()));
|
||||||
|
|
||||||
if (startEnd)
|
if (startEnd)
|
||||||
it->second.push_back(ParallelRegionLines(linesToAdd, *startEnd));
|
it->second.push_back(ParallelRegionLines(linesToAdd, *startEnd, weight));
|
||||||
else
|
else
|
||||||
it->second.push_back(ParallelRegionLines(linesToAdd));
|
it->second.push_back(ParallelRegionLines(linesToAdd, weight));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddFuncCalls(const std::string &func) { functionsCall.insert(func); }
|
void AddFuncCalls(const std::string &func, const std::string &file, const int line)
|
||||||
|
{
|
||||||
|
auto *found_lines = GetLinesByLine(file, line);
|
||||||
|
|
||||||
|
if (found_lines)
|
||||||
|
functionsCall[func].insert(found_lines);
|
||||||
|
}
|
||||||
|
|
||||||
#if __SPF
|
#if __SPF
|
||||||
void AddFuncCallsToAllCalls(FuncInfo *func) { allFunctionsCall.insert(func); }
|
void AddFuncCallsToAllCalls(FuncInfo *func, const std::string &file, const int line)
|
||||||
|
{
|
||||||
|
auto *found_lines = GetLinesByLine(file, line);
|
||||||
|
|
||||||
|
if (found_lines)
|
||||||
|
allFunctionsCall[func].insert(found_lines);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint64_t GetId() const { return regionId; }
|
uint64_t GetId() const { return regionId; }
|
||||||
@@ -176,10 +191,10 @@ public:
|
|||||||
const DataDirective& GetDataDir() const { return dataDirectives; }
|
const DataDirective& GetDataDir() const { return dataDirectives; }
|
||||||
DataDirective& GetDataDirToModify() { return dataDirectives; }
|
DataDirective& GetDataDirToModify() { return dataDirectives; }
|
||||||
|
|
||||||
const std::set<std::string>& GetFuncCalls() const { return functionsCall; }
|
const std::map<std::string, std::set<const ParallelRegionLines*>>& GetFuncCalls() const { return functionsCall; }
|
||||||
|
|
||||||
#if __SPF
|
#if __SPF
|
||||||
const std::set<FuncInfo*>& GetAllFuncCalls() const { return allFunctionsCall; }
|
const std::map<FuncInfo*, std::set<const ParallelRegionLines*>>& GetAllFuncCalls() const { return allFunctionsCall; }
|
||||||
const std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>>& GetUsedLocalArrays() const { return usedLocalArrays; }
|
const std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>>& GetUsedLocalArrays() const { return usedLocalArrays; }
|
||||||
const std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>>& GetUsedCommonArrays() const { return usedCommonArrays; }
|
const std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>>& GetUsedCommonArrays() const { return usedCommonArrays; }
|
||||||
|
|
||||||
@@ -218,7 +233,7 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool HasThisLine(const int line, const std::string &file) const
|
bool HasThisLine(const int line, const std::string &file, const ParallelRegionLines** found = nullptr) const
|
||||||
{
|
{
|
||||||
bool retVal = false;
|
bool retVal = false;
|
||||||
auto it = lines.find(file);
|
auto it = lines.find(file);
|
||||||
@@ -229,6 +244,9 @@ public:
|
|||||||
if (it->second[i].lines.first <= line && it->second[i].lines.second >= line)
|
if (it->second[i].lines.first <= line && it->second[i].lines.second >= line)
|
||||||
{
|
{
|
||||||
retVal = true;
|
retVal = true;
|
||||||
|
if (found)
|
||||||
|
*found = &(it->second[i]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,7 +310,7 @@ public:
|
|||||||
fprintf(fileOut, " originalName '%s'\n", originalName.c_str());
|
fprintf(fileOut, " originalName '%s'\n", originalName.c_str());
|
||||||
fprintf(fileOut, " functions call from %d:\n", (int)functionsCall.size());
|
fprintf(fileOut, " functions call from %d:\n", (int)functionsCall.size());
|
||||||
for (auto &func : functionsCall)
|
for (auto &func : functionsCall)
|
||||||
fprintf(fileOut, " '%s'\n", func.c_str());
|
fprintf(fileOut, " '%s'\n", func.first.c_str());
|
||||||
fprintf(fileOut, " total lines %d:\n", (int)lines.size());
|
fprintf(fileOut, " total lines %d:\n", (int)lines.size());
|
||||||
for (auto &line : lines)
|
for (auto &line : lines)
|
||||||
{
|
{
|
||||||
@@ -362,11 +380,11 @@ private:
|
|||||||
std::string originalName;
|
std::string originalName;
|
||||||
// file -> lines info
|
// file -> lines info
|
||||||
std::map<std::string, std::vector<ParallelRegionLines>> lines;
|
std::map<std::string, std::vector<ParallelRegionLines>> lines;
|
||||||
std::set<std::string> functionsCall;
|
std::map<std::string, std::set<const ParallelRegionLines*>> functionsCall; // func name -> fragments with calls
|
||||||
|
|
||||||
#if __SPF
|
#if __SPF
|
||||||
// for RESOLVE_PAR_REGIONS
|
// for RESOLVE_PAR_REGIONS
|
||||||
std::set<FuncInfo*> allFunctionsCall;
|
std::map<FuncInfo*, std::set<const ParallelRegionLines*>> allFunctionsCall; // function -> fragments with calls
|
||||||
std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>> usedLocalArrays; // func -> array -> lines
|
std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>> usedLocalArrays; // func -> array -> lines
|
||||||
std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>> usedCommonArrays; // func -> array -> lines
|
std::map<FuncInfo*, std::map<DIST::Array*, std::vector<ParallelRegionLines>>> usedCommonArrays; // func -> array -> lines
|
||||||
//
|
//
|
||||||
@@ -408,4 +426,5 @@ private:
|
|||||||
ParallelRegion* getRegionById(const std::vector<ParallelRegion*>& regions, const uint64_t regionId);
|
ParallelRegion* getRegionById(const std::vector<ParallelRegion*>& regions, const uint64_t regionId);
|
||||||
ParallelRegion* getRegionByName(const std::vector<ParallelRegion*>& regions, const std::string& regionName);
|
ParallelRegion* getRegionByName(const std::vector<ParallelRegion*>& regions, const std::string& regionName);
|
||||||
ParallelRegion* getRegionByLine(const std::vector<ParallelRegion*>& regions, const std::string& file, const int line);
|
ParallelRegion* getRegionByLine(const std::vector<ParallelRegion*>& regions, const std::string& file, const int line);
|
||||||
|
std::pair<ParallelRegion*, const ParallelRegionLines*> getRegionAndLinesByLine(const std::vector<ParallelRegion*>& regions, const std::string& file, const int line);
|
||||||
std::set<ParallelRegion*> getAllRegionsByLine(const std::vector<ParallelRegion*>& regions, const std::string& file, const int line);
|
std::set<ParallelRegion*> getAllRegionsByLine(const std::vector<ParallelRegion*>& regions, const std::string& file, const int line);
|
||||||
111
src/ProjectParameters/domTree.h
Normal file
111
src/ProjectParameters/domTree.h
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "vector"
|
||||||
|
#include "map"
|
||||||
|
|
||||||
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace SAPFOR {
|
||||||
|
class DominatorFinder {
|
||||||
|
private:
|
||||||
|
BasicBlock* entry;
|
||||||
|
std::vector<BasicBlock*> vertices;
|
||||||
|
std::unordered_map<BasicBlock*, int> dfs_num;
|
||||||
|
std::vector<int> parent, semi, vertex, ancestor, label;
|
||||||
|
std::vector<std::vector<int>> bucket;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
void DFS(BasicBlock* v, int parent_num) {
|
||||||
|
dfs_num[v] = n;
|
||||||
|
vertex[n] = n;
|
||||||
|
semi[n] = n;
|
||||||
|
label[n] = n;
|
||||||
|
ancestor[n] = -1;
|
||||||
|
parent[n] = parent_num;
|
||||||
|
vertices[n++] = v;
|
||||||
|
|
||||||
|
for (const auto& w : v->getNext()) {
|
||||||
|
if (dfs_num[w] == -1) {
|
||||||
|
DFS(w, dfs_num[v]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compress(int v) {
|
||||||
|
if (ancestor[ancestor[v]] != -1) {
|
||||||
|
Compress(ancestor[v]);
|
||||||
|
if (semi[label[ancestor[v]]] < semi[label[v]])
|
||||||
|
label[v] = label[ancestor[v]];
|
||||||
|
ancestor[v] = ancestor[ancestor[v]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Eval(int v) {
|
||||||
|
if (ancestor[v] == -1) return v;
|
||||||
|
Compress(v);
|
||||||
|
return label[v];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Link(int v, int w) {
|
||||||
|
ancestor[w] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
DominatorFinder(std::vector<BasicBlock*>& blocks) {
|
||||||
|
if (blocks.empty()) return;
|
||||||
|
entry = blocks[0];
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for (auto block : blocks) dfs_num[block] = -1;
|
||||||
|
|
||||||
|
int max_size = blocks.size();
|
||||||
|
vertices.resize(max_size);
|
||||||
|
parent.assign(max_size, -1);
|
||||||
|
semi.assign(max_size, -1);
|
||||||
|
vertex.assign(max_size, -1);
|
||||||
|
ancestor.assign(max_size, -1);
|
||||||
|
label.assign(max_size, -1);
|
||||||
|
bucket.resize(max_size);
|
||||||
|
|
||||||
|
DFS(entry, -1);
|
||||||
|
|
||||||
|
for (int i = n - 1; i > 0; --i) {
|
||||||
|
int w = vertex[i];
|
||||||
|
|
||||||
|
for (BasicBlock* v : vertices[w]->getPrev()) {
|
||||||
|
int u = Eval(dfs_num[v]);
|
||||||
|
if (semi[u] < semi[w])
|
||||||
|
semi[w] = semi[u];
|
||||||
|
}
|
||||||
|
bucket[vertex[semi[w]]].push_back(w);
|
||||||
|
Link(parent[w], w);
|
||||||
|
|
||||||
|
for (int v : bucket[parent[w]])
|
||||||
|
{
|
||||||
|
int u = Eval(v);
|
||||||
|
if (semi[u] < semi[v])
|
||||||
|
vertices[v]->setIdom(vertices[u]);
|
||||||
|
else
|
||||||
|
vertices[v]->setIdom(vertices[parent[w]]);
|
||||||
|
}
|
||||||
|
bucket[parent[w]].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < n; ++i) {
|
||||||
|
int w = vertex[i];
|
||||||
|
if (vertices[w]->getIdom() != vertices[vertex[semi[w]]])
|
||||||
|
vertices[w]->setIdom(vertices[w]->getIdom()->getIdom());
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->setIdom(nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void buildDominatorTreeLT(std::vector<BasicBlock*>& blocks) {
|
||||||
|
DominatorFinder finder(blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,33 +1,413 @@
|
|||||||
#include "../Utils/leak_detector.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
#include "../Utils/SgUtils.h"
|
||||||
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
#include "CFGraph/IR.h"
|
||||||
|
#include "Distribution/Array.h"
|
||||||
#include "dvm.h"
|
#include "dvm.h"
|
||||||
#include "../Utils/errors.h"
|
#include "../Utils/errors.h"
|
||||||
#include "../Utils/SgUtils.h"
|
|
||||||
#include "../GraphCall/graph_calls.h"
|
#include "../GraphCall/graph_calls.h"
|
||||||
#include "../GraphCall/graph_calls_func.h"
|
#include "../GraphCall/graph_calls_func.h"
|
||||||
|
|
||||||
|
#include "libSage++.h"
|
||||||
#include "projectParameters.h"
|
#include "projectParameters.h"
|
||||||
|
#include "domTree.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
map< pair<string, int>, set<string>>
|
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> stmtToIR(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt)
|
||||||
findParameters(const map<string, vector<DefUseList>> &defUseByFunctions,
|
|
||||||
const map<string, CommonBlock*> &commonBlocks,
|
|
||||||
const map<string, vector<FuncInfo*>> &allFuncInfo)
|
|
||||||
{
|
{
|
||||||
map< pair<string, int>, set<string>> foundParameters;
|
SgStatement* cur = stmt;
|
||||||
|
cur->switchToFile();
|
||||||
|
while (cur->variant() != PROC_HEDR && cur->variant() != PROG_HEDR && cur->variant() != FUNC_HEDR)
|
||||||
|
cur = cur->controlParent();
|
||||||
|
|
||||||
|
string funcName = ((SgProcHedrStmt*)cur)->nameWithContains();
|
||||||
|
|
||||||
return foundParameters;
|
int stmtID = stmt->id();
|
||||||
|
for (const auto& [func, bblocks] : CFGraph)
|
||||||
|
{
|
||||||
|
if (func->funcName != funcName)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto basicBlock : bblocks)
|
||||||
|
for (auto ins : basicBlock->getInstructions())
|
||||||
|
if (stmtID == ins->getInstruction()->getOperator()->id())
|
||||||
|
return make_tuple(func, ins->getInstruction(), basicBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
return { NULL, NULL, NULL };
|
||||||
|
}
|
||||||
|
|
||||||
|
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> IRByNumber(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, int num)
|
||||||
|
{
|
||||||
|
if (num < 0)
|
||||||
|
return { NULL, NULL, NULL };
|
||||||
|
|
||||||
|
for (const auto& [func, bblocks] : CFGraph)
|
||||||
|
for (auto byBB : bblocks)
|
||||||
|
if (byBB->getInstructions().front()->getNumber() <= num && byBB->getInstructions().back()->getNumber() >= num)
|
||||||
|
return make_tuple(func, getInstructionByNumber(byBB->getInstructions(), num), byBB);
|
||||||
|
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
return { NULL, NULL, NULL};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
void processArgument(set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Argument* arg,
|
||||||
|
Iterator instr,
|
||||||
|
Iterator first_instr)
|
||||||
|
{
|
||||||
|
if (arg == NULL)
|
||||||
|
return;
|
||||||
|
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
|
||||||
|
extract_vars_from_reg(worklist, arg, instr, first_instr);
|
||||||
|
else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||||
|
{
|
||||||
|
worklist.insert(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Argument* reg,
|
||||||
|
Iterator instr,
|
||||||
|
Iterator first_instr)
|
||||||
|
{
|
||||||
|
for (; instr >= first_instr; instr--)
|
||||||
|
{
|
||||||
|
if ((*instr)->getInstruction()->getResult() == reg)
|
||||||
|
{
|
||||||
|
processArgument(worklist, (*instr)->getInstruction()->getArg1(), instr, first_instr);
|
||||||
|
processArgument(worklist, (*instr)->getInstruction()->getArg2(), instr, first_instr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
||||||
|
set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Instruction* instr,
|
||||||
|
SAPFOR::BasicBlock* bblock,
|
||||||
|
FuncInfo* cur_func,
|
||||||
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||||
|
{
|
||||||
|
while (bblock)
|
||||||
|
{
|
||||||
|
auto first_instr = bblock->getInstructions().begin();
|
||||||
|
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
|
||||||
|
return i->getInstruction() == instr;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (; cur_instr >= bblock->getInstructions().begin(); cur_instr--)
|
||||||
|
{
|
||||||
|
auto instr = (*cur_instr)->getInstruction();
|
||||||
|
auto result_arg = instr->getResult();
|
||||||
|
auto arg1 = instr->getArg1();
|
||||||
|
auto arg2 = instr->getArg2();
|
||||||
|
|
||||||
|
if (worklist.count(result_arg))
|
||||||
|
{
|
||||||
|
processArgument(worklist, arg1, cur_instr, first_instr);
|
||||||
|
processArgument(worklist, arg2, cur_instr, first_instr);
|
||||||
|
worklist.erase(result_arg);
|
||||||
|
}
|
||||||
|
if (instr->getOperation() == SAPFOR::CFG_OP::PARAM && worklist.count(arg1))
|
||||||
|
{
|
||||||
|
// skip to F_CALL
|
||||||
|
auto f_call_instr = cur_instr;
|
||||||
|
while ((*f_call_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL)
|
||||||
|
f_call_instr++;
|
||||||
|
|
||||||
|
if ((*f_call_instr)->getInstruction()->getArg1()->getValue() == "_READ")
|
||||||
|
{
|
||||||
|
auto stmt_before = (*f_call_instr)->getInstruction()->getOperator();
|
||||||
|
auto filename = stmt_before->fileName();
|
||||||
|
auto line = stmt_before->lineNumber();
|
||||||
|
auto var_name = arg1->getValue().substr(arg1->getValue().find('%') + 1);
|
||||||
|
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg1->getValue().c_str(), line, filename);
|
||||||
|
auto toAdd = make_tuple(stmt_before, var_name, MODE::AFTER);
|
||||||
|
where_to_add.insert(toAdd);
|
||||||
|
worklist.erase(arg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& RD = bblock->getRD_In();
|
||||||
|
map<SAPFOR::BasicBlock*, SAPFOR::Instruction*> group_by_block;
|
||||||
|
for (auto& arg : worklist)
|
||||||
|
{
|
||||||
|
if (RD.count(arg))
|
||||||
|
{
|
||||||
|
if (RD.at(arg).size() == 1 && *RD.at(arg).begin() == SAPFOR::CFG_VAL::UNINIT)
|
||||||
|
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
|
||||||
|
else if (RD.at(arg).size() > 1)
|
||||||
|
{
|
||||||
|
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
|
||||||
|
auto filename = stmt_after->fileName();
|
||||||
|
auto line = stmt_after->lineNumber();
|
||||||
|
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
|
||||||
|
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
|
||||||
|
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
|
||||||
|
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
|
||||||
|
where_to_add.insert(toAdd);
|
||||||
|
worklist.erase(arg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto instr_num = *RD.at(arg).begin();
|
||||||
|
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
|
||||||
|
if (cur_func == func && (group_by_block[bblock] == NULL || group_by_block[bblock]->getNumber() < instr_num))
|
||||||
|
group_by_block[bblock] = instr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bblock && group_by_block.find(bblock) == group_by_block.end())
|
||||||
|
bblock = bblock->getIdom();
|
||||||
|
if (bblock)
|
||||||
|
instr = group_by_block[bblock];
|
||||||
|
}
|
||||||
|
|
||||||
|
// other variables are from global scope
|
||||||
|
const auto& RD = fullIR.at(cur_func).front()->getRD_In();
|
||||||
|
for (auto& arg : worklist)
|
||||||
|
{
|
||||||
|
if (arg->isMemGlobal())
|
||||||
|
{
|
||||||
|
set<int> found_rd;
|
||||||
|
if (RD.count(arg))
|
||||||
|
found_rd = RD.at(arg);
|
||||||
|
if (found_rd.size() == 0)
|
||||||
|
{
|
||||||
|
auto call_instr = call_sites[cur_func].size() ? call_sites[cur_func].front() : NULL;
|
||||||
|
while (call_instr && found_rd.size() == 0)
|
||||||
|
{
|
||||||
|
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
|
||||||
|
if (call_bblock->getRD_Out().count(arg))
|
||||||
|
found_rd = call_bblock->getRD_Out().at(arg);
|
||||||
|
|
||||||
|
|
||||||
|
call_instr = call_sites[call_func].size() ? call_sites[call_func].front() : NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found_rd.size() == 1 && *found_rd.begin() == SAPFOR::CFG_VAL::UNINIT)
|
||||||
|
{
|
||||||
|
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
|
||||||
|
} else if (found_rd.size() > 1)
|
||||||
|
{
|
||||||
|
auto first_instr = fullIR.at(cur_func).front()->getInstructions().begin();
|
||||||
|
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
|
||||||
|
auto filename = stmt_after->fileName();
|
||||||
|
auto line = stmt_after->lineNumber();
|
||||||
|
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
|
||||||
|
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
|
||||||
|
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
|
||||||
|
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
|
||||||
|
where_to_add.insert(toAdd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto instr_num = *found_rd.begin();
|
||||||
|
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
|
||||||
|
set<SAPFOR::Argument*> new_worklist = {arg};
|
||||||
|
|
||||||
|
lookup_for_vars(where_to_add, new_worklist, instr, bblock, func, fullIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (const auto& call_instr : call_sites[cur_func])
|
||||||
|
{
|
||||||
|
set<SAPFOR::Argument*> new_worklist;
|
||||||
|
auto params_num = cur_func->funcParams.countOfPars;
|
||||||
|
|
||||||
|
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
|
||||||
|
auto first_instr = call_bblock->getInstructions().begin();
|
||||||
|
auto cur_instr = std::find_if(first_instr, call_bblock->getInstructions().end(), [call_instr](SAPFOR::IR_Block* i) {
|
||||||
|
return i->getInstruction() == call_instr;
|
||||||
|
});
|
||||||
|
for (auto& arg : worklist)
|
||||||
|
{
|
||||||
|
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
|
||||||
|
{
|
||||||
|
auto param_num= stoi(arg->getValue().substr(arg->getValue().find('%', arg->getValue().find('%') + 1) + 1));
|
||||||
|
auto param_instr = (cur_instr - (params_num - param_num));
|
||||||
|
auto param_arg = (*param_instr)->getInstruction()->getArg1();
|
||||||
|
processArgument(new_worklist, param_arg, param_instr, first_instr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lookup_for_vars(where_to_add, new_worklist, call_instr, call_bblock, call_func, fullIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
||||||
|
SgStatement* alloc_statement,
|
||||||
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||||
|
{
|
||||||
|
auto [func, instr, bblock] = stmtToIR(fullIR, alloc_statement);
|
||||||
|
|
||||||
|
auto first_instr = bblock->getInstructions().begin();
|
||||||
|
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
|
||||||
|
return i->getInstruction() == instr;
|
||||||
|
});
|
||||||
|
auto alloc_instr = cur_instr;
|
||||||
|
|
||||||
|
// skip to F_CALL _ALLOC n
|
||||||
|
while ((*alloc_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL ||
|
||||||
|
(*alloc_instr)->getInstruction()->getArg1()->getValue() != "_ALLOC")
|
||||||
|
alloc_instr++;
|
||||||
|
|
||||||
|
|
||||||
|
auto arrays_num = stoi((*alloc_instr)->getInstruction()->getArg2()->getValue());
|
||||||
|
|
||||||
|
set<SAPFOR::Argument*> worklist;
|
||||||
|
for (int i = 0; i < arrays_num; i++)
|
||||||
|
{
|
||||||
|
auto param_instr = --alloc_instr;
|
||||||
|
auto param_reg = (*param_instr)->getInstruction()->getArg1();
|
||||||
|
|
||||||
|
while ((*param_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::LOAD ||
|
||||||
|
(*param_instr)->getInstruction()->getResult() != param_reg)
|
||||||
|
param_instr--;
|
||||||
|
|
||||||
|
|
||||||
|
auto dimensions_num = stoi((*param_instr)->getInstruction()->getArg2()->getValue());
|
||||||
|
|
||||||
|
for (int j = 0; j < dimensions_num; j++)
|
||||||
|
{
|
||||||
|
auto ref_instr = --param_instr;
|
||||||
|
if ((*ref_instr)->getInstruction()->getOperation() == SAPFOR::CFG_OP::RANGE)
|
||||||
|
{
|
||||||
|
vector<SAPFOR::Argument*> range_args = {(*ref_instr)->getInstruction()->getArg1(),
|
||||||
|
(*ref_instr)->getInstruction()->getArg2(),
|
||||||
|
(*ref_instr)->getInstruction()->getResult()};
|
||||||
|
for (auto& arg : range_args)
|
||||||
|
processArgument(worklist, arg, ref_instr, first_instr);
|
||||||
|
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
auto arg = (*ref_instr)->getInstruction()->getArg1();
|
||||||
|
processArgument(worklist, arg, ref_instr, first_instr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lookup_for_vars(where_to_add,worklist, instr, bblock, func, fullIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handle_single_loop(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
||||||
|
SgStatement* loop_stmt,
|
||||||
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||||
|
{
|
||||||
|
auto [func, instr, bblock] = stmtToIR(fullIR, loop_stmt);
|
||||||
|
|
||||||
|
auto cur_instr = bblock->getInstructions().end() - 1;
|
||||||
|
|
||||||
|
set<SAPFOR::Argument*> worklist;
|
||||||
|
extract_vars_from_reg(worklist, (*cur_instr)->getInstruction()->getResult(), cur_instr, bblock->getInstructions().begin());
|
||||||
|
|
||||||
|
lookup_for_vars(where_to_add, worklist, (*cur_instr)->getInstruction(), bblock, func, fullIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
findParameters(ResultSet& foundParameters,
|
||||||
|
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
|
||||||
|
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
|
||||||
|
{
|
||||||
|
set<tuple<SgStatement*, string, MODE>> where_to_add;
|
||||||
|
|
||||||
|
map<string, FuncInfo*> name_to_func;
|
||||||
|
for (const auto& [func, _] : fullIR)
|
||||||
|
name_to_func[func->funcName] = func;
|
||||||
|
|
||||||
|
for (auto& [func, bblocks] : fullIR)
|
||||||
|
{
|
||||||
|
for (const auto& block : bblocks)
|
||||||
|
for (const auto& ir_block : block->getInstructions())
|
||||||
|
{
|
||||||
|
auto instr = ir_block->getInstruction();
|
||||||
|
if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
|
||||||
|
{
|
||||||
|
auto func_name = instr->getArg1()->getValue();
|
||||||
|
auto func_info = name_to_func.find(func_name);
|
||||||
|
|
||||||
|
if (func_info != name_to_func.end())
|
||||||
|
call_sites[func_info->second].push_back(instr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SAPFOR::buildDominatorTreeLT(bblocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<SgStatement*> alloc_statements;
|
||||||
|
for (const auto& [func, bblocks] : fullIR)
|
||||||
|
for (const auto& block : bblocks)
|
||||||
|
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
|
||||||
|
{
|
||||||
|
auto op = (*instr)->getInstruction()->getOperator();
|
||||||
|
if (op && op->variant() == ALLOCATE_STMT) {
|
||||||
|
alloc_statements.insert(op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set<SgStatement*> for_statements;
|
||||||
|
// Find all FOR statements in the program
|
||||||
|
for (const auto& [func, bblocks] : fullIR)
|
||||||
|
for (const auto& block : bblocks)
|
||||||
|
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
|
||||||
|
{
|
||||||
|
auto op = (*instr)->getInstruction()->getOperator();
|
||||||
|
if (op && op->variant() == FOR_NODE)
|
||||||
|
for_statements.insert(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& alloc_statement : alloc_statements)
|
||||||
|
handle_single_allocate(where_to_add, alloc_statement, fullIR);
|
||||||
|
|
||||||
|
for (const auto& stmt : for_statements)
|
||||||
|
handle_single_loop(where_to_add, stmt, fullIR);
|
||||||
|
|
||||||
|
for (const auto& [stmt_before, var_name, mode] : where_to_add)
|
||||||
|
{
|
||||||
|
stmt_before->switchToFile();
|
||||||
|
|
||||||
|
SgVariableSymb* var_symb = new SgVariableSymb(var_name.c_str());
|
||||||
|
SgVarRefExp* var = new SgVarRefExp(var_symb);
|
||||||
|
SgValueExp* zero = new SgValueExp(1337);
|
||||||
|
SgExprListExp* ex = new SgExprListExp();
|
||||||
|
auto assgn_op = new SgExpression(ASSGN_OP, var, zero);
|
||||||
|
ex->setLhs(assgn_op);
|
||||||
|
|
||||||
|
SgExpression* parameter_op = new SgExpression(SPF_PARAMETER_OP, ex);
|
||||||
|
auto dir_list = new SgExprListExp();
|
||||||
|
dir_list->setLhs(parameter_op);
|
||||||
|
SgStatement* toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, dir_list, NULL, NULL);
|
||||||
|
|
||||||
|
toAdd->setlineNumber(stmt_before->lineNumber());
|
||||||
|
toAdd->setLocalLineNumber(stmt_before->lineNumber());
|
||||||
|
toAdd->setFileId(stmt_before->getFileId());
|
||||||
|
toAdd->setProject(stmt_before->getProject());
|
||||||
|
|
||||||
|
if (mode == MODE::AFTER)
|
||||||
|
stmt_before->insertStmtAfter(*toAdd, *stmt_before->controlParent());
|
||||||
|
else
|
||||||
|
stmt_before->insertStmtBefore(*toAdd, *stmt_before->controlParent());
|
||||||
|
|
||||||
|
foundParameters.insert(make_tuple(stmt_before->fileName(), stmt_before->lineNumber(), var_name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,42 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
std::map< std::pair<std::string, int>, std::set<std::string>> findParameters(const std::map<std::string, std::vector<DefUseList>> &defUseByFunctions, const std::map<std::string, CommonBlock*> &commonBlocks, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo);
|
#include "libSage++.h"
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using ResultSet = std::set<std::tuple<std::string, int, std::string>>;
|
||||||
|
|
||||||
|
enum class MODE
|
||||||
|
{
|
||||||
|
BEFORE,
|
||||||
|
AFTER
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<FuncInfo*, std::vector<SAPFOR::Instruction*>> call_sites;
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
void extract_vars_from_reg(std::set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Argument* reg,
|
||||||
|
Iterator instr,
|
||||||
|
Iterator first_instr);
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
void processArgument(std::set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Argument* arg,
|
||||||
|
Iterator instr,
|
||||||
|
Iterator first_instr);
|
||||||
|
|
||||||
|
void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
||||||
|
std::set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Instruction* instr,
|
||||||
|
SAPFOR::BasicBlock* bblock,
|
||||||
|
FuncInfo* cur_func,
|
||||||
|
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR);
|
||||||
|
|
||||||
|
void
|
||||||
|
findParameters(ResultSet& foundParameters,
|
||||||
|
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
|
||||||
|
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);
|
||||||
|
|||||||
@@ -1894,7 +1894,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
else if (curr_regime == RENAME_SYMBOLS)
|
else if (curr_regime == RENAME_SYMBOLS)
|
||||||
runRenameSymbols(&project, commonBlocks);
|
runRenameSymbols(&project, commonBlocks);
|
||||||
else if (curr_regime == FIND_PARAMETERS)
|
else if (curr_regime == FIND_PARAMETERS)
|
||||||
parametersOfProject = findParameters(defUseByFunctions, commonBlocks, allFuncInfo);
|
{
|
||||||
|
findParameters(parametersOfProject, fullIR, declaredArrays);
|
||||||
|
}
|
||||||
else if (curr_regime == BUILD_IR)
|
else if (curr_regime == BUILD_IR)
|
||||||
{
|
{
|
||||||
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
|
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
|
||||||
@@ -2372,6 +2374,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
|
|||||||
case LOOPS_COMBINER:
|
case LOOPS_COMBINER:
|
||||||
case FIX_COMMON_BLOCKS:
|
case FIX_COMMON_BLOCKS:
|
||||||
case TEST_PASS:
|
case TEST_PASS:
|
||||||
|
case FIND_PARAMETERS:
|
||||||
case SET_IMPLICIT_NONE:
|
case SET_IMPLICIT_NONE:
|
||||||
runAnalysis(*project, curr_regime, false);
|
runAnalysis(*project, curr_regime, false);
|
||||||
case SUBST_EXPR_RD_AND_UNPARSE:
|
case SUBST_EXPR_RD_AND_UNPARSE:
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ std::map<int, UserFiles> filesInfo; // information about open,close,write and re
|
|||||||
//
|
//
|
||||||
|
|
||||||
//for FIND_PARAMETERS
|
//for FIND_PARAMETERS
|
||||||
std::map< std::pair<std::string, int>, std::set<std::string>> parametersOfProject; // [file, line] -> set[vars]
|
std::set<std::tuple<std::string, int, std::string>> parametersOfProject; // [file, line, varname]
|
||||||
//
|
//
|
||||||
|
|
||||||
//for GET_MIN_MAX_BLOCK_DIST
|
//for GET_MIN_MAX_BLOCK_DIST
|
||||||
|
|||||||
@@ -1415,6 +1415,35 @@ ParallelRegion* getRegionByLine(const vector<ParallelRegion*>& regions, const st
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<ParallelRegion*, const ParallelRegionLines*> getRegionAndLinesByLine(const vector<ParallelRegion*>& regions, const string& file, const int line)
|
||||||
|
{
|
||||||
|
if (regions.size() == 1 && regions[0]->GetName() == "DEFAULT") // only default
|
||||||
|
return { regions[0], NULL };
|
||||||
|
else if (regions.size() > 0)
|
||||||
|
{
|
||||||
|
map<ParallelRegion*, const ParallelRegionLines*> regFound;
|
||||||
|
const ParallelRegionLines* foundLines = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < regions.size(); ++i)
|
||||||
|
if (regions[i]->HasThisLine(line, file, &foundLines))
|
||||||
|
regFound[regions[i]] = foundLines;
|
||||||
|
|
||||||
|
if (regFound.size() == 0)
|
||||||
|
return { NULL, NULL };
|
||||||
|
else if (regFound.size() == 1)
|
||||||
|
return *regFound.begin();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__spf_print(1, "WARN: this lines included in more than one region!!\n");
|
||||||
|
return { NULL, NULL };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return { NULL, NULL };
|
||||||
|
|
||||||
|
return { NULL, NULL };
|
||||||
|
}
|
||||||
|
|
||||||
set<ParallelRegion*> getAllRegionsByLine(const vector<ParallelRegion*>& regions, const string& file, const int line)
|
set<ParallelRegion*> getAllRegionsByLine(const vector<ParallelRegion*>& regions, const string& file, const int line)
|
||||||
{
|
{
|
||||||
set<ParallelRegion*> regFound;
|
set<ParallelRegion*> regFound;
|
||||||
|
|||||||
52
tests/sapfor/parameter/dynamic_array_maximum.f90
Normal file
52
tests/sapfor/parameter/dynamic_array_maximum.f90
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
program dynamic_array_maximum_3d
|
||||||
|
implicit none
|
||||||
|
integer :: n1, n2, n3, n4 , k, i, j, l, a
|
||||||
|
integer :: sum3
|
||||||
|
real :: max_element
|
||||||
|
real, allocatable :: array(:,:,:), array2(:,:,:), array3(:,:,:)
|
||||||
|
|
||||||
|
write(*, *) "Enter 3 integers"
|
||||||
|
read(*, *) n, m, k
|
||||||
|
m = 100
|
||||||
|
|
||||||
|
if (1 .eq. 1) then
|
||||||
|
a = 3
|
||||||
|
else if (2 .eq. 1) then
|
||||||
|
a = 4
|
||||||
|
endif
|
||||||
|
|
||||||
|
m = m + 1
|
||||||
|
k = m * 1000 + n * 10
|
||||||
|
|
||||||
|
allocate(array(n, m + n, k + m + n), &
|
||||||
|
&array2(k, m + n, k), &
|
||||||
|
&array3(k, m, k + n))
|
||||||
|
|
||||||
|
call random_seed()
|
||||||
|
do i = 1, n1
|
||||||
|
do j = 1, m * n1
|
||||||
|
do l = 1, k * m * n1
|
||||||
|
call random_number(array(i,j,l))
|
||||||
|
array(i,j,l) = int(array(i,j,l) * 100)
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
|
||||||
|
max_element = array(1,1,1)
|
||||||
|
do i = 1, n1
|
||||||
|
do j = 1, m
|
||||||
|
do l = 1, k
|
||||||
|
max_element = MAX(array(i,j,l), max_element)
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
deallocate(array, array2, array3)
|
||||||
|
write(*, *) max_element
|
||||||
|
end program dynamic_array_maximum_3d
|
||||||
|
|
||||||
|
! function sum3(x, y, z)
|
||||||
|
! implicit none
|
||||||
|
! integer :: x, y, z
|
||||||
|
! integer :: sum3
|
||||||
|
! sum3 = x + y + z
|
||||||
|
! end function sum3
|
||||||
Reference in New Issue
Block a user