Files
SAPFOR/Sapfor/_src/SageAnalysisTool/flowAnalysis.cpp
2025-03-12 12:37:19 +03:00

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);
}
}