1076 lines
42 KiB
C++
1076 lines
42 KiB
C++
#include "loops_splitter.h"
|
||
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
#include "../LoopAnalyzer/loop_analyzer.h"
|
||
#include "expr_transform.h"
|
||
#include "errors.h"
|
||
#include "../CFGraph/CFGraph.h"
|
||
#include "../SageAnalysisTool/OmegaForSage/include/lang-interf.h"
|
||
#include "../DirectiveProcessing/directive_parser.h"
|
||
#include "../DirectiveProcessing/directive_omp_parser.h"
|
||
|
||
using std::string;
|
||
using std::vector;
|
||
using std::map;
|
||
using std::set;
|
||
using std::pair;
|
||
using std::make_pair;
|
||
using std::wstring;
|
||
using std::stack;
|
||
|
||
#define PRINT_SPLITTED_FRAGMENTS 0
|
||
|
||
static map<FuncInfo*, vector<SAPFOR::BasicBlock*>> currIR;
|
||
|
||
static inline bool lineInsideBorder(int lineNumber, const pair<SgStatement*, SgStatement*>& border)
|
||
{
|
||
return lineNumber >= border.first->lineNumber() && lineNumber < border.second->lineNumber();
|
||
}
|
||
|
||
static vector<SAPFOR::BasicBlock*> filterByBlock(SgStatement* block)
|
||
{
|
||
int blockStart = block->lineNumber();
|
||
int blockEnd = block->lastNodeOfStmt()->lineNumber();
|
||
if (blockEnd < blockStart)
|
||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||
|
||
if (blockEnd <= 0 || blockStart <= 0)
|
||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||
|
||
SgStatement* funcStat = getFuncStat(block);
|
||
int lineStart = funcStat->lineNumber();
|
||
|
||
vector<SAPFOR::BasicBlock*> currBlocks;
|
||
for (auto& func : currIR)
|
||
{
|
||
if (func.first->linesNum.first == lineStart)
|
||
{
|
||
currBlocks = func.second;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (currBlocks.size() == 0)
|
||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||
|
||
vector<SAPFOR::BasicBlock*> filtered;
|
||
for (auto& block : currBlocks)
|
||
{
|
||
bool needToAdd = false;
|
||
for (auto& ir : block->getInstructions())
|
||
{
|
||
int line = ir->getInstruction()->getOperator()->lineNumber();
|
||
if (blockStart <= line && blockEnd >= line)
|
||
needToAdd = true;
|
||
}
|
||
if (needToAdd)
|
||
filtered.push_back(block);
|
||
}
|
||
|
||
return filtered;
|
||
}
|
||
|
||
static int getIntervalIdx (const vector<pair<int, int>>& intervals, int line)
|
||
{
|
||
int id = -1;
|
||
for (int z = 0; z < intervals.size(); ++z)
|
||
{
|
||
if (intervals[z].first <= line && line <= intervals[z].second)
|
||
{
|
||
id = z;
|
||
break;
|
||
}
|
||
}
|
||
return id;
|
||
}
|
||
|
||
/**
|
||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> map <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
|
||
* <<3C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> : <20><><EFBFBD><EFBFBD><<3C><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>>>
|
||
* <20> since <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> till <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
*/
|
||
static map<const LoopGraph*, map<SgStatement*, pair<set<SgStatement*>, set<SgStatement*>>>> cacheDeps;
|
||
|
||
//TODO: added lines for function calls
|
||
static map<SgStatement*, pair<set<SgStatement*>, set<SgStatement*>>>
|
||
buildReachMapForLoop(const LoopGraph* parentGraphUpest, const LoopGraph* parentGraph, SgStatement* since, SgStatement* till,
|
||
const set<string>& privates, const vector<depGraph*>& depGraphs)
|
||
{
|
||
if (cacheDeps.count(parentGraph))
|
||
return cacheDeps.at(parentGraph);
|
||
|
||
const int sinceLine = since->lineNumber();
|
||
const int tillLine = till->lineNumber();
|
||
|
||
map<SgStatement*, pair<set<SgStatement*>, set<SgStatement*>>> result;
|
||
|
||
set<string> privArrays;
|
||
for (auto& elem : parentGraph->usedArraysAll)
|
||
if (privates.find(elem->GetShortName()) != privates.end())
|
||
privArrays.insert(elem->GetShortName());
|
||
|
||
map<string, set<SgStatement*>> defInBlocks;
|
||
map<string, set<SgStatement*>> useInBlocks;
|
||
|
||
vector<SgStatement*> blocks;
|
||
for (SgStatement* cur = since; cur != till; cur = cur->lexNext())
|
||
{
|
||
blocks.push_back(cur);
|
||
cur = cur->lastNodeOfStmt();
|
||
}
|
||
|
||
//TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
if (privArrays.size() != 0)
|
||
{
|
||
for (auto& block : blocks)
|
||
{
|
||
auto filtered = filterByBlock(block);
|
||
int blockStart = block->lineNumber();
|
||
int blockEnd = block->lastNodeOfStmt()->lineNumber();
|
||
|
||
for (auto& blockIR : filtered)
|
||
{
|
||
for (auto& ir : blockIR->getInstructions())
|
||
{
|
||
auto inst = ir->getInstruction();
|
||
int inLine = inst->getOperator()->lineNumber();
|
||
if (inLine < blockStart || inLine > blockEnd)
|
||
continue;
|
||
|
||
if (inst->getOperation() == SAPFOR::CFG_OP::LOAD ||
|
||
inst->getOperation() == SAPFOR::CFG_OP::STORE)
|
||
{
|
||
auto name = getNameByArg(inst->getArg1());
|
||
if (privArrays.find(name) != privArrays.end())
|
||
{
|
||
if (inst->getOperation() == SAPFOR::CFG_OP::LOAD)
|
||
useInBlocks[name].insert(block);
|
||
else
|
||
defInBlocks[name].insert(block);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> IR, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>,
|
||
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> goto.
|
||
for (int z = 0; z < blocks.size(); ++z)
|
||
{
|
||
for (auto& data : useInBlocks)
|
||
{
|
||
const string array = data.first;
|
||
if (data.second.find(blocks[z]) != data.second.end())
|
||
{
|
||
if (defInBlocks.find(array) != defInBlocks.end())
|
||
{
|
||
bool defFound = false;
|
||
for (int t = z - 1; t >= 0; --t)
|
||
{
|
||
if (defInBlocks[array].find(blocks[t]) != defInBlocks[array].end())
|
||
{
|
||
result[blocks[z]].first.insert(blocks[t]);
|
||
result[blocks[t]].second.insert(blocks[z]);
|
||
defFound = true;
|
||
}
|
||
|
||
if (defFound && useInBlocks[array].find(blocks[t]) != useInBlocks[array].end())
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
vector<pair<pair<string, string>, vector<pair<int, int>>>> data;
|
||
const LoopGraph* lp = parentGraphUpest;
|
||
while (lp)
|
||
{
|
||
auto attrsTr = getAttributes<SgStatement*, SgStatement*>(lp->loop->GetOriginal(), set<int>{ SPF_PARALLEL_DIR });
|
||
for (auto attr : attrsTr)
|
||
fillShadowAcrossFromComment(ACROSS_OP, new Statement(attr), data);
|
||
if (lp == parentGraph)
|
||
break;
|
||
lp = lp->children[0];
|
||
}
|
||
|
||
set<string> arraysWithAcross;
|
||
for (auto& elem : data)
|
||
arraysWithAcross.insert(elem.first.first);
|
||
|
||
for (depGraph* dependencyGraph : depGraphs)
|
||
{
|
||
if (dependencyGraph == NULL)
|
||
continue;
|
||
|
||
for (depNode* node : dependencyGraph->getNodes())
|
||
{
|
||
if (node->typedep == PRIVATEDEP)
|
||
continue;
|
||
if (node->typedep == REDUCTIONDEP)
|
||
continue;
|
||
|
||
if (node->varin != node->varout)
|
||
{
|
||
bool isPrivateArray = false;
|
||
if (node->typedep == ARRAYDEP)
|
||
if (privates.find(node->varin->symbol()->identifier()) != privates.end() ||
|
||
privates.find(node->varout->symbol()->identifier()) != privates.end())
|
||
isPrivateArray = true;
|
||
|
||
if (isPrivateArray)
|
||
continue;
|
||
|
||
SgStatement* statIn = node->stmtin;
|
||
SgStatement* statOut = node->stmtout;
|
||
|
||
checkNull(statIn, convertFileName(__FILE__).c_str(), __LINE__);
|
||
checkNull(statOut, convertFileName(__FILE__).c_str(), __LINE__);
|
||
|
||
if (statOut != statIn)
|
||
{
|
||
int inLine = node->stmtin->lineNumber();
|
||
int outLine = node->stmtout->lineNumber();
|
||
|
||
if (inLine == outLine)
|
||
continue;
|
||
|
||
const string nameIn = node->varin->symbol()->identifier();
|
||
const string nameOut = node->varout->symbol()->identifier();
|
||
bool isAcross = arraysWithAcross.count(nameIn) || arraysWithAcross.count(nameOut);
|
||
|
||
bool hasDependency = false;
|
||
for (int i = 1; i < node->knowndist.size(); ++i)
|
||
{
|
||
//ANTI and REDUCE
|
||
hasDependency |= (node->knowndist[i] == 0) ||
|
||
((node->knowndist[i] == 1) &&
|
||
(node->distance[i] != 0 || (isAcross && (node->kinddep == ddanti))));
|
||
}
|
||
|
||
if (hasDependency)
|
||
{
|
||
bool inIncluded = false, outIncluded = false;
|
||
if (lineInsideBorder(inLine, make_pair(since, till)))
|
||
inIncluded = true;
|
||
if (lineInsideBorder(outLine, make_pair(since, till)))
|
||
outIncluded = true;
|
||
|
||
if (!inIncluded && !outIncluded)
|
||
continue;
|
||
|
||
if (inIncluded && outIncluded)
|
||
{
|
||
result[node->stmtin].first.insert(node->stmtout);
|
||
result[node->stmtout].second.insert(node->stmtin);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// added scalar dependencies
|
||
vector<SAPFOR::BasicBlock*> bblocks;
|
||
vector<pair<int, int>> startEndBlock;
|
||
|
||
for (auto& block : blocks)
|
||
{
|
||
auto filtered = filterByBlock(block);
|
||
bblocks.insert(bblocks.end(), filtered.begin(), filtered.end());
|
||
|
||
int blockStart = block->lineNumber();
|
||
int blockEnd = block->lastNodeOfStmt()->lineNumber();
|
||
startEndBlock.push_back(make_pair(blockStart, blockEnd));
|
||
}
|
||
|
||
map<FuncInfo*, set<FuncInfo*>> callDeps;
|
||
map<string, FuncInfo*> funcByName;
|
||
map<FuncInfo*, map<SAPFOR::Argument*, set<int>>> outForFunc;
|
||
|
||
// create gen kill for blocks
|
||
map<SAPFOR::BasicBlock*, map<SAPFOR::Argument*, set<int>>> gen, kill;
|
||
map<SAPFOR::Instruction*, map<SAPFOR::Argument*, set<int>>> genForIR, killForIR;
|
||
map<SAPFOR::BasicBlock*, set<SAPFOR::Argument*>> notInitedGlobals;
|
||
|
||
for (auto& byFunc : currIR)
|
||
{
|
||
callDeps[byFunc.first].insert(byFunc.first->callsFromV.begin(), byFunc.first->callsFromV.end());
|
||
funcByName[byFunc.first->funcName] = byFunc.first;
|
||
}
|
||
|
||
vector<set<FuncInfo*>> ssc;
|
||
vector<set<FuncInfo*>> callLvls = groupByCallDependencies(callDeps, ssc);
|
||
|
||
//TODO: take into account ssc structure
|
||
for (auto& byLvl : callLvls)
|
||
{
|
||
for (auto& byFunc : byLvl)
|
||
{
|
||
auto itCFG = currIR.find(byFunc);
|
||
if (itCFG == currIR.end())
|
||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||
|
||
map<SAPFOR::Argument*, set<int>> outForCurr;
|
||
buildGenKillForCFG(itCFG->second, funcByName, outForFunc, gen, kill, &genForIR, &killForIR, notInitedGlobals, SAPFOR::CFG_Settings(0));
|
||
|
||
if (outForFunc.count(byFunc))
|
||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||
outForFunc[byFunc] = outForCurr;
|
||
}
|
||
}
|
||
|
||
for (auto& bblock : bblocks)
|
||
{
|
||
auto rd_in = bblock->getRD_In();
|
||
for (auto& ir : bblock->getInstructions())
|
||
{
|
||
auto istr = ir->getInstruction();
|
||
int line = istr->getOperator()->lineNumber();
|
||
if (line <= 0)
|
||
continue;
|
||
|
||
if (line < sinceLine || line >= tillLine)
|
||
continue;
|
||
|
||
int idOperator = getIntervalIdx(startEndBlock, line);
|
||
if (idOperator == -1)
|
||
continue;
|
||
|
||
set<SAPFOR::Argument*> use;
|
||
if (istr->getArg1() && istr->getArg1()->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||
use.insert(istr->getArg1());
|
||
|
||
if (istr->getArg2() && istr->getArg2()->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||
use.insert(istr->getArg2());
|
||
|
||
for (auto& varUse : use)
|
||
{
|
||
auto it = rd_in.find(varUse);
|
||
if (it != rd_in.end())
|
||
{
|
||
for (auto& num : it->second)
|
||
{
|
||
if (num == SAPFOR::UNINIT)
|
||
continue;
|
||
|
||
auto whereByNum = getInstructionAndBlockByNumber(currIR, num);
|
||
if (whereByNum.first == NULL)
|
||
continue;
|
||
|
||
int line = whereByNum.first->getOperator()->lineNumber();
|
||
if (idOperator != getIntervalIdx(startEndBlock, line))
|
||
{
|
||
if (line >= sinceLine && line < tillLine)
|
||
{
|
||
result[istr->getOperator()].first.insert(whereByNum.first->getOperator());
|
||
result[whereByNum.first->getOperator()].second.insert(istr->getOperator());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//else err?
|
||
}
|
||
|
||
auto itGen = genForIR.find(istr);
|
||
if (itGen != genForIR.end())
|
||
for (auto& elem : itGen->second)
|
||
if (elem.first->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||
rd_in[elem.first] = elem.second;
|
||
}
|
||
}
|
||
|
||
if (0) // deb print
|
||
{
|
||
for (auto& array : defInBlocks)
|
||
{
|
||
printf("%s defs in:\n", array.first.c_str());
|
||
for (auto& place : array.second)
|
||
printf(" -- %d\n", place->lineNumber());
|
||
printf("\n");
|
||
}
|
||
|
||
for (auto& array : useInBlocks)
|
||
{
|
||
printf("%s uses in:\n", array.first.c_str());
|
||
for (auto& place : array.second)
|
||
printf(" -- %d\n", place->lineNumber());
|
||
printf("\n");
|
||
}
|
||
|
||
for (auto& it : result)
|
||
{
|
||
printf("st: %d:\n", it.first->lineNumber());
|
||
printf("Depends on:\n");
|
||
for (auto& itt : it.second.first)
|
||
printf("%d ", itt->lineNumber());
|
||
printf("\n");
|
||
|
||
printf("Used in:\n");
|
||
for (auto& itt : it.second.second)
|
||
printf("%d ", itt->lineNumber());
|
||
printf("\n");
|
||
printf("\n");
|
||
}
|
||
}
|
||
|
||
cacheDeps[parentGraph] = result;
|
||
return result;
|
||
}
|
||
|
||
static SgForStmt* createNewLoop(const LoopGraph *globalLoop)
|
||
{
|
||
SgStatement *insertBeforeThis = globalLoop->loop->GetOriginal();
|
||
SgStatement *newLoop = NULL;
|
||
const LoopGraph *curLoopGraph = globalLoop;
|
||
vector<const LoopGraph*> graphs(globalLoop->perfectLoop);
|
||
|
||
for (int i = 0; i < globalLoop->perfectLoop; ++i)
|
||
{
|
||
graphs[i] = curLoopGraph;
|
||
if (curLoopGraph->children.size())
|
||
curLoopGraph = curLoopGraph->children[0];
|
||
}
|
||
|
||
for (int i = graphs.size() - 1; i > 0; --i)
|
||
{
|
||
SgForStmt* curForStmt = (SgForStmt*)graphs[i]->loop->GetOriginal();
|
||
newLoop = new SgForStmt(curForStmt->doName(), curForStmt->start(), curForStmt->end(), curForStmt->step(), newLoop);
|
||
}
|
||
|
||
SgForStmt *curForStmt = (SgForStmt*)graphs[0]->loop->GetOriginal();
|
||
SgForStmt *newGlobalLoop = new SgForStmt(curForStmt->doName(), curForStmt->start(), curForStmt->end(), curForStmt->step(), newLoop);
|
||
|
||
insertBeforeThis->insertStmtBefore(*newGlobalLoop, *insertBeforeThis->controlParent());
|
||
for (int z = 0; z < insertBeforeThis->numberOfAttributes(); ++z)
|
||
newGlobalLoop->addAttribute(new SgAttribute(*insertBeforeThis->getAttribute(z)));
|
||
|
||
SgStatement *lowestInsertedFor = insertBeforeThis;
|
||
for (int i = 0; i < globalLoop->perfectLoop; ++i) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> enddo
|
||
lowestInsertedFor = lowestInsertedFor->lexPrev();
|
||
|
||
return (SgForStmt*)lowestInsertedFor->lexPrev(); //<2F><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
}
|
||
|
||
static void setupOpenDependencies(set<int>& openDependencies, const vector<pair<SgStatement*, SgStatement*>>& borders,
|
||
const set<string>& loopsPrivates, const vector<depGraph*>& depGraphs)
|
||
{
|
||
for (depGraph* dependencyGraph : depGraphs)
|
||
{
|
||
if (dependencyGraph == NULL)
|
||
continue;
|
||
|
||
for (depNode* node : dependencyGraph->getNodes())
|
||
{
|
||
if (node->typedep == PRIVATEDEP)
|
||
continue;
|
||
if (node->typedep == REDUCTIONDEP)
|
||
continue;
|
||
|
||
if (node->varin != node->varout)
|
||
{
|
||
bool isPrivateArray = false;
|
||
if (node->typedep == ARRAYDEP)
|
||
if (loopsPrivates.find(node->varin->symbol()->identifier()) != loopsPrivates.end() ||
|
||
loopsPrivates.find(node->varout->symbol()->identifier()) != loopsPrivates.end())
|
||
isPrivateArray = true;
|
||
|
||
if (isPrivateArray)
|
||
continue;
|
||
|
||
SgStatement* statIn = node->stmtin;
|
||
SgStatement* statOut = node->stmtout;
|
||
|
||
checkNull(statIn, convertFileName(__FILE__).c_str(), __LINE__);
|
||
checkNull(statOut, convertFileName(__FILE__).c_str(), __LINE__);
|
||
|
||
SgStatement* sInFor = statIn;
|
||
while (sInFor && sInFor->variant() != FOR_NODE)
|
||
sInFor = sInFor->controlParent();
|
||
SgStatement* sOutFor = statOut;
|
||
while (sOutFor && sOutFor->variant() != FOR_NODE)
|
||
sOutFor = sOutFor->controlParent();
|
||
|
||
if (statOut != statIn)
|
||
{
|
||
bool hasDependency = false;
|
||
for (int i = 1; i < node->knowndist.size(); ++i)
|
||
{
|
||
//ANTI and REDUCE
|
||
hasDependency |= (node->knowndist[i] == 0) || ((node->knowndist[i] == 1) && (node->distance[i] != 0));
|
||
}
|
||
|
||
if (hasDependency)
|
||
{
|
||
int inLine = node->stmtin->lineNumber();
|
||
int outLine = node->stmtout->lineNumber();
|
||
|
||
bool inIncluded = false, outIncluded = false;
|
||
for (const auto& border : borders)
|
||
{
|
||
if (lineInsideBorder(inLine, border))
|
||
inIncluded = true;
|
||
if (lineInsideBorder(outLine, border))
|
||
outIncluded = true;
|
||
}
|
||
|
||
if (!inIncluded && !outIncluded)
|
||
continue;
|
||
|
||
if (!inIncluded && openDependencies.find(inLine) == openDependencies.end())
|
||
openDependencies.insert(inLine);
|
||
if (!outIncluded && openDependencies.find(outLine) == openDependencies.end())
|
||
openDependencies.insert(outLine);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static void addReachingDefinitionsDependencies(set<int>& openDependencies, const vector<pair<SgStatement*, SgStatement*>>& borders,
|
||
const map<SgStatement*, pair<set<SgStatement*>, set<SgStatement*>>>& requireReachMap)
|
||
{
|
||
for (const auto& border : borders)
|
||
{
|
||
for (SgStatement* current = border.first; current != border.second; current = current->lexNext())
|
||
{
|
||
auto found = requireReachMap.find(current);
|
||
if (found != requireReachMap.end())
|
||
{
|
||
for (auto it = found->second.first.begin(); it != found->second.first.end(); ++it)
|
||
{
|
||
int lineNumber = (*it)->lineNumber();
|
||
bool included = false;
|
||
for (const auto& b : borders)
|
||
{
|
||
if (lineInsideBorder(lineNumber, b))
|
||
{
|
||
included = true;
|
||
break;
|
||
}
|
||
}
|
||
if (!included && openDependencies.find(lineNumber) == openDependencies.end())
|
||
openDependencies.insert(lineNumber);
|
||
}
|
||
|
||
for (auto it = found->second.second.begin(); it != found->second.second.end(); ++it)
|
||
{
|
||
int lineNumber = (*it)->lineNumber();
|
||
bool included = false;
|
||
for (const auto& b : borders)
|
||
{
|
||
if (lineInsideBorder(lineNumber, b))
|
||
{
|
||
included = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!included && openDependencies.find(lineNumber) == openDependencies.end())
|
||
openDependencies.insert(lineNumber);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static bool dependencyAlreadyEnclosed(int lineNum, const vector<pair<SgStatement*, SgStatement*>>& borders)
|
||
{
|
||
for (const auto& border : borders)
|
||
if (lineInsideBorder(lineNum, border))
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> openDependencies <20> borders
|
||
static void expandCopyBorders(SgStatement *globalSince, SgStatement *globalTill, vector<pair<SgStatement*, SgStatement*>> &borders,
|
||
const set<int>& openDependencies)
|
||
{
|
||
for (int lineNumOfDependency : openDependencies)
|
||
{
|
||
if (dependencyAlreadyEnclosed(lineNumOfDependency, borders))
|
||
continue;
|
||
|
||
SgStatement *since = NULL, *till = NULL;
|
||
since = globalSince;
|
||
for (since = globalSince; since != globalTill; since = since->lastNodeOfStmt()->lexNext())
|
||
{
|
||
if (since->lineNumber() <= lineNumOfDependency && since->lastNodeOfStmt()->lineNumber() >= lineNumOfDependency)
|
||
{
|
||
till = since->lastNodeOfStmt()->lexNext();
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (since == globalTill) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>? <20><> <20><> <20><><EFBFBD>.
|
||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||
|
||
borders.push_back(make_pair(since, till));
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> borders
|
||
static void glueBorders(vector<pair<SgStatement*, SgStatement*>> &borders)
|
||
{
|
||
if (borders.size() <= 1)
|
||
return;
|
||
|
||
map<pair<int, int>, pair<SgStatement*, SgStatement*>> bordersMap;
|
||
for (int z = 0; z < borders.size(); ++z)
|
||
bordersMap[make_pair(borders[z].first->lineNumber(), borders[z].second->lineNumber())] = borders[z];
|
||
|
||
borders.clear();
|
||
for (auto &elem : bordersMap)
|
||
borders.push_back(elem.second);
|
||
|
||
bool needToUpdate = true;
|
||
while (needToUpdate)
|
||
{
|
||
needToUpdate = false;
|
||
vector<pair<SgStatement*, SgStatement*>> newBorders;
|
||
newBorders.push_back(borders[0]);
|
||
int lastIdx = 0;
|
||
for (int z = 1; z < borders.size(); ++z)
|
||
{
|
||
if (newBorders[lastIdx].second == borders[z].first)
|
||
newBorders[lastIdx].second = borders[z].second;
|
||
else
|
||
{
|
||
newBorders.push_back(borders[z]);
|
||
lastIdx++;
|
||
}
|
||
}
|
||
if (newBorders.size() != borders.size())
|
||
{
|
||
borders = newBorders;
|
||
needToUpdate = (borders.size() > 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
static vector<LoopGraph*> getLoopsFrom(const vector<pair<SgStatement*, SgStatement*>>& borders, LoopGraph *parentGraph, LoopGraph* parentGraphUpest)
|
||
{
|
||
vector<LoopGraph*> result;
|
||
|
||
while (parentGraphUpest != parentGraph)
|
||
{
|
||
result.push_back(parentGraphUpest);
|
||
if (parentGraphUpest->children.size() == 0 || parentGraphUpest->children.size() > 1)
|
||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||
parentGraphUpest = parentGraphUpest->children[0];
|
||
}
|
||
result.push_back(parentGraph);
|
||
|
||
for (LoopGraph *loop : parentGraph->children)
|
||
for (const auto& frag : borders)
|
||
if (loop->lineNum >= frag.first->lineNumber() && loop->lineNumAfterLoop <= frag.second->lineNumber())
|
||
result.push_back(loop);
|
||
|
||
return result;
|
||
}
|
||
|
||
static vector<depGraph*> getDepGraphsFor(const vector<LoopGraph*> &loops, LoopGraph *parentGraph, const map<LoopGraph*, depGraph*>& depInfoForLoopGraph)
|
||
{
|
||
vector<depGraph*> result;
|
||
for (auto& loop : loops)
|
||
{
|
||
if (depInfoForLoopGraph.count(loop))
|
||
result.push_back(depInfoForLoopGraph.at(loop));
|
||
else
|
||
result.push_back(NULL);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
static bool continueSplitting(SgStatement* globalSince, SgStatement* globalTill, const vector<pair<SgStatement*, SgStatement*>>& borders)
|
||
{
|
||
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
return !(borders.size() == 1 && borders[0].first == globalSince && borders[0].second == globalTill);
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> borders - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
static bool setupSplitBorders(LoopGraph* parentGraphUpest, LoopGraph* parentGraph, SgStatement* globalSince, SgStatement* globalTill,
|
||
vector<pair<SgStatement*, SgStatement*>>& borders,
|
||
const set<string>& privates,
|
||
const map<LoopGraph*, depGraph*>& depInfoForLoopGraph)
|
||
{
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD>-<2D><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
if (globalSince == globalTill)
|
||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||
|
||
borders.clear();
|
||
SgStatement *since, *till;
|
||
|
||
since = globalSince;
|
||
till = since->lastNodeOfStmt()->lexNext();
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> borders - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||
borders.push_back(make_pair(since, till));
|
||
|
||
vector<LoopGraph*> loops = getLoopsFrom(borders, parentGraph, parentGraphUpest);
|
||
vector<depGraph*> depGraphs = getDepGraphsFor(loops, parentGraph, depInfoForLoopGraph);
|
||
|
||
__spf_print(PRINT_SPLITTED_FRAGMENTS, "Initial fragment: %d - %d\n", since->lineNumber(), till->lineNumber());
|
||
|
||
const auto requireReachMap = buildReachMapForLoop(parentGraphUpest, parentGraph, globalSince, globalTill, privates, depGraphs);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> borders
|
||
set<int> openDependencies;
|
||
|
||
setupOpenDependencies(openDependencies, borders, privates, depGraphs);
|
||
addReachingDefinitionsDependencies(openDependencies, borders, requireReachMap);
|
||
|
||
while (openDependencies.size() > 0)
|
||
{
|
||
#if PRINT_SPLITTED_FRAGMENTS == 1
|
||
__spf_print(PRINT_SPLITTED_FRAGMENTS, "Line dependencies:\n", globalSince->lineNumber(), globalTill->lineNumber());
|
||
for (auto& it : openDependencies)
|
||
__spf_print(PRINT_SPLITTED_FRAGMENTS, " %d,", it);
|
||
__spf_print(PRINT_SPLITTED_FRAGMENTS, "\n");
|
||
#endif
|
||
|
||
expandCopyBorders(globalSince, globalTill, borders, openDependencies);
|
||
openDependencies.clear();
|
||
|
||
loops = getLoopsFrom(borders, parentGraph, parentGraphUpest);
|
||
depGraphs = getDepGraphsFor(loops, parentGraph, depInfoForLoopGraph);
|
||
setupOpenDependencies(openDependencies, borders, privates, depGraphs);
|
||
addReachingDefinitionsDependencies(openDependencies, borders, requireReachMap);
|
||
}
|
||
|
||
#if PRINT_SPLITTED_FRAGMENTS == 1
|
||
for (auto &fragment : borders)
|
||
__spf_print(PRINT_SPLITTED_FRAGMENTS, "fragment %d - %d\n", fragment.first->lineNumber(), fragment.second->lineNumber());
|
||
#endif
|
||
|
||
|
||
glueBorders(borders);
|
||
|
||
return continueSplitting(globalSince, globalTill, borders);
|
||
}
|
||
|
||
static void filterSpfAttributes(SgStatement* stat)
|
||
{
|
||
int count = stat->numberOfAttributes();
|
||
if (count)
|
||
{
|
||
SgStatement* lastNode = stat->lastNodeOfStmt();
|
||
//TODO: added filter for private, reduction and ...
|
||
for (int z = 0; z < count; ++z)
|
||
{
|
||
SgAttribute* attr = stat->getAttribute(z);
|
||
if (attr->getAttributeType() == SPF_ANALYSIS_DIR)
|
||
{
|
||
SgStatement* data = (SgStatement*)attr->getAttributeData();
|
||
if (data->localLineNumber() != SPF_USER_DIR)
|
||
continue;
|
||
//__spf_print(1, "%s", data->unparse());
|
||
|
||
set<string> privates;
|
||
fillPrivatesFromComment(new Statement(data), privates);
|
||
|
||
if (privates.size())
|
||
{
|
||
set<string> assignTo;
|
||
for (SgStatement* st = stat; st != lastNode; st = st->lexNext())
|
||
{
|
||
if (st->variant() == ASSIGN_STAT)
|
||
{
|
||
auto ex = st->expr(0)->symbol();
|
||
if (ex)
|
||
assignTo.insert(ex->identifier());
|
||
}
|
||
}
|
||
|
||
set<string> actualPrivate;
|
||
for (auto& elem : privates)
|
||
if (assignTo.find(elem) != assignTo.end())
|
||
actualPrivate.insert(elem);
|
||
|
||
if (actualPrivate.size() != privates.size())
|
||
{
|
||
__spf_print(1, "actual private size %d, in dir %d\n", actualPrivate.size(), privates.size());
|
||
SgExpression* exprList = data->expr(0);
|
||
vector<SgExpression*> newData;
|
||
while (exprList)
|
||
{
|
||
if (exprList->lhs()->variant() == ACC_PRIVATE_OP)
|
||
{
|
||
if (actualPrivate.size())
|
||
{
|
||
SgExpression* list = exprList->lhs()->lhs();
|
||
vector<SgExpression*> newList;
|
||
while (list)
|
||
{
|
||
if (actualPrivate.find(list->lhs()->symbol()->identifier()) != actualPrivate.end())
|
||
newList.push_back(list->lhs());
|
||
list = list->rhs();
|
||
}
|
||
|
||
if (newList.size())
|
||
{
|
||
exprList->lhs()->setLhs(makeExprList(newList));
|
||
newData.push_back(exprList->lhs());
|
||
}
|
||
}
|
||
}
|
||
else
|
||
newData.push_back(exprList->lhs());
|
||
exprList = exprList->rhs();
|
||
}
|
||
|
||
if (newData.size() == 0)
|
||
{
|
||
__spf_print(1, "remove attribute on line %d\n", stat->lineNumber());
|
||
stat->deleteAttribute(z);
|
||
count--;
|
||
}
|
||
else
|
||
{
|
||
__spf_print(1, "set new data size %d\n", newData.size());
|
||
data->setExpression(0, makeExprList(newData));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static void moveStatements(SgForStmt *newLoop, const vector<pair<SgStatement*, SgStatement*>> &fragments, int deep)
|
||
{
|
||
//newLoop is lowest
|
||
SgStatement* lastInserted = newLoop->lastNodeOfStmt();
|
||
SgStatement* cp = lastInserted->controlParent();
|
||
|
||
for (const auto& fragment : fragments)
|
||
{
|
||
SgStatement *toMoveStmt = fragment.first;
|
||
while (toMoveStmt != fragment.second)
|
||
{
|
||
SgStatement *st = toMoveStmt;
|
||
toMoveStmt = toMoveStmt->lastNodeOfStmt()->lexNext();
|
||
|
||
lastInserted->insertStmtBefore(*st->extractStmt(), *cp);
|
||
}
|
||
}
|
||
|
||
for (int z = 0; z < deep - 1; ++z)
|
||
{
|
||
newLoop = isSgForStmt(newLoop->controlParent());
|
||
checkNull(newLoop, convertFileName(__FILE__).c_str(), __LINE__);
|
||
}
|
||
|
||
filterSpfAttributes(newLoop);
|
||
}
|
||
|
||
static bool hasIndirectChildLoops(const LoopGraph* parentGraph, vector<Messages> &messages)
|
||
{
|
||
SgStatement* st = parentGraph->loop->GetOriginal()->lexNext();
|
||
int directLoops = 0;
|
||
while (st->variant() != CONTROL_END)
|
||
{
|
||
if (st->variant() == FOR_NODE)
|
||
directLoops++;
|
||
st = st->lastNodeOfStmt()->lexNext();
|
||
}
|
||
|
||
if (directLoops != parentGraph->children.size())
|
||
{
|
||
messages.push_back(Messages(ERROR, parentGraph->loop->GetOriginal()->lineNumber(), R105,
|
||
L"This loop has indirect child loops and can not be splitted", 2010));
|
||
__spf_print(1, "This loop has indirect child loops and can not be splitted on line %d\n", parentGraph->lineNum);
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
|
||
static bool hasUnexpectedDependencies(const LoopGraph* parentGraph, const depGraph* parentDepGraph,
|
||
const set<string>& privateVars, vector<Messages>& messages)
|
||
{
|
||
bool has = false;
|
||
int countOfMessages = 10;
|
||
int idxOfMessages = 0;
|
||
|
||
if (parentDepGraph == NULL)
|
||
return false;
|
||
|
||
for (depNode* node : parentDepGraph->getNodes())
|
||
{
|
||
if (node->typedep != ARRAYDEP)
|
||
{
|
||
bool privateInChild = false;
|
||
for (LoopGraph* childGraph : parentGraph->children)
|
||
{
|
||
SgStatement *childLoop = childGraph->loop->GetOriginal();
|
||
if (lineInsideBorder(node->stmtin->lineNumber(), make_pair(childLoop, childLoop->lastNodeOfStmt()->lexNext())))
|
||
privateInChild = (node->typedep == PRIVATEDEP);
|
||
}
|
||
|
||
// is it private for this loop
|
||
if (!privateInChild)
|
||
if (node->varin->symbol() && privateVars.find(node->varin->symbol()->identifier()) != privateVars.end())
|
||
privateInChild = true;
|
||
|
||
has |= !privateInChild;
|
||
if (!privateInChild)
|
||
{
|
||
if (idxOfMessages < countOfMessages)
|
||
{
|
||
idxOfMessages++;
|
||
string str;
|
||
__spf_printToBuf(str, "Can not split this loop because of dependency: %s", node->displayDepToStr().c_str());
|
||
__spf_print(1, "%s on line %d\n", str.c_str(), parentGraph->lineNum);
|
||
|
||
wstring strR, strE;
|
||
__spf_printToLongBuf(strE, L"Can not split this loop because of dependency: %s",
|
||
to_wstring(node->displayDepToStr()).c_str());
|
||
|
||
__spf_printToLongBuf(strR, R104, to_wstring(node->displayDepToStr()).c_str());
|
||
messages.push_back(Messages(WARR, parentGraph->lineNum, strR, strE, 2009));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return has;
|
||
}
|
||
|
||
static int splitLoop(LoopGraph *loopGraph, vector<Messages> &messages, int deep, const map<LoopGraph*, depGraph*>& depInfoForLoopGraph)
|
||
{
|
||
LoopGraph *lowestParentGraph = loopGraph;
|
||
for (int i = 0; i < std::min(loopGraph->perfectLoop, deep) - 1; ++i)
|
||
{
|
||
if (lowestParentGraph->children.size() == 1)
|
||
lowestParentGraph = lowestParentGraph->children[0];
|
||
else
|
||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||
}
|
||
|
||
if (hasIndirectChildLoops(lowestParentGraph, messages))
|
||
return -1;
|
||
|
||
if (lowestParentGraph->hasLimitsToSplit())
|
||
{
|
||
messages.push_back(Messages(ERROR, loopGraph->lineNum,
|
||
R106 + std::to_wstring(lowestParentGraph->lineNum),
|
||
L"This loop has limits (goto, print, stops or not DO-ENDDO) for splitting (reason: loop on line " + std::to_wstring(lowestParentGraph->lineNum) + L")",
|
||
2010));
|
||
|
||
__spf_print(1, "%d loop has limits (goto, print, stops or not DO-ENDDO) for splitting (reason: loop on line %d)\n", loopGraph->lineNum, lowestParentGraph->lineNum);
|
||
return -1;
|
||
}
|
||
|
||
set<string> privates;
|
||
tryToFindPrivateInAttributes(loopGraph->loop, privates);
|
||
|
||
const set<string> privVars;
|
||
const depGraph* lowestParentDepGraph = NULL;
|
||
if (depInfoForLoopGraph.count(lowestParentGraph))
|
||
lowestParentDepGraph = depInfoForLoopGraph.at(lowestParentGraph);
|
||
|
||
if (hasUnexpectedDependencies(lowestParentGraph, lowestParentDepGraph, privates, messages))
|
||
{
|
||
messages.push_back(Messages(ERROR, loopGraph->lineNum,
|
||
R107 + std::to_wstring(lowestParentGraph->lineNum),
|
||
L"This loop has unexpected dependencies and can not be splitted (reason: loop on line " + std::to_wstring(lowestParentGraph->lineNum) + L")",
|
||
2010));
|
||
|
||
__spf_print(1, "%d loop has unexpected dependencies and can not be splitted (reason: loop on line %d)\n",
|
||
loopGraph->lineNum, lowestParentGraph->lineNum);
|
||
return -1;
|
||
}
|
||
|
||
SgStatement *globalSince, *globalTill;
|
||
globalSince = lowestParentGraph->loop->GetOriginal()->lexNext();
|
||
globalTill = lowestParentGraph->loop->GetOriginal()->lastNodeOfStmt();
|
||
|
||
vector<pair<SgStatement*, SgStatement*>> borders;
|
||
bool setup = setupSplitBorders(loopGraph, lowestParentGraph, globalSince, globalTill, borders, privates, depInfoForLoopGraph);
|
||
|
||
SgStatement* prev = loopGraph->loop->lexPrev();
|
||
bool hasSplited = false;
|
||
while (setup && borders.size() > 0) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
hasSplited = true;
|
||
#if PRINT_SPLITTED_FRAGMENTS == 1
|
||
__spf_print(PRINT_SPLITTED_FRAGMENTS, "global since %d, global till %d\n", globalSince->lineNumber(), globalTill->lineNumber());
|
||
__spf_print(PRINT_SPLITTED_FRAGMENTS, "result fragment: ");
|
||
for (auto& it : borders)
|
||
__spf_print(PRINT_SPLITTED_FRAGMENTS, "%d - %d, ", it.first->lineNumber(), it.second->lineNumber());
|
||
__spf_print(PRINT_SPLITTED_FRAGMENTS, "\n");
|
||
#endif
|
||
moveStatements(createNewLoop(loopGraph), borders, deep);
|
||
globalSince = lowestParentGraph->loop->GetOriginal()->lexNext();
|
||
|
||
setup = setupSplitBorders(loopGraph, lowestParentGraph, globalSince, globalTill, borders, privates, depInfoForLoopGraph);
|
||
}
|
||
|
||
//move comment to uppest loop
|
||
if (hasSplited)
|
||
{
|
||
if (loopGraph->loop->comments())
|
||
{
|
||
prev->lexNext()->addComment(loopGraph->loop->comments());
|
||
loopGraph->loop->delComments();
|
||
}
|
||
}
|
||
return hasSplited ? 0 : 1;
|
||
}
|
||
|
||
int splitLoops(SgFile *file, vector<LoopGraph*> &loopGraphs, vector<Messages> &messages,
|
||
const map<LoopGraph*, depGraph*>& depInfoForLoopGraph,
|
||
const map<string, CommonBlock*>& commonBlocks,
|
||
const map<string, vector<FuncInfo*>>& allFuncInfo, int &countOfTransform)
|
||
{
|
||
cacheDeps.clear();
|
||
map<int, LoopGraph*> mapLoopGraph;
|
||
createMapLoopGraph(loopGraphs, mapLoopGraph);
|
||
int totalErr = 0;
|
||
|
||
for (auto &loopPair : mapLoopGraph)
|
||
{
|
||
if (!loopPair.second->isFor())
|
||
continue;
|
||
|
||
LoopGraph *loop = loopPair.second;
|
||
auto attrsTr = getAttributes<SgStatement*, SgStatement*>(loop->loop->GetOriginal(), set<int>{ SPF_TRANSFORM_DIR });
|
||
for (auto attr : attrsTr)
|
||
{
|
||
SgExpression *list = attr->expr(0);
|
||
if (list->lhs()->variant() == SPF_FISSION_OP)
|
||
{
|
||
checkNull(list->lhs()->lhs(), convertFileName(__FILE__).c_str(), __LINE__);
|
||
|
||
SgExprListExp *listExp = isSgExprListExp(list->lhs()->lhs());
|
||
checkNull(listExp, convertFileName(__FILE__).c_str(), __LINE__);
|
||
int deep = listExp->length();
|
||
|
||
currIR = buildCFGforCurrentFunc(loop->loop, SAPFOR::CFG_Settings(true, true), commonBlocks, allFuncInfo);
|
||
totalErr = splitLoop(loop, messages, deep, depInfoForLoopGraph);
|
||
|
||
if (totalErr > 0)
|
||
{
|
||
messages.push_back(Messages(ERROR, loop->lineNum, R196, L"The loop transformation cannot be performed due to dependencies between operators", 2022));
|
||
__spf_print(1, "%d The loop transformation cannot be performed due to dependencies between operators\n", loop->lineNum);
|
||
}
|
||
else if (totalErr == 0)
|
||
{
|
||
filterSpfAttributes(loop->loop->GetOriginal());
|
||
countOfTransform++;
|
||
}
|
||
|
||
deleteCFG(currIR);
|
||
}
|
||
}
|
||
}
|
||
|
||
cacheDeps.clear();
|
||
return totalErr;
|
||
}
|