sagexx_ug (1158317), страница 9
Текст из файла (страница 9)
note: this doesnot use any dependence analysis, so it is notvery ambitious. it is just an example ofhow to create variable, declare them, createsexpressions , create statements and functionsand install them in a program.Restructure - addStuToProgramvoid addStuffToProgram( SgProject *project, SgFile *file){SgValueExp c1(1), c2(2), c3(3), c100(100);SgExpression *pt;SgVarRefExp *e1, *e2, *e3, *e4;SgStatement *themain, *first, *firstex, *last;SgFuncHedrStmt *ptfunc;SgSymbol *ptsymb;SgSymbol *i1;SgSymbol *i2;SgSymbol *i3;SgSymbol *i4;SgSymbol *anarray;SgAssignStmt *stmt, *stmt1;SgIfStmt *anif;SgStatement *anotherif;SgWhileStmt *awhile;SgForStmt *afor;SgReturnStmt *areturn;SgCallStmt *afuncall;SgArrayType *typearray;135Chapter 9: Example ProgramsSgType basetype(T_FLOAT);printf("There is %d files in that project\n",project->numberOfFiles());// get the first statement in the file this is the GLOBAL_BFND, i.e.// the header for the file and not a real statement in the program.first = (file->firstStatement());// find the main program.themain = (file->mainProgram());if(!themain){printf("no main program here!\n");return;}// first create a new functionptfunc = new SgFuncHedrStmt("funct1");// next add some parameters.ptsymb = new SgVariableSymb("var1");pt = new SgVarRefExp(*ptsymb);ptfunc->AddArg(*pt);ptsymb = new SgVariableSymb("var2");pt = new SgVarRefExp(*ptsymb);ptfunc->AddArg(*pt);// Now insert our function after the file// header.
this is a bit hard to read.// x->instertStmtAfter(y) means put y after x.first->insertStmtAfter(*ptfunc);// lets add a statement to that function// first declare some integer variables.i1 = new SgVariableSymb("i1");i1->declareTheSymbol(*ptfunc);e1 = new SgVarRefExp(*i1);i2 = new SgVariableSymb("i2");i2->declareTheSymbol(*ptfunc);e2 = new SgVarRefExp(*i2);i3 = new SgVariableSymb("i3");i3->declareTheSymbol(*ptfunc);e3 = new SgVarRefExp(*i3);136Chapter 9: Example Programs137i4 = new SgVariableSymb("i4");i4->declareTheSymbol(*ptfunc);e4 = new SgVarRefExp(*i4);// next find the last declaration in the function.// so that we can add statements after it.firstex = (ptfunc->lastDeclaration());// make the assignment i1 = i2 + (i3 + 1)*i4stmt = new SgAssignStmt((*e1), (*e2) + ((*e3) + c1) * (*e4));// mane another assignment i2 = i3stmt1 = new SgAssignStmt(*e2,*e3);// make an if statement: if( 1.gt.2) then//stmt1//else//a copy of stmt//endifanif = new SgIfStmt(c1 > c2 , *stmt1, stmt->copy());// make another if statement that is a copy of the last.anotherif = &(anif->copy());// make a while loop: while (i4 < 2)//a copy of the if statement//endwhileawhile = new SgWhileStmt( (*e4)< c2 , anif->copy());// make a do loop:////do i1 = 1, 2, 3a copy of the while statementenddoafor = new SgForStmt(* i1, c1, c2, c3, awhile->copy());// now a return statementareturn = new SgReturnStmt();// now a subroutine call:call funct1(1,2,3)Chapter 9: Example Programsafuncall = new SgCallStmt(*ptfunc->symbol());afuncall->addArg(c1.copy());afuncall->addArg(c2.copy());afuncall->addArg(c3.copy());// let insert what we have created into the subroutine.// note these will come out in reverse order of insertion// becuase we keep inserting them after the last declaration.firstex->insertStmtAfter(*anif);firstex->insertStmtAfter(stmt->copy());firstex->insertStmtAfter(*awhile);firstex->insertStmtAfter(*afor);// to do it the other way, find the last statement.// and insert the return at the end.last = (ptfunc->lastExecutable());last->insertStmtAfter(*areturn);// now put the if and the function call in the main// program.themain->insertStmtAfter(*anotherif);themain->insertStmtAfter(*afuncall);// Let's create an array.
basetype was declared as float above.// first we create a type. in sage an array type is its base// type plus its dimensions (ranges).typearray = new SgArrayType(basetype);typearray->addRange(c1);typearray->addRange(c2);typearray->addRange(c3);// now create the array symbol of this type.anarray = new SgVariableSymb("Array1",*typearray);anarray->declareTheSymbol(*ptfunc);// make an array expression Array1(i1, i2, i3)pt =new SgArrayRefExp(*anarray,*e1,*e2,*e3);// make an assignment statement//Array1(i1, i2, i3) = i2 + (Array1(i1,i2,i3) + 1)*Array1(i1,i2,i3)stmt = new SgAssignStmt((*pt), (*e2) + ((*pt) + c1) * (*pt));// insert it into our subroutine.138Chapter 9: Example Programsfirstex->insertStmtAfter(*stmt);// unparse the filefile->unparsestdout();// and save the modified dep file.file->saveDepFile("debug.dep");}Restructure - main//This main program assumes there is a fortran file called.// x.f which has been parsed with cfp to generate a x.dep file.// also there must be a project file x.proj which// is just one line containing the name x.dep// multiple source files may be added to the project by adding// the corresponding dep file name (one to a line.)// however, sage has not been tested on multiple source// files lately and it probably will not work.int main(int argc, char **argv){// better to grab the names from argv.// but lets keep it simple.SgProject project("x.proj");SgFile file("x.f");int c;// first check to see what language the source file is.// each dep file has the language type encoded.}switch (file.languageType()) {case CSrc: // it is C or C++printf("this is a c program.
this example is for fortran \n");return -1;case ForSrc: // it is a fortran 77 or fortran 90 program.addStuffToProgram(&project, &file);// ProjectUnparse(&project);}return 0;9.2 Instrument139Chapter 9: Example Programs/*********************************************************************//*pC++/Sage++ Copyright (C) 1993*//* Indiana University University of Oregon University of Rennes*//*********************************************************************/#include <stdio.h>#include <malloc.h>#define DISTRIBUTION#include "sage++user.h"#define MAXSUBS 100struct ftable {char *function_name;SgStatement *function;} ftable;struct ftable function_table[MAXSUBS];int totalfunctions;static int event = 0;SgProject *project;Instrument - Fortran Program Transformations// Fortran program transformationsSgType *SgTypeInt();SgSymbol *entry, *eexit, *loop_entry, *loop_exit;char *fnames[] = {"entry_event","exit_event","loop_entry_event","loop_exit_event"};#define#define#define#defineENTRY_EVENTEXIT_EVENTLOOP_ENTRYLOOP_EXIT0123#define AFTER 0#define BEFORE 1Instrument - InitSymbols140Chapter 9: Example Programs141// Initialize the function symbols (used in the instrumentation)voidInitSymbols(SgProject *p){SgFile *f;}f = &(p->file(0));entry = new SgFunctionSymb(PROCEDURE_NAME,fnames[0],*SgTypeInt(),*(f->firstStatement()));eexit = new SgFunctionSymb(PROCEDURE_NAME,fnames[1],*SgTypeInt(), *(f->firstStatement()));loop_entry= new SgFunctionSymb(PROCEDURE_NAME,fnames[2],*SgTypeInt(), *(f->firstStatement()));loop_exit = new SgFunctionSymb(PROCEDURE_NAME,fnames[3],*SgTypeInt(), *(f->firstStatement()));Instrument - InitFunctionTable// Initialize the function table (used for searching for functions).voidInitFunctionTable(SgProject *project){int Files = project->numberOfFiles();int k = 0;for (int i = 0; i < project->numberOfFiles(); i++) {SgFile *f;f = &(project->file(i));int num_routines;num_routines = f->numberOfFunctions();for (int j = 0; j < num_routines; j++){SgStatement *sub;SgSymbol *subsym;#if 0sub = function_table[k].function = f->functions(j);subsym = sub->symbol();function_table[k++].function_name = subsym->identifier();printf("Function %d's name is %s\n", i*Files+j, subsym->identifier());Chapter 9: Example Programs142#endif}}}totalfunctions = k;Instrument - InsertFCallNode// Inserting a call to the instrumentation libraryvoid InsertFCallNode(int event_type, SgStatement *s, int how){SgSymbol *symb;switch (event_type) {case ENTRY_EVENT: symbbreak;case EXIT_EVENT: symbbreak;case LOOP_ENTRY: symbbreak;case LOOP_EXIT : symbbreak;}= entry;= eexit;= loop_entry;= loop_exit;SgCallStmt *c;SgValueExp *ev;c = new SgCallStmt(*symb);ev = new SgValueExp(event);c->addArg(*ev);delete(ev);event++;}switch (how) {case BEFORE:s->insertStmtBefore(*c);break;case AFTER:s->insertStmtAfter(*c);break;}Chapter 9: Example ProgramsInstrument - FixLoops// Fixing the loops in the subroutine (massaging the program)voidFixLoops(SgStatement* s){SgStatement *br;SgForStmt *f;for (br = s->lexNext(); ; br = br->lexNext()) {if (f = isSgForStmt(br))if (! f->isEnddoLoop())f->convertLoop();if (br == s->lastNodeOfStmt())break;}}Instrument - FInstrumentSub// Instrumentation running within a subroutine.voidFInstrumentSub(SgStatement* s){SgStatement *br;}for (br = s->lexNext(); ; br = br->lexNext()) {switch (br->variant()){case FOR_NODE:InsertFCallNode(LOOP_ENTRY, br, BEFORE);InsertFCallNode(LOOP_EXIT, br->lastNodeOfStmt(), AFTER);break;default:break;}if (br == s->lastNodeOfStmt())break;}Instrument - FInitialize// Basic initialization143Chapter 9: Example Programs144extern "C"voidFInitialize(SgProject *project){InitSymbols(project);InitFunctionTable(project);}Instrument - FInstrument// Instrumentation call (search for function symbol based on function name)extern "C"voidFInstrument(char *name){SgStatement *sub;for(int i=0; i < totalfunctions; i++) {if (strcmp(name, function_table[i].function_name) == 0)break;}}sub = function_table[i].function;FixLoops(sub);InsertFCallNode(ENTRY_EVENT, sub->lastDeclaration(), AFTER);InsertFCallNode(EXIT_EVENT, sub->lastExecutable(), AFTER);FInstrumentSub(function_table[i].function);Instrument - ProjectUnparseextern "C"voidProjectUnparse(SgProject *project){for (int i = 0; i < project->numberOfFiles(); i++) {SgFile *f;}}f = &(project->file(i));f->unparsestdout();Chapter 9: Example ProgramsInstrument - UnparseSubextern "C"voidUnparseSub(char *name){SgStatement *sub;for(int i=0; i < totalfunctions; i++) {if (strcmp(name, function_table[i].function_name) == 0)break;}}sub = function_table[i].function;sub->unparsestdout();Instrument - VistaInstrument// needs to be filled in (used for instrumentation for animation)voidVistaInstrument(SgStatement *s){SgStatement *br;SgExprListExp *l;SgExpression *e;SgExpression *a;for (br = s->lexNext(); ; br = br->lexNext()) {for (l = isSgExprListExp(br->expr(0)); l ; l = l->next()){e = l->value();}if (br == s->lastNodeOfStmt())break;}}Instrument - FAnalyze// Instrumenting the entire program.voidFAnalyze(SgProject *project)145Chapter 9: Example Programs{char s[32];printf ("Project has %d number of files\n", project->numberOfFiles());for (int i = 0; i < project->numberOfFiles(); i++) {SgFile *f;f = &(project->file(i));printf("Source file %s has", project->fileName(i));int num_routines;num_routines = f->numberOfFunctions();printf ("%d routines\n", num_routines);for (int j = 0; j < num_routines; j++) {SgStatement *sub;SgStatement *exe;//sub = f->functions(j);exe = sub->lastDeclaration();InsertFCallNode(ENTRY_EVENT, exe, AFTER);FixLoops(sub);FInstrumentSub(sub);}f->unparsestdout();printf ("\n Done unparsing\n");#if 0f->saveDepFile(sprintf(s,"debug%d.dep",i));#endif}for (i = 0; i < project->numberOfFiles(); i++) {SgFile *f;f = &(project->file(i));printf("Source file %s has", project->fileName(i));int num_routines;num_routines = f->numberOfFunctions();printf ("%d routines\n", num_routines);for (int j = 0; j < num_routines; j++) {SgStatement *sub;sub = f->functions(j);VistaInstrument(sub);}f->unparsestdout();printf ("\n Done unparsing\n");146Chapter 9: Example Programs147#if 0f->saveDepFile(sprintf(s,"debug%d.dep",i));#endif}}Instrument - pCxx Program Transformations// pCxx Program transformations.SgSymbol *timer_clear, *timer_start, *timer_stop, *timer_elapsed;char *cnames[] = {"Test_CMMD_node_timer_clear","Test_CMMD_node_timer_start","Test_CMMD_node_timer_stop","Test_CMMD_node_timer_elapsed"};#define#define#define#defineTIMER_CLEAR 0TIMER_START 1TIMER_STOP 2TIMER_ELAPSED3Instrument - isReferenceToMethodOfElement// Basic help routines (all obtained from the compiler)// Should be made part of the library.SgSymbol *isReferenceToMethodOfElement(SgExpression *expr){SgVarRefExp *varef;SgFunctionCallExp *fcall;SgSymbol *symb;SgMemberFuncSymb *symbm;Chapter 9: Example Programs}148SgFieldSymb *symbf;if (!expr)return NULL;if (varef = isSgVarRefExp(expr)){symb = varef->symbol();}if (fcall = isSgFunctionCallExp(expr)){symb = fcall->symbol();}if (symbm = isSgMemberFuncSymb(symb)){if (symbm->isMethodOfElement())return symbm;elsereturn NULL;}if (symbf = isSgFieldSymb(symb)){if (symbf->isMethodOfElement())return symbf;elsereturn NULL;}return 0;Instrument - isReferenceToClassOfElementSgSymbol *isReferenceToClassOfElement(SgDerivedCollectionType *type,SgExpression *expr){SgVarRefExp *varef;SgFunctionCallExp *fcall;SgSymbol *symb,*elsymb;SgMemberFuncSymb *symbm;SgFieldSymb *symbf;SgType *elmetype;SgDerivedType *eltype;if (!expr || !type)return NULL;elmetype = type->elementClass();if (!elmetype)return NULL;if (elmetype->isTheElementType())return NULL;Chapter 9: Example Programsif (eltype = isSgDerivedType(elmetype)){if (!(elsymb = eltype->typeName())){return NULL;}} elsereturn NULL;if (varef = isSgVarRefExp(expr)){symb = varef->symbol();}if (fcall = isSgFunctionCallExp(expr)){symb = fcall->symbol();}}if (symbm = isSgMemberFuncSymb(symb)){if (symbm->className() == elsymb)return symbm;elsereturn NULL;}if (symbf = isSgFieldSymb(symb)){if (symbf->structureName() == elsymb)return symbf;elsereturn NULL;}return NULL;Instrument - inMethodOfTheElementintinMethodOfTheElement(SgStatement *where){SgFuncHedrStmt *fh;SgMemberFuncSymb *symb;if (!where)return 0;149Chapter 9: Example Programsif (where->variant() == GLOBAL)return 0;}if (fh = isSgFuncHedrStmt(where)){if (symb = isSgMemberFuncSymb(fh->symbol())){return symb->isMethodOfElement();}}return inMethodOfTheElement(where->controlParent());Instrument - whichFunctionAmISgFuncHedrStmt *whichFunctionAmI(SgStatement *where){SgFuncHedrStmt *fh;SgMemberFuncSymb *symb;if (!where)return NULL;if (where->variant() == GLOBAL)return NULL;}if (fh = isSgFuncHedrStmt(where)){return fh;}return whichFunctionAmI(where->controlParent());Instrument - isReferenceToCollection//// where is used to disambiguate this//SgDerivedCollectionType *isReferenceToCollection(SgExpression *expr, SgStatement *where){150Chapter 9: Example ProgramsSgType *type = NULL;SgExpression *lhs;SgVarRefExp *varef;SgPointerType *tpt;SgReferenceType *tref;SgDerivedCollectionType *dstype;SgArrayRefExp *array;SgSymbol *symb;SgFunctionCallExp *func;if (!expr)return NULL;switch (expr->variant()){case RECORD_REF:case POINTST_OP:case DEREF_OP:lhs = expr->lhs();break;case VAR_REF:case ARRAY_REF:case FUNC_CALL:lhs = expr;break;default :// default should be to try to generate a copy for the expression151Chapter 9: Example Programs152// and see if expression becomes call the function again.return NULL;}if (!lhs)return NULL;if (varef = isSgVarRefExp(lhs)){if (varef->symbol())type = varef->symbol()->type();} elseif (isSgThisExp(lhs)){if (inMethodOfTheElement(where))return 0; // this refer to the elementtype = lhs->type();} elseif (array = isSgArrayRefExp(lhs)){symb = array->symbol();if (symb)type = symb->type();if (type)type = type->internalBaseType();} elseif (func = isSgFunctionCallExp(lhs)){symb = func->symbol();if (symb)type = symb->type();} elseif (isSgPointerDerefExp(lhs)){type = isReferenceToCollection(lhs,where);} elseif (isSgExprListExp(lhs)){type = isReferenceToCollection(lhs->lhs(),where);} elsereturn NULL;if (!type)return NULL;switch (expr->variant()){case FUNC_CALL:case ARRAY_REF:case VAR_REF:case RECORD_REF:if (dstype = isSgDerivedCollectionType(type))return dstype;if (tref = isSgReferenceType(type)){type = tref->baseType();if (dstype = isSgDerivedCollectionType(type))return dstype;}break;case DEREF_OP:Chapter 9: Example ProgramsInstrument - ListCollections// Simple routines to look into a pCxx Program.voidListCollections(SgFile *file){SgStatement *s;SgCollectionStmt *c;}for (s = file->firstStatement(); s ; s = s->lexNext()){if (c = isSgCollectionStmt(s)){c->unparsestdout();}}Instrument - ListCollectionInstancesvoidListCollectionInstances(SgFile *file){SgType *type;SgDerivedCollectionType *c;for (type = file->firstType(); type ; type = type->next()){if (c = isSgDerivedCollectionType(type)){SgStatement *s;}}}printf("%s<%s>\n",c->collectionName()->identifier(),c->elementClass()->symbol()->identifier());Instrument - ListCollectionInvocationsvoidListCollectionInvocations(SgFile *f)153Chapter 9: Example Programs{}SgStatement *br;SgExprListExp *l;SgExpression *e;SgStatement *s;SgDerivedCollectionType *a;SgSymbol *b;s = f->firstStatement();for (br = s; br; br = br->lexNext())for (l = isSgExprListExp(br->expr(0)); l ; l = l->next()){e = l->value();switch (e->variant()) {case DEREF_OP:case RECORD_REF:case POINTST_OP:a = isReferenceToCollection(e, br);b = isReferenceToMethodOfElement(e->rhs());if (a && !b)b = isReferenceToClassOfElement(a, e->rhs());if (a && b)br->unparsestdout();}}Instrument - CAnalyzevoidCAnalyze(SgProject *project){for (int i = 0; i < project->numberOfFiles(); i++) {SgFile *f;f = &(project->file(i));ListCollections(f);ListCollectionInstances(f);printf("Source file %s has ", project->fileName(i));int num_routines;}}num_routines = f->numberOfFunctions();printf ("%d routines\n", num_routines);ListCollectionInvocations(f);154Chapter 9: Example ProgramsInstrument - CInitSymbols// Initializing the timer function symbols.void CInitSymbols(SgProject *p){SgFile *f;}f = &(p->file(0));timer_clear = new SgFunctionSymb(FUNCTION_NAME,cnames[0],*SgTypeInt(),*(f->firstStatement()));timer_start = new SgFunctionSymb(FUNCTION_NAME,cnames[1],*SgTypeInt(), *(f->firstStatement()));timer_stop = new SgFunctionSymb(FUNCTION_NAME,cnames[2],*SgTypeInt(), *(f->firstStatement()));timer_elapsed = new SgFunctionSymb(FUNCTION_NAME,cnames[3],*SgTypeInt(), *(f->firstStatement()));Instrument - CInitializeextern "C"voidCInitialize(SgProject *project){CInitSymbols(project);InitFunctionTable(project);}Instrument - InsertCCallNode// Insert a C function call statementvoidInsertCCallNode(int event_type, SgStatement *s, int how){SgSymbol *symb;155Chapter 9: Example Programsswitch (event_type) {case TIMER_CLEAR: symb = timer_clear;break;case TIMER_START: symb = timer_start;break;case TIMER_STOP: symb = timer_stop;break;case TIMER_ELAPSED: symb = timer_elapsed;break;}SgFunctionCallExp *func;SgExprListExp *exp;SgCExpStmt *c;func = new SgFunctionCallExp(*symb);exp = new SgExprListExp();exp->setValue(*func);c = new SgCExpStmt (*exp);}switch (how) {case BEFORE:s->insertStmtBefore(*c);break;case AFTER:s->insertStmtAfter(*c);break;}Instrument - CTimingInstrumentSub// Instrument a pC++ function for timing collection invocations.voidCTimingInstrumentSub(SgStatement *s){SgStatement *br;SgExprListExp *l;SgExpression *e;SgDerivedCollectionType *a;SgSymbol *b;for (br = s->lastDeclaration(); ; br = br->lexNext()) {for (l = isSgExprListExp(br->expr(0)); l ; l = l->next()){e = l->value();156Chapter 9: Example Programsswitch(e->variant()){case DEREF_OP:case POINTST_OP:case RECORD_REF:a = isReferenceToCollection(e, br);b = isReferenceToMethodOfElement(e->rhs());if (a && !b)b = isReferenceToClassOfElement(a, e->rhs());if (a && isSgCExpStmt(br)) {InsertCCallNode(TIMER_START, br, BEFORE);InsertCCallNode(TIMER_STOP, br, AFTER);InsertCCallNode(TIMER_ELAPSED, br->lexNext(), AFTER);}}}if (br == s->lastNodeOfStmt())break;}}Instrument - CTimingInstrument// Instrumentation based on function name.extern "C"voidCTimingInstrument(char *name){for(int i=0; i < totalfunctions; i++) {if (strcmp(name, function_table[i].function_name) == 0)break;}}CTimingInstrumentSub(function_table[i].function);Instrument - OpenProjectextern "C"voidOpenProject(char *proj) {157Chapter 9: Example Programs}project = new SgProject (proj);Instrument - IsFortran#define TRUE 1#define FALSE 0extern "C"intIsFortran() {SgFile *file;}file = &(project->file(0));if (file->languageType() == ForSrc)return TRUE;elsereturn FALSE;Instrument - IsCextern "C"intIsC() {SgFile *file;}file = &(project->file(0));if (file->languageType() == CSrc)return TRUE;elsereturn FALSE;9.3 Expand Syntax/*********************************************************************//*pC++/Sage++ Copyright (C) 1993*//* Indiana University University of Oregon University of Rennes*//*********************************************************************/158Chapter 9: Example Programs159/******************************************************************** A Simple application of Sage++ that analyzes pCxx Programs and does** one simple source transformation to eliminate some extra communication** and expand some syntax.**** pC++ has distributed data-structures called Collections that are** homogenous and they contain classes as elements.