moved
This commit is contained in:
412
Sapfor/_src/SageAnalysisTool/loopTransform.cpp
Normal file
412
Sapfor/_src/SageAnalysisTool/loopTransform.cpp
Normal file
@@ -0,0 +1,412 @@
|
||||
#include <stdio.h>
|
||||
#include "sage++user.h"
|
||||
#include "definesValues.h"
|
||||
#include "set.h"
|
||||
#include "definitionSet.h"
|
||||
#include "inducVar.h"
|
||||
#include "depGraph.h"
|
||||
|
||||
#ifdef __SPF
|
||||
extern "C" void addToCollection(const int line, const char *file, void *pointer, int type);
|
||||
extern "C" void removeFromCollection(void *pointer);
|
||||
#endif
|
||||
|
||||
extern int countPerfectLoopNest(SgStatement*);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// some global declarations
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Loop Transformation Sets. (the validity checkings for the transformations
|
||||
// are in the depGraph method.
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// b is the outer loopm
|
||||
// permut specify the loop permutations
|
||||
// the n outermost loops must be perfectly nested
|
||||
// permut start at 0; Example
|
||||
// do i = 0
|
||||
// do j = 8
|
||||
// do k = 1
|
||||
// ....
|
||||
// permut = [2,1,0]
|
||||
// gives
|
||||
// do k = 1
|
||||
// do j = 8
|
||||
// do i = 0
|
||||
// ....
|
||||
//
|
||||
|
||||
int loopInterchange(SgStatement *b, int *permut, int n)
|
||||
{
|
||||
SgSymbol *tab_symb[MAXNESTEDLOOP];
|
||||
SgExpression *tab_bf[MAXNESTEDLOOP];
|
||||
SgExpression * tab_bi[MAXNESTEDLOOP];
|
||||
SgExpression * tab_step[MAXNESTEDLOOP];
|
||||
SgForStmt *loop, *tloop;
|
||||
int i;
|
||||
if (!(loop = isSgForStmt(b)))
|
||||
return 0;
|
||||
|
||||
if (n > countPerfectLoopNest(loop))
|
||||
{
|
||||
Message("Interchange loop error, loops are not perfectly nested", loop->lineNumber());
|
||||
return 0;
|
||||
}
|
||||
tloop = loop;
|
||||
for (i = 0; (i < n); i++)
|
||||
{
|
||||
tab_symb[i] = tloop->symbol();
|
||||
tab_bf[i] = tloop->start();
|
||||
tab_bi[i] = tloop->end();
|
||||
tab_step[i] = tloop->step();
|
||||
tloop = isSgForStmt(tloop->getNextLoop());
|
||||
}
|
||||
|
||||
tloop = loop;
|
||||
for (i = 0; (i < n); i++)
|
||||
{
|
||||
if (tab_symb[permut[i]])
|
||||
tloop->setSymbol(*tab_symb[permut[i]]);
|
||||
if (tab_bf[permut[i]])
|
||||
tloop->setStart(*tab_bf[permut[i]]);
|
||||
if (tab_bi[permut[i]])
|
||||
tloop->setEnd(*tab_bi[permut[i]]);
|
||||
if (tab_step[permut[i]])
|
||||
tloop->setStep(*tab_step[permut[i]]);
|
||||
tloop = isSgForStmt(tloop->getNextLoop());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Tile a loop.
|
||||
// assumed to be perfectly nested.
|
||||
// size is NO_STEP we do not want it to be tiled
|
||||
//
|
||||
|
||||
int tileLoops(SgStatement *func, SgStatement *b, int *size, int nb)
|
||||
{
|
||||
int i, j;
|
||||
SgSymbol *tab_symb[MAXNESTEDLOOP];
|
||||
SgStatement *body, *ptstmt;
|
||||
SgForStmt *internal_loop, *temp, *last_loop;
|
||||
SgForStmt *loop, *temloo;
|
||||
SgExpression *borne_inf[MAXNESTEDLOOP];
|
||||
SgExpression *borne_sup[MAXNESTEDLOOP];
|
||||
SgExpression *step[MAXNESTEDLOOP];
|
||||
SgType *typint;
|
||||
SgSymbol *min_fonc;
|
||||
char strfoname[256];
|
||||
|
||||
if (!(loop = isSgForStmt(b)) || !func)
|
||||
return 0;
|
||||
if (nb > countPerfectLoopNest(loop))
|
||||
{
|
||||
Message("loop Tilling error, loops are not perfectly nested", loop->lineNumber());
|
||||
return 0;
|
||||
}
|
||||
if (nb == 0) return 0;
|
||||
|
||||
if (nb >= MAXNESTEDLOOP)
|
||||
{
|
||||
Message("Too many nested level", b->lineNumber());
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < MAXNESTEDLOOP; i++)
|
||||
{
|
||||
tab_symb[i] = NULL;
|
||||
borne_inf[i] = NULL;
|
||||
borne_sup[i] = NULL;
|
||||
step[i] = NULL;
|
||||
}
|
||||
last_loop = loop;
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
if (size[i] != NO_STEP)
|
||||
{
|
||||
if (last_loop->step())
|
||||
{
|
||||
Message("Cannot tile loop, there is already a step", last_loop->lineNumber());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
last_loop = isSgForStmt(last_loop->getNextLoop());
|
||||
}
|
||||
// Get integer type;
|
||||
typint = SgTypeInt();
|
||||
// get the indexes of the loops;
|
||||
temloo = loop;
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
tab_symb[i] = temloo->symbol();
|
||||
internal_loop = temloo;
|
||||
temloo = isSgForStmt(temloo->getNextLoop());
|
||||
}
|
||||
if (!internal_loop)
|
||||
{
|
||||
Message("Internal loop not found", loop->lineNumber());
|
||||
return 0;
|
||||
}
|
||||
// generate the new symbol and declare them
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
sprintf(strfoname, "iT%d_%d", loop->id(), i);
|
||||
tab_symb[i + nb] = new SgVariableSymb(strfoname);
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, tab_symb[i + nb], 1);
|
||||
#endif
|
||||
tab_symb[i + nb]->declareTheSymbol(*func);
|
||||
}
|
||||
last_loop = loop;
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
if (size[i] != NO_STEP)
|
||||
{
|
||||
SgValueExp *tmp = (new SgValueExp(size[i] + 1));
|
||||
last_loop->setStep(*tmp);
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, tmp, 1);
|
||||
#endif
|
||||
}
|
||||
last_loop = isSgForStmt(last_loop->getNextLoop());
|
||||
}
|
||||
|
||||
// create a min function;
|
||||
min_fonc = new SgSymbol(FUNCTION_NAME, "min", *typint, *(loop->controlParent()));
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, min_fonc, 1);
|
||||
#endif
|
||||
// creation of the bound expressions;
|
||||
last_loop = loop;
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
if (size[i] != NO_STEP)
|
||||
{
|
||||
SgFunctionCallExp *cexp;
|
||||
borne_inf[i + nb] = new SgValueExp(0);
|
||||
cexp = new SgFunctionCallExp(*min_fonc);
|
||||
borne_sup[i + nb] = cexp;
|
||||
|
||||
SgValueExp *tmp = (new SgValueExp(size[i]));
|
||||
SgVarRefExp *tmp1 = (new SgVarRefExp(*tab_symb[i]));
|
||||
cexp->addArg(((last_loop->end())->copy()) - *tmp1);
|
||||
cexp->addArg(*tmp);
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, borne_inf[i + nb], 1);
|
||||
addToCollection(__LINE__, __FILE__, cexp, 1);
|
||||
addToCollection(__LINE__, __FILE__, tmp, 1);
|
||||
addToCollection(__LINE__, __FILE__, tmp1, 1);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
borne_inf[i + nb] = new SgValueExp(1);
|
||||
borne_sup[i + nb] = &((last_loop->end())->copy());
|
||||
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, borne_inf[i + nb], 1);
|
||||
#endif
|
||||
}
|
||||
step[i + nb] = NULL;
|
||||
last_loop = isSgForStmt(last_loop->getNextLoop());
|
||||
}
|
||||
// remove the loop body;
|
||||
// update the steps;
|
||||
body = internal_loop->extractStmtBody();
|
||||
// upper bound for NO_STEP loops
|
||||
last_loop = loop;
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
if (size[i] == NO_STEP)
|
||||
{
|
||||
SgValueExp *tmp = (new SgValueExp(1));
|
||||
last_loop->setEnd(*tmp);
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, tmp, 1);
|
||||
#endif
|
||||
}
|
||||
last_loop = isSgForStmt(last_loop->getNextLoop());
|
||||
}
|
||||
// create the new loop;
|
||||
last_loop = internal_loop;
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
loop = new SgForStmt(tab_symb[i + nb], borne_inf[i + nb], borne_sup[i + nb], step[i + nb], NULL);
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, loop, 1);
|
||||
#endif
|
||||
last_loop->insertStmtAfter(*loop, *last_loop);
|
||||
last_loop = loop;
|
||||
}
|
||||
|
||||
// update the loop body;
|
||||
if (!body || !last_loop)
|
||||
{
|
||||
Message("The loop may not have a body or internal error", 0);
|
||||
return 0;
|
||||
}
|
||||
last_loop->insertStmtAfter(*body, *last_loop);
|
||||
|
||||
for (j = 0; j < last_loop->numberOfChildrenList1(); j++)
|
||||
{
|
||||
ptstmt = last_loop->childList1(j);
|
||||
if (ptstmt)
|
||||
{
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
if (size[i] != NO_STEP)
|
||||
{
|
||||
SgVarRefExp *tmp = (new SgVarRefExp(*tab_symb[i]));
|
||||
SgVarRefExp *tmp1 = (new SgVarRefExp(*tab_symb[i + nb]));
|
||||
ptstmt->replaceSymbByExp(*tab_symb[i], *tmp + *tmp1);
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, tmp, 1);
|
||||
addToCollection(__LINE__, __FILE__, tmp1, 1);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
SgVarRefExp *tmp = (new SgVarRefExp(*tab_symb[i]));
|
||||
ptstmt->replaceSymbByExp(*tab_symb[i], *tmp);
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, tmp, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// distribute the loops according to the
|
||||
// table of SCC.
|
||||
// for instance consider the following loop
|
||||
//
|
||||
// do i= 1,100
|
||||
//[1] x = 2
|
||||
//[2] do j= 1,100
|
||||
// D(j+i) = A(i,j)
|
||||
// D(j+i) = A(i,j)
|
||||
// enddo
|
||||
//[3] x = 2
|
||||
// enddo
|
||||
// and the following content of the
|
||||
// [[1,3],2] scc table index
|
||||
//
|
||||
|
||||
int distributeLoopSCC(SgStatement *b, int *sccTable, int leadingdim, int numSCC)
|
||||
{
|
||||
int i, j;
|
||||
SgStatement *last, **sccloop, **sccextracted, *ptstm;
|
||||
SgStatement *previous, *cp, *copl;
|
||||
SgForStmt *loop;
|
||||
int nbstat;
|
||||
|
||||
if (!(loop = isSgForStmt(b)) || !sccTable)
|
||||
return 0;
|
||||
|
||||
nbstat = loop->numberOfChildrenList1() - 1; // does not remove the controlend;
|
||||
sccloop = new SgStatement *[numSCC];
|
||||
sccextracted = new SgStatement *[nbstat];
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, sccloop, 2);
|
||||
addToCollection(__LINE__, __FILE__, sccextracted, 2);
|
||||
#endif
|
||||
for (j = 0; j < nbstat; j++)
|
||||
{
|
||||
ptstm = loop->childList1(j);
|
||||
sccextracted[j] = ptstm;
|
||||
}
|
||||
for (j = 0; j < nbstat; j++)
|
||||
{
|
||||
if (sccextracted[j])
|
||||
sccextracted[j]->extractStmt();
|
||||
}
|
||||
// now creates the loop;
|
||||
previous = loop->nodeBefore();
|
||||
cp = loop->controlParent();
|
||||
loop->extractStmt();
|
||||
copl = &(loop->copy());
|
||||
previous->insertStmtAfter(*loop, *cp);
|
||||
sccloop[0] = loop;
|
||||
last = loop->lastNodeOfStmt();
|
||||
// need to extractloop before doing the copy;
|
||||
|
||||
for (j = 1; j < numSCC; j++)
|
||||
{
|
||||
if (j == numSCC - 1)
|
||||
sccloop[j] = copl;
|
||||
else
|
||||
sccloop[j] = &(copl->copy());
|
||||
last->insertStmtAfter(*(sccloop[j]), *cp);
|
||||
last = sccloop[j]->lastNodeOfStmt();
|
||||
}
|
||||
|
||||
for (j = 0; j < numSCC; j++)
|
||||
{
|
||||
for (i = leadingdim - 1; i >= 0; i--)
|
||||
{
|
||||
// insert in the right body the statement;
|
||||
// go revserse order; simpler;
|
||||
if (sccTable[j*leadingdim + i])
|
||||
if (sccextracted[sccTable[j*leadingdim + i] - 1])
|
||||
sccloop[j]->insertStmtAfter(*sccextracted[sccTable[j*leadingdim + i] - 1], *sccloop[j]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __SPF
|
||||
removeFromCollection(sccloop);
|
||||
removeFromCollection(sccextracted);
|
||||
#endif
|
||||
delete []sccloop;
|
||||
delete []sccextracted;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Takes two loops and fusion the bodies
|
||||
//
|
||||
|
||||
int loopFusion(SgStatement *loop1, SgStatement *loop2)
|
||||
{
|
||||
SgForStmt *doloop1;
|
||||
SgForStmt *doloop2;
|
||||
SgStatement *body, *last;
|
||||
|
||||
if (!(doloop1 = isSgForStmt(loop1)))
|
||||
return 0;
|
||||
if (!(doloop2 = isSgForStmt(loop2)))
|
||||
return 0;
|
||||
|
||||
if (!doloop1->symbol())
|
||||
return 0;
|
||||
|
||||
SgVarRefExp *tmp = (new SgVarRefExp(*doloop1->symbol()));
|
||||
doloop2->replaceSymbByExp(*doloop2->symbol(), *tmp);
|
||||
#ifdef __SPF
|
||||
addToCollection(__LINE__, __FILE__, tmp, 1);
|
||||
#endif
|
||||
body = doloop2->extractStmtBody();
|
||||
if (!body)
|
||||
return 0;
|
||||
last = doloop1->lastNodeOfStmt();
|
||||
if (!last)
|
||||
return 0;
|
||||
last = last->nodeBefore();
|
||||
if (!last)
|
||||
return 0;
|
||||
last->insertStmtAfter(*body, *doloop1);
|
||||
doloop2->extractStmt();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user