170 lines
5.1 KiB
C++
170 lines
5.1 KiB
C++
|
|
#include <stdio.h>
|
||
|
|
#include "sage++user.h"
|
||
|
|
#include "definesValues.h"
|
||
|
|
#include "set.h"
|
||
|
|
#include "definitionSet.h"
|
||
|
|
|
||
|
|
#ifdef __SPF
|
||
|
|
extern "C" void addToCollection(const int line, const char *file, void *pointer, int type);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
extern Set *genSet[MAXNODE];
|
||
|
|
extern Set *killSet[MAXNODE];
|
||
|
|
extern Set *inSet[MAXNODE];
|
||
|
|
extern Set *outSet[MAXNODE];
|
||
|
|
|
||
|
|
//
|
||
|
|
// used in compute loop invariant
|
||
|
|
//
|
||
|
|
|
||
|
|
int stmtEqual(void *e1, void *e2)
|
||
|
|
{
|
||
|
|
SgStatement *ex1, *ex2;
|
||
|
|
if (!e1 && !e2)
|
||
|
|
return 1;
|
||
|
|
if (!e1 || !e2)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
ex1 = (SgStatement *)e1;
|
||
|
|
ex2 = (SgStatement *)e2;
|
||
|
|
|
||
|
|
if (ex1 != ex2)
|
||
|
|
return 0;
|
||
|
|
else
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
void stmtPrint(void *e1)
|
||
|
|
{
|
||
|
|
SgStatement *ex1;
|
||
|
|
if (!e1)
|
||
|
|
return;
|
||
|
|
|
||
|
|
ex1 = (SgStatement *)e1;
|
||
|
|
printf("statement at line %d:\n", ex1->lineNumber());
|
||
|
|
ex1->unparsestdout();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
void exprPrint(void *e1)
|
||
|
|
{
|
||
|
|
SgExpression *ex1;
|
||
|
|
if (!e1)
|
||
|
|
return;
|
||
|
|
ex1 = (SgExpression *)e1;
|
||
|
|
ex1->unparsestdout();
|
||
|
|
printf("\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
//
|
||
|
|
//function to Compute Loop Invariant Computation
|
||
|
|
// assume Reaching definition has been done
|
||
|
|
// and also the used and defined for each statment has also been computed
|
||
|
|
//
|
||
|
|
|
||
|
|
Set *loopInvariantStmt(SgStatement *func, SgStatement *stmt)
|
||
|
|
{
|
||
|
|
SgStatement *last, *first, *defreach, *temp, *cp;
|
||
|
|
SgForStmt *loop;
|
||
|
|
Set *invariant, *reachdef;
|
||
|
|
SgExpression *use, *pt, *usevar, *expr;
|
||
|
|
int change, id, inloop, inv, step;
|
||
|
|
PT_ELSET el;
|
||
|
|
int i;
|
||
|
|
if (!stmt || !func)
|
||
|
|
return NULL;
|
||
|
|
|
||
|
|
if (!(loop = isSgForStmt(stmt)))
|
||
|
|
return NULL;
|
||
|
|
|
||
|
|
last = stmt->lastNodeOfStmt();
|
||
|
|
invariant = new Set(stmtEqual, NULL, stmtPrint);
|
||
|
|
#ifdef __SPF
|
||
|
|
addToCollection(__LINE__, __FILE__, invariant, 1);
|
||
|
|
#endif
|
||
|
|
change = 1;
|
||
|
|
step = 0;
|
||
|
|
while (change)
|
||
|
|
{
|
||
|
|
change = 0;
|
||
|
|
step++;
|
||
|
|
for (temp = stmt->lexNext(); temp; temp = temp->lexNext())
|
||
|
|
{
|
||
|
|
// only if assgn_stat...;
|
||
|
|
if (!isSgAssignStmt(temp))
|
||
|
|
{
|
||
|
|
if (temp == last)
|
||
|
|
break;
|
||
|
|
else
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
id = temp->id();
|
||
|
|
use = (SgExpression *)temp->attributeValue(0, USEDLIST_ATTRIBUTE);
|
||
|
|
//Used[id];
|
||
|
|
reachdef = inSet[id];
|
||
|
|
// look at all the use of ;
|
||
|
|
inv = 1;
|
||
|
|
for (pt = use; pt && (inv == 1); pt = pt->rhs())
|
||
|
|
{
|
||
|
|
usevar = pt->lhs();
|
||
|
|
if (usevar)
|
||
|
|
{// look at if the definition is the reaching set;
|
||
|
|
for (i = 0; i < reachdef->size(); i++)
|
||
|
|
{
|
||
|
|
el = (PT_ELSET)reachdef->getElement(i);
|
||
|
|
if (el)
|
||
|
|
{
|
||
|
|
defreach = el->stmt;
|
||
|
|
expr = el->expr;
|
||
|
|
if (expr)
|
||
|
|
{
|
||
|
|
if (expr->symbol() && usevar->symbol() &&
|
||
|
|
(expr->symbol() == usevar->symbol()))
|
||
|
|
{
|
||
|
|
// we have a definition of the variable;
|
||
|
|
if (!invariant->isInSet((void *)defreach))
|
||
|
|
{
|
||
|
|
// look at if in the loop body;
|
||
|
|
inloop = 0;
|
||
|
|
cp = defreach;
|
||
|
|
while (cp)
|
||
|
|
{
|
||
|
|
if (cp == stmt)
|
||
|
|
{
|
||
|
|
inloop = 1;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if ((cp->variant() == GLOBAL) || (cp == func))
|
||
|
|
{
|
||
|
|
inloop = 0;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
cp = cp->controlParent();
|
||
|
|
}
|
||
|
|
if (inloop)
|
||
|
|
{
|
||
|
|
inv = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (inv && !invariant->isInSet((void *)temp) && (step < MAXITDATAFLOW))
|
||
|
|
{
|
||
|
|
invariant->addElement((void *)temp);
|
||
|
|
change = 1;
|
||
|
|
}
|
||
|
|
if (step >= MAXITDATAFLOW)
|
||
|
|
Message("invariant computation is Looping", 0);
|
||
|
|
if (temp == last)
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return invariant;
|
||
|
|
}
|
||
|
|
|