![]() |
|||
|
|
This project will locate Arithmetic Ifs and Computed Gotots in a FORTRAN program and transform these into equivalent statements containing only If-Then-Elseif-Else-Endif constructs, and Goto type statments. See Rules to Transform Gotos below for hints.
mini_polaris -f sw test.f > test.listIn this example, test.f is a FORTRAN program which you want to compile.
We save the output to the file test.list which may be examined for correctness. The file sw contains your own copy of the switchfile in your work directory. (see Switches.)
list2src < test.list > test.P.fThe .P.f ending indicates the file potentially contains parallelization directives, which is not relevant for this assignment, but which is important to the purpose of the Polaris compiler.
The output FORTRAN program produced by this project should contain all the statements of the original, with the exception of the transformed Gotos (see Gotos example.) You should alsoprovide the option of printing out the current subprogram just after you have found the basic blocks, either in normal FORTRAN or a detailed listing of the abstract syntax tree.
convert_gotos 1 Convert arithmetic ifs and computed gotos to simple gotosThese values are the default as specified in the file switches in your work directory (do not remove this file since it is the default switchfile -- copy it to another file and specify that filename with the -f option when running mypolaris.)
p_congoto 2 print after convert gotos pass (1 == Fortran form, 2 == all fields)
So, if you use a different switchfile which has p_congoto set to 0, then the summary routine will not be called. If you set convert_gotos to 0, then none of the routines will be called (it doesn't make sense to print the program if you have not performed the gotos pass.)
void convert_gotos(ProgramUnit & pgm);NOTE : The original source files provided by setup neglected to make the parameter a reference type (i.e. the & was left out.) This causes the program unit to be duplicated, and any changes you make would be lost upon exiting convert_gotos().
This is a simple pass which takes one program unit as input, transforms any relevant statements inside, and completes, returning nothing.
On linux, the file cvdl/gotos/Makefile includes the lines :
CPPSRCS = gotos.cc # add your other .cc files hereIf you create other source files, you should add them to these two lines so they will be compiled and linked into the final program.
CPPHDRS = gotos.h # add your other .h files here
Iterator<Statement> stmt_it = stmt_list.stmts_of_type(ARITHMETIC_IF_STMT,
COMPUTED_GOTO_STMT);
IF (f(x)) 10,20,30then transforming it to
IF (f(x) .LT. 0) THENwill potentially cause a problem if the function f has any side-effects (e.g. parameter modified or common (global) variable modified.) The solution is to replace the expression with a precalculated value. Fortunately, Polaris provides such a function get_precalc() which is described in cvdl/base/utilities/precalc_util.h . Include "utilities/precalc_util.h" to access this file. An example of its use would be as follows :
GOTO 10
ELSEIF (f(x) .EQ. 0) THEN
GOTO 20
ELSE
GOTO 30
ENDIF
if (! stmt.expr().is_side_effect_free())This first tests to see if precalculation is necessary, and if so, it replaces the expression for stmt (type Statement &) with the precalculation variable as well as inserting an assignment to the precalculation variable just before the current statement. If the above code were applied to
{
stmt.expr(get_precalc(stmt.expr().clone(), pgm, stmt,
PRECALC_ALWAYS, "TEMP")) ;
}
IF (f(x)) 10, 20, 30it would then look like
temp = f(x)which avoids side-effects. Also, the variable temp is automatically inserted in the symbol table of the current program unit, so it will be declared. Finally, argument 5 to get_precalc() indicates the suggested name to use. If more than one expression is precalculated, the function will automatically create unique names for successive instances, always with the prefix TEMP.
IF (temp) 10, 20, 30
GotoStmt * mygoto = new GotoStmt(pgm.stmts().new_tag(),Note that simply creating this statement does not insert it into the statement list. You must do so yourself with the ins_after(), ins_before(), or related member functions of StmtList.
& somestmt);
However, the If-Then-Else-Endif construct involves multiple statements, which must have consistent references to one another. If you try to insert only an IfStmt Polaris will stop and report an inconsistency. Thus, StmtList provides some functions such as ins_IF_ELSE_after() and ins_ELSEIF_after(). You should carefully examine the description of the parameters. An example of their use is provided in StmtList_test.cc. (Note : many of the techniques used to create expressions are unnecessarily low-level, as there are macros and functions to do much of this work.)
Don't forget that once you have created all the new statements and inserted them in the proper locations that you must delete the old (single) statement.
You must remember that whenever you create a new expression from an old one, that you need to clone the old one to maintain ownership consistency. An example of creating a condition which tests if a previously defined expression is less than zero woud be as follows :
Expression * lt_id = oldexpr.clone();In this example, oldexpr is of type Expression &. Once you have created lte, you may insert it into an IF statement, for example.
Expression * lt_zero = constant(0);
BinaryExpr * lte = new BinaryExpr(LT_OP,
expr_type(LT_OP,
lt_id->type(),
lt_zero->type()),
lt_id,
lt_zero);
It is highly recommended that you implement this function one step at a time, compiling and testing your latest addition to verify that your additions are correct (see Examples.)
If you have not compiled mini_polaris yet, change to your work directory and run make
cd ~/minipolaris
make
If you make some changes and want to recompile, just type make at the gotos directory. Or, if you want to do it from the top-level makefile, you should do (suppose you are at the gotos directory)
rm libgotos_pkg.so.1
cd ~/minipolaris
make
cd ~/minipolaris/cvdl/gotos
rm *.o libgotos_pkg.so.1Then
cd ..
tar cf - gotos | gzip > project1A_UIN.tar.gz
gzcat project1A_UIN.tar.gz | tar tvf - # this will list the files for verificationYou need to log on csnet.cs.tamu.edu and turn in proj-gotos.tar.gz.
IF (expr) label1, label2, label3Example :
IF (i) 10,20,30Transformation :
IF (expr .LT. 0) THENThis is assuming that the precalculation transformation was performed before, and if necessary, expr represents the precalculation variable.
GOTO label1
ELSEIF (expr .EQ. 0) THEN
GOTO label2
ELSE
GOTO label3
ENDIF
GOTO (label1, label2, ... , labelN) exprwhere N >= 1 Example :
GOTO (10,20,30,40,50,10) iTransformation :
IF (expr .EQ. 1) THENThis is assuming that the precalculation transformation was performed before, and if necessary, expr represents the precalculation variable.
GOTO label1
ELSEIF (expr .EQ. 2) THEN
GOTO label2
ELSEIF (expr .EQ. 3) THEN
GOTO label3
.
.
.
ELSEIF (expr .EQ. N) THEN
GOTO labelN
ENDIF
Notice that unlike the Arithmetic If statement, there will be cases not covered by the Computed Goto statement, such as when expr < 1 or expr > N. There should not be any simple ELSE statements in the transformed code, since that would incorrectly handle cases which fell outside the range.
Parasol Home | Research | People | General info | Seminars | Resources Parasol Lab, 301 Harvey R. Bright Bldg, 3112 TAMU, College Station, TX 77843-3112 Contact Webmaster Phone 979.458.0722 Fax 979.458.0718
Department of Computer Science and Engineering | Dwight Look College of Engineering | Texas A&M University Privacy statement: Computer Science and Engineering Engineering TAMU |