281 lines
7.9 KiB
C++
281 lines
7.9 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "sage++user.h"
|
|
#include "definesValues.h"
|
|
#include "set.h"
|
|
|
|
#ifdef __SPF
|
|
extern "C" void addToCollection(const int line, const char *file, void *pointer, int type);
|
|
extern "C" void removeFromCollection(void *pointer);
|
|
#endif
|
|
|
|
//
|
|
// Control FLOW part of declaration
|
|
//
|
|
|
|
extern void controlFlow(SgStatement *stmt, SgStatement *func,
|
|
SgStatement **pred, SgStatement **suc,
|
|
int *predin, int *sucint);
|
|
|
|
Set *genSet[MAXNODE];
|
|
Set *killSet[MAXNODE];
|
|
Set *inSet[MAXNODE];
|
|
Set *outSet[MAXNODE];
|
|
|
|
//
|
|
// Main function for data flow analysis, take some functions as a parameter
|
|
//
|
|
|
|
|
|
void iterativeForwardFlowAnalysis(SgFile *file,
|
|
SgStatement *func,
|
|
Set *(*giveGenSet)(SgStatement *func, SgStatement *stmt),
|
|
Set *(*giveKillSet)(SgStatement *func, SgStatement *stmt),
|
|
int(*feq)(void *e1, void *e2),
|
|
void *(*fcomb)(void *e1, void *e2),
|
|
void(*fp)(void *e1))
|
|
{
|
|
SgStatement *last, *first, *lastfunc, *temp;
|
|
SgStatement *pred[MAXP], *suc[MAXP];
|
|
int nbpred, nbsuc;
|
|
int size, i, j;
|
|
Set *tps, *oldout, *tpt, *pt1, *pt2, *comb;
|
|
int change, step;
|
|
int cid;
|
|
if (!file || !func || !giveGenSet || !giveKillSet)
|
|
{
|
|
Message("iterativeForwardFlowAnalysis: Some Argument are NULL", 0);
|
|
return;
|
|
}
|
|
lastfunc = func->lastNodeOfStmt();
|
|
// should use the max id instead;
|
|
for (i = 0; i < MAXNODE; i++)
|
|
{
|
|
genSet[i] = NULL;
|
|
killSet[i] = NULL;
|
|
outSet[i] = NULL;
|
|
inSet[i] = NULL;
|
|
}
|
|
// initialize the gen and kill set;
|
|
for (temp = func; temp; temp = temp->lexNext())
|
|
{
|
|
if (temp->id() > MAXNODE)
|
|
{
|
|
Message("Too many nodes in program: Fatal", 0);
|
|
exit(1);
|
|
}
|
|
genSet[temp->id()] = (*giveGenSet)(func, temp);
|
|
killSet[temp->id()] = (*giveKillSet)(func, temp);
|
|
if (temp == lastfunc)
|
|
break;
|
|
}
|
|
// initialize the out set;
|
|
for (temp = func; temp; temp = temp->lexNext())
|
|
{
|
|
if (genSet[temp->id()])
|
|
{
|
|
pt2 = genSet[temp->id()];
|
|
outSet[temp->id()] = pt2->copy();
|
|
}
|
|
else
|
|
outSet[temp->id()] = NULL;
|
|
inSet[temp->id()] = NULL;
|
|
if (temp == lastfunc)
|
|
break;
|
|
}
|
|
change = 1;
|
|
step = 0;
|
|
while (change)
|
|
{
|
|
step++;
|
|
change = 0;
|
|
for (temp = func; temp; temp = temp->lexNext())
|
|
{
|
|
cid = temp->id();
|
|
controlFlow(temp, func, pred, suc, &nbpred, &nbsuc);
|
|
if (inSet[cid])
|
|
{
|
|
#ifdef __SPF
|
|
removeFromCollection(inSet[cid]);
|
|
#endif
|
|
delete inSet[cid];
|
|
}
|
|
tps = new Set(feq, fcomb, fp);
|
|
#ifdef __SPF
|
|
addToCollection(__LINE__, __FILE__, tps, 1);
|
|
#endif
|
|
for (i = 0; i < nbpred; i++)
|
|
{
|
|
tps->unionSet(outSet[pred[i]->id()]);
|
|
}
|
|
|
|
inSet[cid] = tps;
|
|
|
|
oldout = outSet[cid];
|
|
outSet[cid] = new Set(feq, fcomb, fp);
|
|
tpt = new Set(feq, fcomb, fp);
|
|
#ifdef __SPF
|
|
addToCollection(__LINE__, __FILE__, outSet[cid], 1);
|
|
addToCollection(__LINE__, __FILE__, tpt, 1);
|
|
#endif
|
|
tpt->diffSet(inSet[cid], killSet[cid]);
|
|
|
|
outSet[cid]->unionSet(genSet[cid]);
|
|
outSet[cid]->unionSet(tpt);
|
|
pt1 = outSet[cid];
|
|
outSet[cid] = pt1->compact();
|
|
#ifdef __SPF
|
|
removeFromCollection(pt1);
|
|
#endif
|
|
delete pt1;
|
|
if (!oldout && outSet[cid])
|
|
change = 1;
|
|
else
|
|
if (!oldout->equalSet(outSet[cid]))
|
|
change = 1;
|
|
if (oldout)
|
|
{
|
|
#ifdef __SPF
|
|
removeFromCollection(oldout);
|
|
#endif
|
|
delete oldout;
|
|
}
|
|
if (tpt)
|
|
{
|
|
#ifdef __SPF
|
|
removeFromCollection(tpt);
|
|
#endif
|
|
delete tpt;
|
|
}
|
|
|
|
if (temp == lastfunc)
|
|
break;
|
|
}
|
|
if (step > MAXITDATAFLOW)
|
|
{
|
|
Message("data flow analysis not converging", 0);
|
|
return;
|
|
}
|
|
printf("Data flow analysis at step %d\n", step);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Iterative Algorithme for General Frameworks page 690 Aho Ullman
|
|
// out is initialise to transfertSet(NULL). in is initialized to NULL (this is T).
|
|
// combineSet() is the meet operator (take as input the union or output...)
|
|
//
|
|
|
|
void generalIterativeFlowAnalysis(SgFile *file,
|
|
SgStatement *func,
|
|
Set *(*transfertSet)(SgStatement *func, SgStatement *stmt, Set *setin),
|
|
int(*feq)(void *e1, void *e2),
|
|
void* (*fcomb)(void *e1, void *e2),
|
|
void(*fp)(void *e1))
|
|
{
|
|
SgStatement *last, *first, *lastfunc, *temp;
|
|
SgStatement *pred[MAXP], *suc[MAXP];
|
|
int nbpred, nbsuc;
|
|
int size, i, j;
|
|
Set *tps, *oldout, *tpt, *pt1, *pt2, *comb;
|
|
int change, step;
|
|
int cid;
|
|
if (!file || !func || !transfertSet)
|
|
{
|
|
Message("generalIterativeFlowAnalysis: Some Arguments are NULL", 0);
|
|
return;
|
|
}
|
|
lastfunc = func->lastNodeOfStmt();
|
|
// should use the max id instead;
|
|
for (i = 0; i < MAXNODE; i++)
|
|
{
|
|
genSet[i] = NULL;
|
|
killSet[i] = NULL;
|
|
outSet[i] = NULL;
|
|
inSet[i] = NULL;
|
|
}
|
|
// initialize the out Set
|
|
for (temp = func; temp; temp = temp->lexNext())
|
|
{
|
|
if (temp->id() > MAXNODE)
|
|
{
|
|
Message("Too many nodes in program: Fatal", 0);
|
|
exit(1);
|
|
}
|
|
outSet[temp->id()] = (*transfertSet)(func, temp, NULL);
|
|
if (temp == lastfunc)
|
|
break;
|
|
}
|
|
change = 1;
|
|
step = 0;
|
|
while (change)
|
|
{
|
|
step++;
|
|
change = 0;
|
|
for (temp = func; temp; temp = temp->lexNext())
|
|
{
|
|
cid = temp->id();
|
|
controlFlow(temp, func, pred, suc, &nbpred, &nbsuc);
|
|
if (inSet[cid])
|
|
{
|
|
#ifdef __SPF
|
|
removeFromCollection(inSet[cid]);
|
|
#endif
|
|
delete inSet[cid];
|
|
}
|
|
tps = new Set(feq, fcomb, fp);
|
|
#ifdef __SPF
|
|
addToCollection(__LINE__, __FILE__, tps, 1);
|
|
#endif
|
|
for (i = 0; i < nbpred; i++)
|
|
{
|
|
tps->unionSet(outSet[pred[i]->id()]);
|
|
}
|
|
tpt = tps;
|
|
tps = tps->combineSet();
|
|
inSet[cid] = tps;
|
|
if (tpt)
|
|
{
|
|
#ifdef __SPF
|
|
removeFromCollection(tpt);
|
|
#endif
|
|
delete tpt;
|
|
}
|
|
|
|
oldout = outSet[cid];
|
|
outSet[cid] = (*transfertSet)(func, temp, inSet[cid]);
|
|
if (!oldout && outSet[cid])
|
|
{
|
|
change = 1;
|
|
// printf ("old out is NULL (line %d)\n", temp->lineNumber());
|
|
}
|
|
else
|
|
if (!oldout->equalSet(outSet[cid]))
|
|
{
|
|
// printf ("-------debug ouput (line %d)-----------: \n", temp->lineNumber());
|
|
// printf ("oldout: \n");
|
|
// oldout->printSet();
|
|
// printf ("out: \n");
|
|
// if (outSet[cid])
|
|
// outSet[cid]->printSet();
|
|
change = 1;
|
|
}
|
|
if (oldout)
|
|
{
|
|
#ifdef __SPF
|
|
removeFromCollection(oldout);
|
|
#endif
|
|
delete oldout;
|
|
}
|
|
if (temp == lastfunc)
|
|
break;
|
|
}
|
|
if (step > MAXITDATAFLOW)
|
|
{
|
|
Message("data flow analysis not converging", 0);
|
|
return;
|
|
}
|
|
printf("Data flow analysis at step %d\n", step);
|
|
}
|
|
}
|