116 D.M. Doolin et al. / JLAPACK – compiling LAPACK FORTRAN to Java
code does not attempt to call Dummy.label() (in
the JVM, a zero byte corresponds to the nop instruc-
tion – i.e., it does nothing). On the second pass, we
scan for calls to Dummy.go_to(). For each call,
we look up the target label of the goto in the hash
table to obtain the actual bytecode address of the
label. Then we may replace the Dummy.go_to()
method invocation with an actual goto instruction.
Since the method invocation instruction sequence is
longer than the goto instruction, we zero out the re-
maining bytes.
So far, this method has been successful in translat-
ing GOTO statements in the BLAS/LAPACK source
code and testing routines. There may be some cases
in which “hacking” the compiler-producedbytecode as
we have done will produce unexpected results, possi-
bly putting the JVM into an unusual state. The Java
compiler generates code under certain assumptions,
one example of which is that the program should not
branch to a statement within a loop from outside the
loop. Our GOTO translation method has the poten-
tial to violate these assumptions, although we have not
yet come across a specific instance in the BLAS or
LAPACK source.
2.1.9. The need for code restructuring
Even though we now have a way to translate any ar-
bitrary GOTO statement into Java source, there is still
another problem caused by Java’s lack of a goto state-
ment. Consider the following segment of code from
ddot.f:
if(incx.eq.1.and.incy.eq.1)
go to 20
c
[...code for unequal
increments...]
c
ddot = dtemp
return
c
c code for both increments
equal to 1
c
20 m = mod(n,5)
The first line of code checks whether both increments
are equal to 1 and if so, skips the section of code to deal
with unequal increments. We can see by looking at the
FORTRAN code (and so can the FORTRAN compiler)
that statement 20 can be reached. However, looking at
the Java source code produced by f2j, it is easy to see
why the Java compiler does not recognize that fact:
if (incx == 1 && incy == 1)
Dummy.go_to("Ddot",20);
[...code for unequal increments...]
ddot = dtemp;
return ddot;
Dummy.label("Ddot",20);
m = (n)%(5) ;
When the Java compiler analyzes this program, it
views the call to Dummy.go_to as a normal method
call. So, as far as javac is concerned, execution resumes
with the code immediately following the method call.
Since the segment of code following the method call
ends with a return statement, javac determines
that any statements following the return cannot be
reached. Normally this would be a perfectly reason-
able determination, but in this case we know that the
call to Dummy.go_to will really cause the program
to branch to statement 20.
Currently, there are a few ways to handle this. We
could manually change the FORTRAN source code
such that the IF expressionis reversed and put the equal
increments code ahead of the unequal increments code.
There are code restructuring tools that can recognize
and restructure these constructs automatically, remov-
ing the GOTO in the process. We could restructure the
Java source code after translation (not a great idea). Fu-
ture versions of f2j may have some code restructuring
ability built in, so that they can generate correct Java
source code without the need for manual restructuring
or external tools. Our current approach is to generate
one “real” return statement at the end of the function
or subroutine, with a unique label. All other return
statements are translated into dummy gotos, with the
target being the “real” return. Using this approach,
the java compiler views all return statements as func-
tion calls, so it no longer thinks that subsequent state-
ments cannot be reached. This approach is much sim-
pler and less error-prone than code restructuring.
2.1.10. DATA statements
FORTRAN DATA statements are generated as vari-
able declarations combined with initializations. They
must be combined since all variables are now gener-
ated as static class variables and therefore cannot have
separate assignment statements mixed in. For example,
the following DATA statement:
integer z(4)
DATA z/1,2,3,4/