@(#)r3fisrs.htm 1.1 - 03/12/01
1.3 Definitions, Acronyms and Abbreviations
2.5 Assumptions and Dependencies
3.1.0 General Instrumentation Requirements
3.1.1 Instrument Subprogram Entry Points
3.1.2 Instrument Subprogram Return Points
3.1.5 Processing of INCLUDE Directives
3.1.6 Processing of Unrecognized Statements
3.2 External Interface Requirements
Appendixes
1.0 Introduction
1.1 Purpose
This SRS states the requirements for the Recon Instrumentor for Fortran. It is intended as a guide for developers, testers, and maintainers of this software component.
The Recon Instrumentor for Fortran will first be developed in an initial version, and then progressively enhanced. Requirements in this SRS are annotated with v1.0 if they are expected to be provided in the initial version or vX.X if they are tentative requirements for inclusion in later versions. (Assume v1.0 for requirements that are not annotated.) These tentative requirements are described here since developers may wish to design their code to facilitate the probable enhancements.
The Recon Instrumentor for Fortran,
r3finst, is part of the Recon3 tool set for
dynamic analysis of software [AR3] which is, in turn, a
major upgrade and extension of the Recon2 software
reconnaissance tool [Recon2].
Each time it is called, r3finst reads one
of the Fortran 77 source files making up the user's
target program, and writes an instrumented copy of
that source file. This instrumented target program file
contains instrumentation statements so that, when
compiled and executed, the instrumented target program will
produce traces of execution.
The main benefit of r3finst is to
facilitate the understanding or debugging of Fortran
programs using techniques such as software reconnaissance
[SR95].
Major differences between the initial version of
r3finst and later versions are as
follows:
r3finst will
focus on target source files that follow the Fortran 77
standard. Statement types or formats that occur only in
certain Fortran 77 implementations, in Fortran 90 or in
Fortran 95, will be handled at developer discretion if they
can be easily included (v1.0). Later versions of
r3finst may extend to Fortran 90 or Fortran
95 (vX.X).r3finst, the
instrumentation statements will call
subprograms in the file r3fisubs.c. An initial
version of r3fisubs.c is described in Appendix A.
These subprograms will write the trace of execution
directly to a file named unknown.r2t. (This is
the default behavior of Recon2). This file will have the
trace file format expected by the r2analyz
component of Recon2. (See [Recon2, file
userman.htm] for a description of this
format.) Later versions will call the more sophisticated C
trace interface being developed for Recon3 [AR3] or
possibly will use a native Fortran interface providing
similar capabilities (vX.X).[Note: Fortran 77 is generally a subset of
Fortran 90 and Fortran 95, though with some exceptions. In
anticipation of future enhancement of
r3finst, this SRS has been written working
from the Fortran 90 and 95 standards. However it excludes Fortran 90/95
constructs which are not in Fortran 77 and which would
complicate the v.10 implementation. Main references have
been [For95] and [For90], to which the reader is referred for more
precise language explanations.]
|
Basic Block, Decision, Subprogram Entry and Return |
See [AR3 section 2.2.1] for definitions of these different kinds of trace event. |
|
Instrumentation Statements, Instrumented Target Program, Target Program, Trace Event, Trace of Execution, Trace Record |
See [AR3 section 1.3] |
|
Developer |
The individual or organization that is implementing
|
|
Program Unit |
a Fortran program unit is either: a main program, an external subprogram, or a block data unit. See [For95, Section 1]. |
|
Subprogram |
A Fortran SUBROUTINE or FUNCTION. |
|
[AR3] |
"Architecture of Recon3" Norman Wilde, Laura White, Aaron Tarnosky (Version is TBD. This document should be finalized before Aug. 31/99) |
|
[For90] |
"Fortran 90: A Reference Guide", Luc Chamberland, Prentice Hall, 1995. |
|
[For95] |
"Fortran 95 Language Guide", Wilhelm Gehrke, Springer, 1996. |
|
[Recon2] |
Code and documents for the Recon2 system available at http://www.cs.uwf.edu/~wilde/recon. |
|
[SR95] |
"Software Reconnaissance: Mapping Program Features to Code", N. Wilde and M. Scully, Journal of Software Maintenance, Vol. 7, pp. 49-62, (1995). |
This SRS follows roughly the ANSI/830 standard. Section
2 gives an overview of r3finst and its functional and
other requirements. Section 3 gives the requirements more
specifically. Appendix A describes briefly the Fortran subroutines that
will be called by the instrumentation statements
and Appendix B gives examples of instrumentation.
Terms defined in section 1.3 will appear in emphasis, like this.
Program names, file names, and Fortran language
constructs will appear in CODE format like
this.
[Brief explanations of the rationale for certain requirements are given in block quotes like this one.]
As previously mentioned in section 1.2,
r3finst is the component of the Recon3 tool set
that creates instrumented copies of Fortran source files by
inserting instrumentation statements.

Figure 1 shows how r3finst will
work with other components in the initial version (v1.0).
The user invokes r3finst using a command
line interface. Each time it is invoked,
r3finst instruments one Fortran source file.
When the user has instrumented all the Fortran files making
up his target program, he uses his Fortran compiler to
produce the instrumented target executable. He runs the
instrumented target executable using appropriate test data.
The instrumentation statements create a file named
unknown.r2t containing a trace of execution.
The user normally renames this file to something
meaningful. Several traces of execution are then fed to the
r2analyz trace analysis program.
See [AR3, section 2.1] for a block diagram showing how the different components of Recon3 will be related in later versions (vX.X).
r3finst
will introduce instrumentation
for the following trace events:
[Note: Arithmetic statement
functions are not instrumented. Since they consist
of a single statement there is no way to add
instrumentation.]
r3finst
will introduce instrumentation
for the following trace events:
[Note: The instrumentation does not distinguish different alternate returns from a subprogram. It is not clear how this kind of interprocedural control flow can most usefully be traced.]
In general, decisions are instrumented by writing
the value of the logical expression of an IF or of the
integer expression of a computed GOTO. r3finst
will introduce instrumentation for the following trace
events:
computed GOTO
statement.logical IF statement.IF-THEN construct or in the ELSE IF part of such a
construct.[Note: The loop decision taken on every iteration of a DO or DO WHILE is not instrumented. Experience using Recon2 for software reconnaissance has yet to find a functionality that was distinguishable by such a decision; both branches of the loop decision are almost always executed in every test case. Thus loop decision instrumentation adds greatly to the size of the trace of execution while providing little help for software reconnaissance. However, if experience shows that Recon3 traces are used for other purposes than software reconnaissance this decision may need to be revisited.]
[Assigned GOTO statementsandarithmetic IF statementsare not instrumented in decision instrumentation in v1.0. If the user needs to trace them, he may request basic block instrumentation, which is much more easily implemented.]
In general, instrumentation of basic blocks is done at
every statement that can be the target of a transfer of
control. r3finst will introduce
instrumentation for the following trace events:
logical IF or the executable statement
following a logical IF.[Note: For the reasons given in the previous section, the beginnings of DO and DO WHILE loops are not instrumented, unless they are also labeled.]
[Note: FORMAT and other non-executable statements, although labeled, cannot be the target of a transfer of control and so are not instrumented.]
INCLUDE directives vary in form and processing from
compiler to compiler. r3finst will attempt
to process only directives having the following, more or
less standard, form:
INCLUDE 'file-path'
r3finst
will copy the contents of the specified
file to the instrumented target program, replacing the
INCLUDE directive.
[Note: If the file path in the INCLUDE statement is relative (i.e. does not start with "/" in Unix or with the equivalent in other operating systems)r3finstwill look for the file in the directory that was the current working directory whenr3finstwas started. Some compilers look instead in the directory containing the file that has the INCLUDE statement. Users ofr3finstmay need to "cd" to that directory before running, or else they may need to modify the INCLUDE directives.]
Fortran implementations differ considerably; most
compilers provide extensions that go beyond the language
standards. A priority for r3finst is that it
should be usable for as many Fortran programs as possible.
Whenever possible it should produce an instrumented target
program that will compile and run in the same environment
as the original target program.
Thus if r3finst encounters statements
that it does not recognize, it will copy them to the
instrumented target program with as few changes as
possible. It may produce a warning message at developer
discretion.
The user is expected to be an experienced programmer.
He will be familiar particularly with how to compile
and run the target program.
2.4 General Constraints
To facilitate portability and maintenance by the
University of West Florida project team,
r3finst will be implemented using standard
only ANSI C to the greatest extent possible.
Code that depends on operating system, path lengths,
file name formats, etc. should be avoided for portability.
However is the developer really needs such things,
r3finst should include the r2.h
header file of Recon2 and make use of the preprocessor
directives it contains.
The instrumentation statements introduced by
r3finst shall consist of calls to the
FORTRAN external subprograms in the file
r3fisubs.f described in Appendix A to this
document.
None.
3.0 Specific Requirement
3.1 Functional Requirements
3.1.0 General Instrumentation Requirements
At the beginning of every Fortran program unit,
r3finst will define a variable named R3PATH to identify
the target source file being instrumented. It will also
declare the instrumentation functions R3SWIT and R3LOGI
which may be used in decision instrumentation. The
following instrumentation statements will be
inserted before any executable statement, at a location in
the program unit where type declaration statements are
valid:
CHARACTER *<pathlen> R3PATH
DATA R3PATH /'<path>'/
INTEGER R3SWIT
LOGICAL R3LOGI
where <path> is the source path string specified on the command line (see 3.2.1) and <pathlen> is the length of the path string.
[See [For95, section 1.5] for the permitted ordering of Fortran statements. This ordering determines exactly where the instrumentation may be inserted. Section 1.4 of [For95] gives a list of the executable statements of Fortran.]
Before instrumenting,
r3finst will convert all logical IF statements
to IF-THEN constructs as in the following example:
becomes:
IF ( ... ) stmt1
stmt2
IF ( ... ) THEN
stmt1
ENDIF
stmt2
Fortran's logical IF statements can only occupy one line, so it is difficult to introduce instrumentation. It is simpler to just convert them all.]
If the user has selected instrumentation of
subprogram entry points on the command line (see 3.2.1),
r3finst will introduce instrumentation for the
following trace events:
An instrumentation statement is inserted in the first basic block of the main program, of the form:
CALL R3ENTR( R3PATH, <lineno>, 'MAIN')
where <lineno> is the line number of the
first executable statement in the main program.
If a PROGRAM statement has been encountered
giving the name of the target program, then that name will
be used in the call to R3ENTR. If no such statement has
been encountered, the name 'MAIN' will be used as shown above.
An instrumentation statement is inserted in the first basic block of the subprogram, of the form:
CALL R3ENTR( R3PATH, <lineno>, '<name>')
where <lineno> is the line number of the first executable statement in the subprogram and <name> is the name of the subprogram.
An instrumentation statement is inserted just after the
ENTRY statement, of the form:
CALL R3ENTR( R3PATH, <lineno>, '<name>')
where <lineno> is the line number of the
ENTRY statement and <name> is the name
of the subprogram (not the name of the
entry).
ENTRY statements at the very beginning of a subroutine are instrumented according to (3.1.1.2). This rule applies only to ENTRY statements appearing after the first executable statement of the subroutine.
[Note: Normally subprogram entry and return events are paired; for every entry there is a corresponding return. However if non-structured ENTRY statements are present, there may appear to be more entry events than returns. For example, the following subroutine may, when instrumented and executed, generate two entry trace events and only one return:
SUBROUTINE SUB1
PRINT *, 'A'
ENTRY ENT1
PRINT *, 'B'
RETURN
END
If SUB1 is called, control "falls through" the entry point ENT1 so that both SUB1 and ENT1 will appear to be executed before the RETURN is executed.
Paired entry and return events provide a more
meaningful trace that allows the user to see the call
hierarchy of the target program. In v1.0, however,
r3finst will allow the unpaired events.
Possibly vX.X may address this problem.]
See Appendix B.1 for an example.
If the user has selected instrumentation of
subprogram return points on the command line (see 3.2.1),
r3finst will introduce instrumentation for the
following trace events:
An instrumentation statement is inserted immediately
before the STOP statement, of the form:
CALL R3RETN( R3PATH, <lineno>, 'MAIN')
where <lineno> is the line number of the
STOP statement.
Note that if the STOP statement was on a one-line
logical IF statement, of the following
form:
IF (expr) STOP
the IF is first converted into an IF-THEN construct as described in (3.1.0), and so is instrumented as follows:
IF (expr) THEN
CALL R3RETN( R3PATH, <lineno>, 'MAIN')
STOP
END IF
An instrumentation statement is inserted just before the
RETURN statement, of the form:
CALL R3RETN( R3PATH, <lineno>, '<name>')
where <lineno> is the line number of the
RETURN statement and <name> is the name
of the subprogram.
If the RETURN statement is on a one-line logical
IF statement, the IF is first converted into an
IF-THEN construct, as described in (3.1.0).
An instrumentation statement is inserted just before the
END, END PROGRAM, END FUNCTION or END SUBROUTINE
statement, of the form:
CALL R3RETN( R3PATH, <lineno>, '<name>')
where <lineno> is the line number of the
statement and <name> is the name of the
subprogram, or 'MAIN' if this is the end of the main
program.
See Appendix B.2 for an example.
If the user has selected instrumentation of
decisions on the command line (see 3.2.1), r3finst
will introduce instrumentation for the following trace
events:
computed GOTO
statement. A switch instrumentation function "wrapper" is inserted around the integer expression in the GOTO statement, of the form:
GO TO (lab1, ...) R3SWIT(R3PATH, <lineno>, integer_exp)
where <lineno> is the line number of the
GOTO statement.
logical IF statement. The logical IF is first converted into an IF-THEN construct as described in (3.1.0), and then is instrumented as described in the following section.
IF-THEN construct or in the ELSE IF part of
such a construct.A logical instrumentation function "wrapper" is inserted around the logical expression in the IF and ELSE IF statement, of the form:
IF (R3LOGI(R3PATH, <lineno>, logical_exp)) THEN
...
ELSE IF (R3LOGI(R3PATH, <lineno>, logical_exp)) THEN
...
where <lineno> is the line number of the
IF or ELSE IF statement.
See Appendix B.3 for an example.
If the user has selected instrumentation of basic
blocks on the command line (see 3.2.1), r3finst
will introduce instrumentation for the following trace
events:
Instrumentation is inserted before the labeled executable statement and the label is moved to the instrumentation. Thus a statement of the form:
nnn stmt
is instrumented as:
nnn CALL R3BLOC(R3PATH, <lineno>)
stmt
where <lineno> is the line number of the labeled statement in the original source file.
The instrumentation statement is inserted before the labeled executable statement and the label is moved to it. The DO is modified to use a new label which is also placed on the original DO statement. Thus the following code fragment:
DO nnn ...
...
nnn stmt
is instrumented as:
DO mmm ...
...
nnn CALL R3BLOC(R3PATH, <lineno>)
mmm stmt
where <lineno> is the line number of the labeled statement in the original source file and mmm is a newly generated statement label that does not occur elsewhere in the program unit.
The instrumentation is inserted between the GOTO and the executable statement. Thus a code fragment of the form:
GOTO ( ....) expr
stmt
is instrumented as:
GOTO ( ....) expr
CALL R3BLOC(R3PATH, <lineno>)
stmt
where <lineno> is the line number of the statement in the original source file.
Non-executable statements following the GOTO, such as FORMAT's, are skipped and this rule is applied to the first executable statement.
If the executable statement following the GOTO has a label, then paragraph 3.1.4.1 or 3.1.4.2 applies instead of this one.
logical IF or the statement
following a logical IF.A logical IF is converted to an IF-THEN construct as specified in (3.1.0) and is then instrumented as described in the following section.
Instrumentation is inserted before the first executable statement of each part of the IF construct. A code fragment of the form:
IF ( ... ) THEN
stmt1
ELSE IF ( ... ) THEN
stmt2
ELSE
stmt3
END IF
is instrumented as:
IF ( ... ) THEN
CALL R3BLOC(R3PATH, <lineno1>)
stmt1
ELSE IF ( ... ) THEN
CALL R3BLOC(R3PATH, <lineno2>)
stmt2
ELSE
CALL R3BLOC(R3PATH, <lineno3>)
stmt3
END IF
where <lineno1> , <lineno2> and <lineno3> are the line numbers of the stmt1, stmt2 and stmt3 respectively. The statements stmt1, stmt2 and stmt3 represent the first executable statement in the block. If any of these statements has a label, then paragraph 3.1.4.1 or 3.1.4.2 applies and the corresponding call to R3BLOC is not inserted.
See Appendix B.4 for an example.
r3finst
will attempt to process only
INCLUDE directives having the following form:
INCLUDE 'file-path'
r3finst
will copy the contents of the specified
file to the instrumented target program, replacing the
INCLUDE directive and will then instrument the resulting code.
When r3finst encounters statements that
do not match the instrumentation requirements specified in
the previous sections, it will copy them to the
instrumented target program with as few changes as
possible.
3.2 External Interface Requirements
3.2.1 Command Line
To instrument a single source file, the user invokes
r3finst using a command line of the
following form:
r3finst source dest [-bder]
[-v[level]]
where source is the path of the
Fortran source file to be instrumented, and
dest is the path for the instrumented copy of
the source file. The instrumentation flags 'b', 'd', 'e'
and 'r' may be present in any combination to indicate the
kinds of trace events to be instrumented:
b - denotes basic block instrumentation
d - denotes decision instrumentation
e - denotes subprogram entry instrumentation
r - denotes subprogram return instrumentation
If no instrumentation flags are specified, the assumed default is '-ber'.
The -v flag specifies the "verbosity level" for warning and progress messages. The different possibilities may be determined by the developer.
If the command line does not have the form given above,
a "usage" message is printed and r3finst
exits.
[Note: For consistency, the external interface ofr3finstis as similar as possible to that ofr2inst, the current C instrumentor.]
The target program source file is expected to consist of one or more Fortran program units.
r3finst
will only process target
programs that are in fixed source form as defined in
section 1.1 of [For95]. Exceptions to the guidelines stated
there are as follows:
The exact list of error conditions and messages may be determined by the developer, in accordance with the following general policy:
r3finst encounters an error that will
probably impede it from producing a valid Fortran program,
equivalent to the input program, it will write a meaningful
error message to standard output and exit.r3finst encounters an input that is
dubious, but that may not impede it from producing a
working program as described above, it may write a warning
message to standard output, depending on the verbosity
level set on the command line (see 3.2.1).r3finst
has no critical performance
requirements. However as a general guideline, the
developers should keep in mind that it is intended for use
on large Fortran programs of, at least, tens of thousands
of lines. The time required to instrument a file should
normally be not significantly greater than the compile time
for the same file in the same environment.
See section (2.4).
3.5 Attributes
None.
3.6 Other Requirements
None
Appendixes
The instrumentation subroutines currently provided for v1.0 have the following restrictions:
The subprograms to be used in v1.0 are in file
r3fisubs.f,
which includes the statements in
r3ficomm.f.
Uninstrumented file:
C ex01U.f - Example for
C "Instrument Subprogram Entry Points"
C
C Main program
REAL Y
DATA Y /10.0/
CALL ENT(Y)
CALL ENT1(Y)
END
C
C Subroutine with two entry points, ENT and ENT1
SUBROUTINE ENT(X)
REAL X, PI
DATA PI /3.14/
PRINT 1001, PI*X
RETURN
ENTRY ENT1(X)
PRINT 1001, 2*PI*X
RETURN
1001 FORMAT(' Result: ', F8.2)
END
Instrumented file:
C ex01U.f - Example for
C "Instrument Subprogram Entry Points"
C
C Main program
REAL Y
DATA Y / 10.0 /
CHARACTER * 7 R3PATH
DATA R3PATH / 'ex01u.f' /
INTEGER R3SWIT
LOGICAL R3LOGI
CALL R3ENTR ( R3PATH , 7 , 'MAIN' )
CALL ENT ( Y )
CALL ENT1 ( Y )
END
C
C Subroutine with two entry points, ENT and ENT1
SUBROUTINE ENT ( X )
REAL X , PI
DATA PI / 3.14 /
CHARACTER * 7 R3PATH
DATA R3PATH / 'ex01u.f' /
INTEGER R3SWIT
LOGICAL R3LOGI
CALL R3ENTR ( R3PATH , 15 , 'ENT' )
PRINT 1001 , PI * X
RETURN
ENTRY ENT1 ( X )
CALL R3ENTR ( R3PATH , 18 , 'ENT' )
PRINT 1001 , 2 * PI * X
RETURN
01001 FORMAT ( ' Result: ' , F8 .2 )
END
Uninstrumented file:
C ex02U.f - Example for
C "Instrument Subprogram Return Points"
C
C Main program
REAL Y
DATA Y /10.0/
C An arithmetic statement function,
C which is NOT instrumented.
SQ(Z) = Z*Z
CALL SUB(-2.0)
CALL SUB(SQ(Y))
END
C
C Subroutine
SUBROUTINE SUB(X)
REAL X, PI
DATA PI /3.14/
IF ( X .LT. 0 ) RETURN
PRINT 1001, PI*X
STOP
1001 FORMAT(' Result: ', F8.2)
END SUBROUTINE SUB
Instrumented file:
C ex02U.f - Example for
C "Instrument Subprogram Return Points"
C
C Main program
REAL Y
DATA Y / 10.0 /
C An arithmetic statement function,
C which is NOT instrumented.
CHARACTER * 7 R3PATH
DATA R3PATH / 'ex02u.f' /
INTEGER R3SWIT
LOGICAL R3LOGI
SQ ( Z ) = Z * Z
CALL SUB ( - 2.0 )
CALL SUB ( SQ ( Y ) )
CALL R3RETN ( R3PATH , 12 , 'MAIN' )
END
C
C Subroutine
SUBROUTINE SUB ( X )
REAL X , PI
DATA PI / 3.14 /
CHARACTER * 7 R3PATH
DATA R3PATH / 'ex02u.f' /
INTEGER R3SWIT
LOGICAL R3LOGI
IF ( X .LT. 0 ) THEN
CALL R3RETN ( R3PATH , 18 , 'SUB' )
RETURN
ENDIF
PRINT 1001 , PI * X
CALL R3RETN ( R3PATH , 20 , 'MAIN' )
STOP
01001 FORMAT ( ' Result: ' , F8 .2 )
CALL R3RETN ( R3PATH , 22 , 'SUB' )
ENDSUBROUTINE SUB
Uninstrumented file:
C ex03u.f - Example for
C "Instrument Decisions"
C
C Computed GOTO statement
DO 100 J=1,3
GOTO (20, 10) J
PRINT 1001, 'C'
GOTO 100
10 PRINT 1001, 'B'
GOTO 100
20 PRINT 1001, 'A'
100 CONTINUE
C GOTO on a logical IF
DO 200 J=1,3
IF (J .GT. 1) GOTO (120, 110) J - 1
PRINT 1001, 'D'
GOTO 200
110 PRINT 1001, 'F'
GOTO 200
120 PRINT 1001, 'E'
200 CONTINUE
C Logical IF
DO 300 J=1,3
IF ( J .LT. 2 ) PRINT 1001, 'G'
300 CONTINUE
C IF THEN ELSE construct
DO 400 J=1,3
IF ( J .EQ. 1 ) THEN
PRINT 1001, 'h'
ELSE IF (J .EQ. 2) THEN
PRINT 1001, 'i'
ELSE
PRINT 1001, 'j'
ENDIF
400 CONTINUE
1001 FORMAT(' Result: ', A)
END
Instrumented file:
C ex03u.f - Example for
C "Instrument Decisions"
C
C Computed GOTO statement
CHARACTER * 7 R3PATH
DATA R3PATH / 'ex03u.f' /
INTEGER R3SWIT
LOGICAL R3LOGI
DO 100 J = 1 , 3
GOTO ( 20 , 10 ) R3SWIT ( R3PATH , 7 , J )
PRINT 1001 , 'C'
GOTO 100
00010 PRINT 1001 , 'B'
GOTO 100
00020 PRINT 1001 , 'A'
00100 CONTINUE
C GOTO on a logical IF
DO 200 J = 1 , 3
IF ( R3LOGI ( R3PATH , 16 , J .GT. 1 ) ) THEN
GOTO ( 120 , 110 ) R3SWIT ( R3PATH , 16 , J - 1 )
ENDIF
PRINT 1001 , 'D'
GOTO 200
00110 PRINT 1001 , 'F'
GOTO 200
00120 PRINT 1001 , 'E'
00200 CONTINUE
C Logical IF
DO 300 J = 1 , 3
IF ( R3LOGI ( R3PATH , 25 , J .LT. 2 ) ) THEN
PRINT 1001 , 'G'
ENDIF
00300 CONTINUE
C IF THEN ELSE construct
DO 400 J = 1 , 3
IF ( R3LOGI ( R3PATH , 29 , J .EQ. 1 ) ) THEN
PRINT 1001 , 'h'
ELSEIF ( R3LOGI ( R3PATH , 31 , J .EQ. 2 ) ) THEN
PRINT 1001 , 'i'
ELSE
PRINT 1001 , 'j'
ENDIF
00400 CONTINUE
01001 FORMAT ( ' Result: ' , A )
END
Uninstrumented file:
C ex04u.f - Example for
C "Instrument Basic Blocks"
C
C Computed GOTO statement
DO 100 J=1,3
GOTO (20, 10) J
1001 FORMAT(' Result: ', A)
PRINT 1001, 'C'
GOTO 100
10 PRINT 1001, 'B'
GOTO 100
20 PRINT 1001, 'A'
100 CONTINUE
C GOTO on a logical IF
DO 200 J=1,3
IF (J .GT. 1) GOTO (120, 110) J - 1
101 PRINT 1001, 'D'
GOTO 200
110 PRINT 1001, 'F'
GOTO 200
120 PRINT 1001, 'E'
200 CONTINUE
C Logical IF
DO 300 J=1,3
IF ( J .LT. 2 ) PRINT 1001, 'G'
300 CONTINUE
C IF THEN ELSE construct
DO 400 J=1,3
IF ( J .EQ. 1 ) THEN
PRINT 1002, 'h'
ELSE IF (J .EQ. 2) THEN
1002 FORMAT(' Result: ', A)
PRINT 1002, 'i'
ELSE
PRINT 1002, 'j'
ENDIF
400 CONTINUE
END
Instrumented file:
C ex04u.f - Example for
C "Instrument Basic Blocks"
C
C Computed GOTO statement
CHARACTER * 7 R3PATH
DATA R3PATH / 'ex04u.f' /
INTEGER R3SWIT
LOGICAL R3LOGI
DO 8800 J = 1 , 3
GOTO ( 20 , 10 ) J
01001 FORMAT ( ' Result: ' , A )
CALL R3BLOC ( R3PATH , 8 )
PRINT 1001 , 'C'
GOTO 100
00010 CALL R3BLOC ( R3PATH , 10 )
PRINT 1001 , 'B'
GOTO 100
00020 CALL R3BLOC ( R3PATH , 12 )
PRINT 1001 , 'A'
00100 CALL R3BLOC ( R3PATH , 13 )
08800 CONTINUE
C GOTO on a logical IF
DO 8801 J = 1 , 3
IF ( J .GT. 1 ) THEN
CALL R3BLOC ( R3PATH , 16 )
GOTO ( 120 , 110 ) J - 1
ENDIF
00101 CALL R3BLOC ( R3PATH , 17 )
PRINT 1001 , 'D'
GOTO 200
00110 CALL R3BLOC ( R3PATH , 19 )
PRINT 1001 , 'F'
GOTO 200
00120 CALL R3BLOC ( R3PATH , 21 )
PRINT 1001 , 'E'
00200 CALL R3BLOC ( R3PATH , 22 )
08801 CONTINUE
C Logical IF
DO 8802 J = 1 , 3
IF ( J .LT. 2 ) THEN
CALL R3BLOC ( R3PATH , 25 )
PRINT 1001 , 'G'
ENDIF
00300 CALL R3BLOC ( R3PATH , 26 )
08802 CONTINUE
C IF THEN ELSE construct
DO 8803 J = 1 , 3
IF ( J .EQ. 1 ) THEN
CALL R3BLOC ( R3PATH , 30 )
PRINT 1002 , 'h'
ELSEIF ( J .EQ. 2 ) THEN
01002 FORMAT ( ' Result: ' , A )
CALL R3BLOC ( R3PATH , 33 )
PRINT 1002 , 'i'
ELSE
CALL R3BLOC ( R3PATH , 35 )
PRINT 1002 , 'j'
ENDIF
00400 CALL R3BLOC ( R3PATH , 37 )
08803 CONTINUE
END