Files
SAPFOR/Sapfor/_src/SageAnalysisTool/invariant.cpp

170 lines
5.1 KiB
C++
Raw Normal View History

2023-09-14 19:43:13 +03:00
#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;
}