632 lines
21 KiB
C++
632 lines
21 KiB
C++
#include "leak_detector.h"
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
#include <set>
|
|
|
|
#include "loop_transform.h"
|
|
#include "../DirectiveProcessing/directive_parser.h"
|
|
#include "../SageAnalysisTool/OmegaForSage/include/lang-interf.h"
|
|
#include "../SageAnalysisTool/definesValues.h"
|
|
#include "SgUtils.h"
|
|
#include "../SageAnalysisTool/depGraph.h"
|
|
#include "graph_calls_func.h"
|
|
|
|
using std::pair;
|
|
using std::map;
|
|
using std::tuple;
|
|
using std::stack;
|
|
using std::string;
|
|
using std::vector;
|
|
using std::set;
|
|
using std::make_pair;
|
|
|
|
static void buildTopParentLoop(LoopGraph *current, LoopGraph *top, map<LoopGraph*, LoopGraph*> &loopTopMap)
|
|
{
|
|
loopTopMap[current] = top;
|
|
for (int i = 0; i < current->children.size(); ++i)
|
|
buildTopParentLoop(current->children[i], top, loopTopMap);
|
|
}
|
|
|
|
static void buildLoopMap(LoopGraph *current, map<PTR_BFND, LoopGraph*> &loopMap)
|
|
{
|
|
loopMap[current->loop->thebif] = current;
|
|
for (int i = 0; i < current->children.size(); ++i)
|
|
buildLoopMap(current->children[i], loopMap);
|
|
}
|
|
|
|
void reverseCreatedNestedLoops(const string &file, vector<LoopGraph*> &loopsInFile)
|
|
{
|
|
map<PTR_BFND, LoopGraph*> loopMap;
|
|
map<LoopGraph*, LoopGraph*> loopTopMap;
|
|
|
|
for (auto &elem : loopsInFile)
|
|
{
|
|
buildLoopMap(elem, loopMap);
|
|
buildTopParentLoop(elem, elem, loopTopMap);
|
|
}
|
|
|
|
//TODO: need to rewrite
|
|
/*
|
|
auto *launches = SageTransform::LoopTransformTighten::getLaunches();
|
|
if (launches->count(file) == 0) {
|
|
__spf_print(1, " nothing to revert in %s\n", file.c_str());
|
|
return;
|
|
}
|
|
stack<pair<SgForStmt*, SageTransform::LineReorderRecord>> &backOrder = launches->at(file);
|
|
set<LoopGraph*> topLoopsToRecalaulate;
|
|
|
|
while (backOrder.size())
|
|
{
|
|
auto &elem = backOrder.top();
|
|
auto it = loopMap.find(elem.first->thebif);
|
|
if (it == loopMap.end())
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
auto reorder = elem.second.buildReverse();
|
|
SageTransform::LineReorderer::apply(elem.first, reorder);
|
|
topLoopsToRecalaulate.insert(loopTopMap[it->second]);
|
|
backOrder.pop();
|
|
}
|
|
|
|
for (auto &elem : topLoopsToRecalaulate)
|
|
{
|
|
elem->recalculatePerfect();
|
|
elem->restoreDirective();
|
|
}*/
|
|
}
|
|
|
|
static void fillPrivateAndReductionFromComment(SgStatement *st, set<Symbol*> &privates,
|
|
map<string, set<Symbol*>> &reduction,
|
|
map<string, set<tuple<Symbol*, Symbol*, int>>> &reduction_loc)
|
|
{
|
|
for (auto &data : getAttributes<SgStatement*, SgStatement*>(st, set<int>{ SPF_ANALYSIS_DIR }))
|
|
{
|
|
fillPrivatesFromComment(new Statement(data), privates);
|
|
fillReductionsFromComment(new Statement(data), reduction);
|
|
fillReductionsFromComment(new Statement(data), reduction_loc);
|
|
}
|
|
}
|
|
|
|
static pair<SgForStmt*, depGraph*> getDepGraph(LoopGraph *loopGraph, const map<LoopGraph*, depGraph*> &depInfoForLoopGraph)
|
|
{
|
|
SgForStmt *sgForStmt = NULL;
|
|
depGraph *dg = NULL;
|
|
|
|
if (depInfoForLoopGraph.count(loopGraph) == 0)
|
|
__spf_print(1, "getDepGraph for loop at %d. No depGraph found\n", loopGraph->lineNum);
|
|
else
|
|
{
|
|
dg = depInfoForLoopGraph.at(loopGraph);
|
|
sgForStmt = isSgForStmt(dg->loop);
|
|
if (sgForStmt == NULL)
|
|
__spf_print(1, "getDepGraph for loop at %d. SgForStmt missing for depGraph\n", loopGraph->lineNum);
|
|
}
|
|
|
|
return make_pair(sgForStmt, dg);
|
|
}
|
|
|
|
static ddnature fromDepNode(depNode *node)
|
|
{
|
|
if (node->typedep == SCALARDEP || node->typedep == PRIVATEDEP)
|
|
{
|
|
ddnature nature = (ddnature) node->kinddep;
|
|
switch (nature)
|
|
{
|
|
case ddflow:
|
|
case ddanti:
|
|
case ddoutput:
|
|
return nature;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return dd_unknown;
|
|
}
|
|
|
|
static void displayDep(const depNode *dn)
|
|
{
|
|
SgExpression *ex1, *ex2;
|
|
int i;
|
|
ddnature nature;
|
|
ex1 = dn->varin;
|
|
ex2 = dn->varout;
|
|
|
|
|
|
if (!dn->typedep)
|
|
{
|
|
__spf_print(1, "UNKNOWN DATA DEPENDENCE\n");
|
|
return;
|
|
}
|
|
|
|
if (dn->typedep == ARRAYDEP)
|
|
{
|
|
nature = (ddnature)dn->kinddep;
|
|
__spf_print(1, "------> ");
|
|
switch (nature)
|
|
{
|
|
case ddflow:
|
|
__spf_print(1, "FLOW dependence between ");
|
|
break;
|
|
case ddanti:
|
|
__spf_print(1, "ANTI dependence between ");
|
|
break;
|
|
case ddoutput:
|
|
__spf_print(1, "OUTPUT dependence between ");
|
|
break;
|
|
case ddreduce:
|
|
__spf_print(1, "REDUCE dependence between ");
|
|
break;
|
|
}
|
|
|
|
__spf_print(1, "%s", ex1->unparse());
|
|
__spf_print(1, " (line %d) and ", dn->stmtin->lineNumber());
|
|
__spf_print(1, "%s", ex2->unparse());
|
|
__spf_print(1, " (line %d) with vector (", dn->stmtout->lineNumber());
|
|
for (i = 1; i <= dn->lenghtvect; i++)
|
|
{
|
|
if (dn->knowndist[i])
|
|
__spf_print(1, "%d", dn->distance[i]);
|
|
else
|
|
{
|
|
if (dn->distance[i] & DEPZERO)
|
|
__spf_print(1, "0");
|
|
if (dn->distance[i] & DEPGREATER)
|
|
__spf_print(1, "+");
|
|
if (dn->distance[i] & DEPLESS)
|
|
__spf_print(1, "-");
|
|
}
|
|
|
|
if (i < dn->lenghtvect)
|
|
__spf_print(1, ", ");
|
|
}
|
|
__spf_print(1, ")\n");
|
|
}
|
|
else
|
|
{
|
|
__spf_print(1, "------> ");
|
|
__spf_print(1, "This is a Scalar Dep on ");
|
|
__spf_print(1, "%s", ex1->unparse());
|
|
if (dn->typedep == PRIVATEDEP)
|
|
__spf_print(1, " and variable can be PRIVATE");
|
|
if (dn->typedep == REDUCTIONDEP)
|
|
__spf_print(1, " and variable can be REDUCTION with kind %d", dn->kinddep);
|
|
__spf_print(1, "\n");
|
|
}
|
|
}
|
|
|
|
static void printDepGraph(depGraph *dg)
|
|
{
|
|
if(dg == NULL)
|
|
return;
|
|
|
|
for (depNode *dn : dg->getNodes())
|
|
{
|
|
displayDep(dn);
|
|
/*int out = dn->stmtout != NULL ? dn->stmtout->lineNumber() : -1;
|
|
int in = dn->stmtin != NULL ? dn->stmtin->lineNumber() : -1;
|
|
__spf_print(1, "dep from %d --> %d\n", out, in);*/
|
|
}
|
|
}
|
|
|
|
static void addToMap(SgStatement *stmt, depGraph *depGraph, map<SgSymbol*, ddnature> &depMap)
|
|
{
|
|
depNode *node = NULL;
|
|
|
|
for (auto &dn : depGraph->getNodes())
|
|
{
|
|
//TODO: process ARRAYDEP!
|
|
if (dn->typedep > ARRAYDEP && dn->stmtin == stmt)
|
|
{
|
|
node = dn;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (node != NULL)
|
|
{
|
|
ddnature type = fromDepNode(node);
|
|
if (node->typedep == SCALARDEP)
|
|
type = ddoutput;
|
|
|
|
SgSymbol *symbol = node->varin->symbol();
|
|
|
|
auto it = depMap.find(symbol);
|
|
if(it != depMap.end())
|
|
depMap[symbol] = (it->second < type ? type : it->second);
|
|
else
|
|
depMap.insert(make_pair(symbol, type));
|
|
}
|
|
}
|
|
|
|
static map<SgSymbol*, ddnature> buildTransformerDependencyMap(SgForStmt *outerLoop, depGraph *outerDepGraph, SgForStmt *innerLoop, depGraph *innerDepGraph)
|
|
{
|
|
__spf_print(1, "Print outer depgraph START\n");
|
|
printDepGraph(outerDepGraph);
|
|
__spf_print(1, "Print outer depgraph END\n");
|
|
|
|
__spf_print(1, "Print inner depgraph START\n");
|
|
printDepGraph(innerDepGraph);
|
|
__spf_print(1, "Print inner depgraph END\n");
|
|
|
|
map<SgSymbol*, ddnature> depMap;
|
|
|
|
for (SgStatement *stmt = outerLoop->lexNext(); stmt != outerLoop->lastNodeOfStmt(); stmt = stmt->lexNext())
|
|
{
|
|
addToMap(stmt, innerDepGraph, depMap);
|
|
addToMap(stmt, outerDepGraph, depMap);
|
|
}
|
|
|
|
return depMap;
|
|
}
|
|
|
|
static SgForStmt* lexNextLoop(SgStatement* pStmt, SgStatement* end)
|
|
{
|
|
SgStatement* pClosestDo = pStmt;
|
|
while (!isSgForStmt(pClosestDo) && pClosestDo != end)
|
|
pClosestDo = pClosestDo->lexNext();
|
|
return isSgForStmt(pClosestDo);
|
|
}
|
|
|
|
static ddnature getOrDefault(const map<SgSymbol*, ddnature> &inMap, SgSymbol *key, ddnature defaultValue)
|
|
{
|
|
//implementation must be visible to compiler
|
|
auto it = inMap.find(key);
|
|
if (it == inMap.end())
|
|
return defaultValue;
|
|
else
|
|
return it->second;
|
|
};
|
|
|
|
static void processArgs(SgExpression *ex, set<SgSymbol*> &assignToScalars, bool &allAssignmentOrIf, int numArg, const FuncInfo *currF)
|
|
{
|
|
if (ex)
|
|
{
|
|
bool onlyIn = false;
|
|
if (currF)
|
|
if (currF->funcParams.isArgIn(numArg) && !currF->funcParams.isArgOut(numArg))
|
|
onlyIn = true;
|
|
|
|
if (ex->variant() == ARRAY_REF)
|
|
{
|
|
if (!onlyIn)
|
|
allAssignmentOrIf = false;
|
|
}
|
|
else if (ex->variant() == VAR_REF)
|
|
{
|
|
if (!onlyIn)
|
|
assignToScalars.insert(OriginalSymbol(ex->symbol()));
|
|
}
|
|
}
|
|
}
|
|
|
|
static void findfuncCalls(SgExpression *ex, set<SgSymbol*>& assignToScalars, bool& allAssignmentOrIf, const map<string, FuncInfo*>& mapFuncInfo)
|
|
{
|
|
if (ex)
|
|
{
|
|
if (ex->variant() == FUNC_CALL)
|
|
{
|
|
SgFunctionCallExp* funcExp = (SgFunctionCallExp*)ex;
|
|
const string fName = funcExp->funName()->identifier();
|
|
if (!isIntrinsicFunctionName(fName.c_str()))
|
|
{
|
|
auto itF = mapFuncInfo.find(fName);
|
|
FuncInfo* currF = NULL;
|
|
if (itF != mapFuncInfo.end())
|
|
currF = itF->second;
|
|
|
|
for (int z = 0; z < funcExp->numberOfArgs(); ++z)
|
|
processArgs(funcExp->arg(z), assignToScalars, allAssignmentOrIf, z, currF);
|
|
}
|
|
}
|
|
|
|
findfuncCalls(ex->lhs(), assignToScalars, allAssignmentOrIf, mapFuncInfo);
|
|
findfuncCalls(ex->rhs(), assignToScalars, allAssignmentOrIf, mapFuncInfo);
|
|
}
|
|
}
|
|
|
|
static bool processInterval(SgStatement* invBegin, SgStatement* invEnd, set<SgSymbol*>& assignToScalars, const map<string, FuncInfo*>& mapFuncInfo)
|
|
{
|
|
bool allAssignmentOrIf = true;
|
|
|
|
SgStatement* stmt = invBegin;
|
|
while (stmt != invEnd)
|
|
{
|
|
allAssignmentOrIf = allAssignmentOrIf && (isSgAssignStmt(stmt) || isSgIfStmt(stmt) || isSgLogIfStmt(stmt) || isSgControlEndStmt(stmt));
|
|
|
|
if (stmt->variant() == ASSIGN_STAT)
|
|
{
|
|
if (stmt->expr(0)->variant() == ARRAY_REF)
|
|
allAssignmentOrIf = false;
|
|
else
|
|
assignToScalars.insert(OriginalSymbol(stmt->expr(0)->symbol()));
|
|
}
|
|
else if (stmt->variant() == PROC_STAT)
|
|
{
|
|
if (!isIntrinsicFunctionName(stmt->symbol()->identifier()))
|
|
{
|
|
auto itF = mapFuncInfo.find(stmt->symbol()->identifier());
|
|
FuncInfo* currF = NULL;
|
|
if (itF != mapFuncInfo.end())
|
|
currF = itF->second;
|
|
|
|
int num = 0;
|
|
for (SgExpression* ex = stmt->expr(0); ex; ex = ex->rhs(), ++num)
|
|
processArgs(ex->lhs(), assignToScalars, allAssignmentOrIf, num, currF);
|
|
}
|
|
}
|
|
|
|
for (int z = 0; z < 3; ++z)
|
|
findfuncCalls(stmt->expr(z), assignToScalars, allAssignmentOrIf, mapFuncInfo);
|
|
|
|
stmt = stmt->lexNext();
|
|
}
|
|
|
|
return allAssignmentOrIf;
|
|
}
|
|
|
|
static bool validateInvariantStatement(SgStatement* invBegin, SgStatement* invEnd,
|
|
const map<SgSymbol*, ddnature> &dependencies, const map<string, FuncInfo*>& mapFuncInfo)
|
|
{
|
|
//by type check
|
|
SgStatement* stmt = invBegin;
|
|
set<SgSymbol*> assignToScalarsOuter;
|
|
set<SgSymbol*> assignToScalarsInner;
|
|
bool allAssignmentOrIf = processInterval(invBegin, invEnd, assignToScalarsOuter, mapFuncInfo);
|
|
processInterval(invEnd, invEnd->lastNodeOfStmt(), assignToScalarsInner, mapFuncInfo);
|
|
|
|
if (allAssignmentOrIf)
|
|
{
|
|
//TODO: use CFG graph for this analysis
|
|
//TODO: improve it
|
|
for (auto& elem : assignToScalarsInner)
|
|
if (assignToScalarsOuter.find(elem) != assignToScalarsOuter.end())
|
|
return false;
|
|
|
|
bool hasFlowDep = false;
|
|
stmt = invBegin;
|
|
while (stmt != invEnd && !hasFlowDep)
|
|
{
|
|
SgAssignStmt* assignStmt = isSgAssignStmt(stmt);
|
|
if(assignStmt)
|
|
{
|
|
SgSymbol* symbol = assignStmt->lhs()->symbol();
|
|
auto dependency = getOrDefault(dependencies, symbol, ddnovalue);
|
|
hasFlowDep = hasFlowDep
|
|
|| dependency == ddflow
|
|
|| dependency == dd_unknown;
|
|
}
|
|
stmt = stmt->lexNext();
|
|
}
|
|
|
|
if (hasFlowDep)
|
|
{
|
|
bool hasAntiOrOutputDep = false;
|
|
stmt = invBegin;
|
|
while (stmt != invEnd && !hasAntiOrOutputDep)
|
|
{
|
|
SgAssignStmt* assignStmt = isSgAssignStmt(stmt);
|
|
if(assignStmt)
|
|
{
|
|
SgSymbol* symbol = assignStmt->lhs()->symbol();
|
|
auto dependency = getOrDefault(dependencies, symbol, ddnovalue);
|
|
hasAntiOrOutputDep = hasAntiOrOutputDep
|
|
|| dependency == ddanti
|
|
|| dependency == ddoutput
|
|
|| dependency == dd_unknown;
|
|
}
|
|
stmt = stmt->lexNext();
|
|
}
|
|
|
|
if (!hasAntiOrOutputDep)
|
|
{
|
|
__spf_print(1, "%d : Only flow dependencies present, can tighten.\n", invBegin->lineNumber());
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
__spf_print(1, "%d : Invariant value not used in loop, can tighten.\n", invBegin->lineNumber());
|
|
return true;
|
|
}
|
|
}
|
|
__spf_print(1, "%d : Invariant cannot be moved into loop.\n", invBegin->lineNumber());
|
|
return false;
|
|
}
|
|
|
|
static bool canTightenSingleLevel(SgForStmt* outerLoop, const map<SgSymbol*, ddnature> &dependencies, const map<string, FuncInfo*>& mapFuncInfo)
|
|
{
|
|
SgStatement* outerEnddo = outerLoop->lastNodeOfStmt();
|
|
SgForStmt* innerLoop = lexNextLoop(outerLoop->lexNext(), outerEnddo);
|
|
if (innerLoop != NULL)
|
|
{
|
|
bool beforeValid = validateInvariantStatement(outerLoop->lexNext(), innerLoop, dependencies, mapFuncInfo);
|
|
//TODO:
|
|
//validateInvariantStatement(innerLoop->lastNodeOfStmt()->lexNext(), outerEnddo, dependencies);
|
|
bool afterValid = (outerLoop->lastNodeOfStmt() == innerLoop->lastNodeOfStmt()->lexNext());
|
|
|
|
return beforeValid && afterValid;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
static int canTighten(SgForStmt* pForLoop, const map<SgSymbol*, ddnature> &dependencies, const map<string, FuncInfo*>& mapFuncInfo)
|
|
{
|
|
int nestDepth = 1;
|
|
SgForStmt* processedLoop = pForLoop;
|
|
while (canTightenSingleLevel(processedLoop, dependencies, mapFuncInfo))
|
|
{
|
|
processedLoop = lexNextLoop(processedLoop->lexNext(), NULL);
|
|
nestDepth++;
|
|
}
|
|
|
|
if (nestDepth == 1)
|
|
return 0;
|
|
else
|
|
return nestDepth;
|
|
}
|
|
|
|
static int canTighten(SgForStmt* pForLoop)
|
|
{
|
|
int nestnessLevel = 1;
|
|
SgForStmt* nextOuterLoop = pForLoop;
|
|
while (nextOuterLoop)
|
|
{
|
|
SgStatement* outerLoopControlEnd = nextOuterLoop->lastNodeOfStmt();
|
|
SgStatement* nextInnerLoop = nextOuterLoop->lexNext();
|
|
while (!isSgForStmt(nextInnerLoop) && nextInnerLoop != outerLoopControlEnd)
|
|
nextInnerLoop = nextInnerLoop->lexNext();
|
|
|
|
if (nextInnerLoop == outerLoopControlEnd) //no for loops found in outerloop
|
|
nextOuterLoop = NULL;
|
|
else //inner for loop found
|
|
{
|
|
nestnessLevel++;
|
|
nextOuterLoop = isSgForStmt(nextInnerLoop);
|
|
}
|
|
}
|
|
if (nestnessLevel == 1)
|
|
return 0;
|
|
else
|
|
return nestnessLevel;
|
|
}
|
|
|
|
static SgStatement* sinkIntoNextNearestLoop(SgStatement* pStmt, SgStatement* nextLoop)
|
|
{
|
|
__spf_print(1, "%d : SinkIntoNextNearestLoop\n", pStmt->lineNumber());
|
|
|
|
if(!isSgIfStmt(pStmt->controlParent()))
|
|
{
|
|
SgStatement *extr = pStmt->extractStmt();
|
|
nextLoop->insertStmtAfter(*extr, *nextLoop);
|
|
}
|
|
|
|
return pStmt;
|
|
}
|
|
|
|
static SgStatement* sinkIntoPreviousNearestLoop(SgStatement* pStmt, SgStatement* prevLoop, SgStatement* afterStmt)
|
|
{
|
|
__spf_print(1, "%d : sinkIntoPreviousNearestLoop\n", pStmt->lineNumber());
|
|
|
|
if(!isSgIfStmt(pStmt->controlParent()))
|
|
{
|
|
SgStatement *extr = pStmt->extractStmt();
|
|
afterStmt->insertStmtAfter(*extr, *prevLoop);
|
|
}
|
|
|
|
return pStmt;
|
|
}
|
|
|
|
static void tightenSingleLevel(SgForStmt* outerLoop, SgForStmt* topLevelForLoop)
|
|
{
|
|
SgForStmt* innerLoop = lexNextLoop(outerLoop->lexNext(), NULL);
|
|
{
|
|
//move statements after given loop before the inner loop
|
|
|
|
//moving these statements is done in reverse order,
|
|
// because insertion is always after the inner loop header
|
|
|
|
//begin := statement before closest inner loop header
|
|
SgStatement* begin = innerLoop->lexPrev();
|
|
SgStatement* end = outerLoop;
|
|
SgStatement* stmt = begin;
|
|
SgStatement* next;
|
|
while (stmt != end)
|
|
{
|
|
next = stmt->lexPrev();
|
|
sinkIntoNextNearestLoop(stmt, innerLoop);
|
|
stmt = next;
|
|
}
|
|
}
|
|
|
|
{
|
|
SgStatement* begin = outerLoop->lastNodeOfStmt()->lexPrev();
|
|
SgStatement* end = innerLoop->lastNodeOfStmt();
|
|
SgStatement* afterStmt = end->lexPrev();
|
|
SgStatement* stmt = begin;
|
|
SgStatement* next;
|
|
while (stmt != end)
|
|
{
|
|
next = stmt->lexPrev();
|
|
sinkIntoPreviousNearestLoop(stmt, innerLoop, afterStmt);
|
|
stmt = next;
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool tighten(SgForStmt* pForLoop, int level)
|
|
{
|
|
if (level > canTighten(pForLoop))
|
|
//cannot do that
|
|
return false;
|
|
|
|
int processing = 2;
|
|
SgForStmt* processedLoop = pForLoop;
|
|
|
|
while (processing <= level)
|
|
{
|
|
tightenSingleLevel(processedLoop, pForLoop);
|
|
processedLoop = lexNextLoop(processedLoop->lexNext(), NULL);
|
|
processing++;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool createNestedLoops(LoopGraph *current, const map<LoopGraph*, void*> &depInfoForLoopGraphV,
|
|
const map<string, FuncInfo*>& mapFuncInfo, vector<Messages> &messages)
|
|
{
|
|
map<LoopGraph*, depGraph*> depInfoForLoopGraph;
|
|
for (auto& elem : depInfoForLoopGraphV)
|
|
depInfoForLoopGraph[elem.first] = (depGraph*)elem.second;
|
|
|
|
bool wasTightened = false;
|
|
// has non nested child loop
|
|
__spf_print(1, " createNestedLoops for loop at %d. Start\n", current->lineNum);
|
|
bool outerTightened = false;
|
|
bool loopCondition = current->children.size() == 1 && current->perfectLoop == 1 && !current->hasLimitsToParallel();
|
|
|
|
if (loopCondition)
|
|
{
|
|
pair<SgForStmt*, depGraph*> outerLoopDependencies = getDepGraph(current, depInfoForLoopGraph);
|
|
pair<SgForStmt*, depGraph*> innerLoopDependencies = getDepGraph(current->children.at(0), depInfoForLoopGraph);
|
|
|
|
if (outerLoopDependencies.first && outerLoopDependencies.second && innerLoopDependencies.first && innerLoopDependencies.second)
|
|
{
|
|
SgForStmt *outerLoop = outerLoopDependencies.first;
|
|
map<SgSymbol*, ddnature> depMap = buildTransformerDependencyMap(outerLoop, outerLoopDependencies.second, innerLoopDependencies.first, innerLoopDependencies.second);
|
|
if (canTighten(outerLoop, depMap, mapFuncInfo) >= 2)
|
|
{
|
|
outerTightened = tighten(outerLoop, 2);
|
|
LoopGraph *firstChild = current->children.at(0);
|
|
|
|
if (outerTightened)
|
|
firstChild->perfectLoop = countPerfectLoopNest(firstChild->loop);
|
|
|
|
__spf_print(1, " createNestedLoops for loop at %d. Tighten success: %d\n", current->lineNum, outerTightened);
|
|
|
|
wchar_t buf[256];
|
|
std::wstring messageE, messageR;
|
|
__spf_printToLongBuf(messageE, L"Loops on lines %d and %d were combined", current->lineNum, firstChild->lineNum);
|
|
__spf_printToLongBuf(messageR, R100, current->lineNum, firstChild->lineNum);
|
|
|
|
messages.push_back(Messages(NOTE, current->lineNum, messageR, messageE, 2005));
|
|
}
|
|
}
|
|
}
|
|
|
|
wasTightened = outerTightened;
|
|
for (int i = 0; i < current->children.size(); ++i)
|
|
{
|
|
__spf_print(1, " createNestedLoops for loop at %d. Transform child %d\n", current->lineNum, i);
|
|
bool result = createNestedLoops(current->children[i], depInfoForLoopGraphV, mapFuncInfo, messages);
|
|
wasTightened = wasTightened || result;
|
|
}
|
|
|
|
//update perfect loop
|
|
current->recalculatePerfect();
|
|
__spf_print(1, " createNestedLoops for loop at %d. End\n", current->lineNum);
|
|
|
|
return wasTightened;
|
|
} |