#include #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; }