Revised November, 1996 for Release 4.0.
All rights reserved. No part of this publication may be reproduced, stored in a retrieval system,
or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or
otherwise, without the express written permission of Apogee Software, Inc.
Information in this document is subject to change without notice and does not represent a
commitment on the part of Apogee Software, Inc.
The software described in this document is furnished under a license and may be used or copied
only in accordance with the terms of such license.
Apogee-C, Apogee-C++, Apogee-FORTRAN 77, Apogee-Fortran 90 and the Apogee logo
{ } are trademarks of Apogee Software, Inc.
KAP is a trademark of Kuck and Associates, Inc.
VAST is a registered trademark of Pacific-Sierra Research Corporation.
UNIX is a registered trademark and is exclusively licensed by X/Open Company, Ltd.
SPARC is a registered trademark of SPARC International, Inc. All SPARC trademarks, including
microSPARC, SuperSPARC, hyperSPARC, and UltraSPARC are trademarks or registered
trademarks of SPARC International, Inc.
SunOS, Solaris and SunSoft are trademarks or registered trademarks of Sun Microsystems, Inc.
PowerPC is a trademark of International Business Machines Corporation.
VAX and VMS are trademarks of Digital Equipment Corporation.
Cray is a registered trademark of Cray Research, Inc., and/or Silicon Graphics, Inc.
FLEXlm is a trademark of Globetrotter Software. Portions of the FLEXlm Manual are used with
permission of Globetrotter Software.
All other names are trademarks of their respective holders.
Throughout this manual, trademarked names are used without placing a trademark symbol at
every occurrence. All such names are used in an editorial fashion only, with no intention of
trademark infringement. Inquires concerning trademarks or trademarked products should be
directed to the companies involved.
Page 3
Table of Contents
Table of Contents
Table of Contents...............................................................................................3
Throughout this manual, C and C++ are collectively referred to as C/C++, while FORTRAN 77
and Fortran 90 are collectively referred to as FORTRAN 77/90, or simply as FORTRAN. Cases
specific to each language are noted by reference to the specific language. The addition of
"Apogee-" to any of the above languages denotes the appropriate Apogee Compiler. Most of
the information provided in this manual applies to the Apogee-C, Apogee-C++, ApogeeFORTRAN and Apogee-Fortran 90 compilers. When a specific point applies to any subgroup
of these compilers, that fact is noted.
This manual provides information on how to use the Apogee-C, Apogee-C++, ApogeeFORTRAN 77 and Apogee-FORTRAN 90 Optimizing Compilers running under the UNIX
operating system. Information that is provided in this manual includes:
•How to compile, assemble, and link programs.
•How to control the behavior of the compilers during compilation.
•Which kinds of optimizations are performed by the compilers.
•How the C, C++ and FORTRAN 77/90 languages accepted by the compilers compare
with several industry-standard definitions of C/C++ and FORTRAN 77/90.
•Which programming restrictions apply when the Apogee compilers are used, and how
to deal with programs that violate these restrictions.
Information that is not provided in this manual includes:
•How to write C/C++ and FORTRAN 77/90 programs in general. (For that purpose a
C, C++, FORTRAN 77 or Fortran 90 language reference manual should be consulted.)
Apogee User’s Manual Page 9
Page 10
Apogee Software, Inc.
•How to use the various aspects of UNIX indirectly associated with compiling and
executing programs, such as:
1)preparing program files to be input to the compilers,
2)using the make program,
3)using the debugger,
4)using the profiling facility, or
5)manipulating files output from program execution.
For any of these topics, a suitable UNIX manual should be consulted.
Specifically, the chapters of this manual are organized as follows:
Chapter 1:Introduction to the Apogee Compilers. This chapter discusses and
explains the various components of the compilation system, and gives
an overview discussion of compiler optimization and control of the
compiler’s behavior.
Chapter 2:Invoking the Compilers. This chapter discusses the command line
used to invoke the compilation system. This chapter is the "man page"
in UNIX terminology.
Chapter 3:Control-Variables and Control-Programs. This chapter introduces the
control-variables whose values can be set to govern the behavior of the
compilers during compilation.
Chapter 4:Control-Variable Definitions. This chapter discusses the meaning of
Chapter 5:Reference Tables. This chapter contains tables that can be consulted to
Chapter 6:Programming Restrictions. This chapter discusses the restrictions on
Chapter 7:The Apogee-FORTRAN 77/90 Languages. This chapter discusses the
Chapter 8:The Apogee-C & Apogee-C++ Languages. This chapter discusses the
Appendix A:A 5-Minute VAST Guide. This appendix gives a brief introduction to
Appendix B:A 5-Minute KAP Guide. This appendix is designed to supply the basic
Page 10 Apogee User’s Manual
each of the control-variables.
learn the important properties of each of the control-variables and
control-groups.
programming usage that must be followed when applying
optimization to a program.
FORTRAN language accepted by the Apogee-FORTRAN and ApogeeFortran 90 Optimizing Compilers relative to industry standards.
C and C++ languages accepted by the Apogee-C and Apogee-C++
Optimizing Compilers relative to several industry standards.
the VAST preprocessors, including commonly useful switches.
information needed to begin using the KAP preprocessors.
Page 11
Appendix C:Apogee Compilers on SPARC Systems. This appendix documents the
features specific to Apogee’s compilers on SPARC systems.
Appendix D:Apogee Compilers on PowerPC Systems. This appendix documents
the features specific to Apogee’s compilers on PowerPC systems.
Appendix E:Installation and License Management. This chapter is designed to
assist users in installing Apogee products, and in understanding and
utilizing the FLEXlm License Manager.
Typographic Conventions
The conventions for use of various typefaces in this manual are as follows:
PurposeConvention
English proseThe Palatino typeface is used for ordinary English prose in this
manual. The bold variant of Palatino is used to emphasize words.
definitionsFor defined terms, at their point of definition, this typeface, the
underlined variant of Palatino, is used. Some defined terms that are
multiple words are hyphenated.
computer textFor literal samples of text from some language given as input to or
output from the computer, this typeface, the bold variantof a typeface named Courier, is used. Two examples are:
"The control-variable mopt is used to govern the main optimizations."
"When writing a for statement in C.... "
variable fieldsFor parts of the compiler control language whose exact value must be
specified by user, this typeface, the italic variant of Helvetica, is used. For
example:
"To govern the main optimizations, write mopt=n, where n is an
integer from 0 through 4."
"quotation marks"Quotation marks are used in the usual way for quoting text copied
from another place, and for quoting text being discussed (as in the
examples just above). Quotation marks are also used to set off
technical terms borrowed from another context.
Preface
Typographic Conventions
Apogee User’s Manual Page 11
Page 12
Apogee Software, Inc.
Terminology
The following definitions apply to terms used throughout this manual:
TermDefinition
routineA subroutine or function or procedure. As used in this manual, the
term "routine" includes routines which either return a value or do not
return a value, which are either main-routines or not main-routines,
which have either a single entry point or have multiple entry points,
and which are either written by the user or are intrinsic-routines.
Thus in FORTRAN 77/90, the following things are routines: a
program, a subroutine, a function, a block data subprogram, or an
intrinsic function. A statement-function is not a routine.
And in C/C++, the following things are routines: a user-written
function or a library function. A preprocessor macro is not a routine.
main-routineA routine that the user has coded to indicate that it is the starting point
for program execution. In FORTRAN 77/90, a program. In C/C++, a
function named main.
intrinsic-routineA routine whose effect is defined as a part of the definition of the
source language in use, so that it can be called by the user without
needing to be supplied by the user.
programA collection of routines organized by the user to execute together.
Each program must have exactly one main-routine, and may also have
any number of non-main-routines.
program failureAny behavior of the compiled program that causes it to produce the
wrong answers, or to fail to complete execution properly. The concept
of correctness against which program failure or success is measured
can come from either a standard language definition or from the
behavior of the program when compiled by some other compiler. See
the Index listing "program failure".
control-variableA quantity that is similar in concept to a variable in a programming
language, but that exists only during compilation and that is used to
control the behavior of the compiler. Note the hyphen in "controlvariable". This distinguishes it from more casual use of the term, e.g.,
"The loop control variable ...".
target computerThe particular kind and model of computer for which the compiler is
to produce compiled code and the operating environment on it.
host computerThe particular kind and model of computer on which the compiler is
running. The usual situation is, of course, that the target computer is
the same as the host computer. However, it is not necessary that this
be true.
Page 12 Apogee User’s Manual
Page 13
Preface
A 3-minute Guide to Using the Apogee Compilers
A 3-minute Guide to Using the Apogee Compilers
Read this section for a quick introduction to using the Apogee compilers. Also quickly scan
the appendix specific to your target operating environment (eg, SPARC).
On SPARC, the Apogee compilers support both Solaris 1 (SunOS 4.1.x) and Solaris 2.x. The
compilers may be installed on any machine, with a single license permitting use of the
compiler on any connected Solaris 1 or Solaris 2 machine. On a mixed Solaris 1/Solaris 2
network, the compilers may be used transparently on either OS, i.e. the compilers
automatically determine whether they are running under Solaris 1 or Solaris 2. However, the
compilers do not support cross-compilation. Running the compiler on a Solaris 1 system will
produce a Solaris 1 binary, and running the compiler on a Solaris 2 system will produce a
Solaris 2 binary.
The Apogee compilers use the Flexible License Manager (FLEXlm) to permit floating license
usage. That is, the compilers may be used on any machine that is on the same network as the
license server for the compilers. The number of simultaneous users is limited to the number of
licensed copies. For more information, see Appendix E.
The Apogee compilers strongly follow UNIX tradition for compiler options. For areas where
there is not an established UNIX tradition, options unique to the Apogee compilers are used.
The common UNIX compiler options accepted by the Apogee compilers are as follows: -c, -g,
-l, -o, -p, -w, -A, -C,-D, -E, -H, -I, -L, -O, -S, and -U.
The Apogee compilers also accept several Sun-specific options. See page 182 in Appendix C.
To see the "man page" for the compilers, see Chapter 2: "Invoking the Compilers", page 23.
For the nontraditional options, which permit very detailed control of the compilers, see the -X
option in Chapter 2 and the table of control-variables in Chapter 5.
Overall control of optimization is done with the -O
The default is -O1, which does only minimal optimization. The -O3 (or just -O) option is a
very useful level of optimization. Levels -O4 and -O5 invoke interprocedural optimization
and require extra care in managing recompilation. -O and -g may be specified together,
though debugging optimized code presents certain challenges.
Note:To optimize a given program, we recommend compiling it initially with "typical" compiler
optimization enabled. Specifically, build your program using the optimization switch -fast
(or -O), to get a baseline of optimized performance, before enabling other more sophisticated
optimization switches. This simple approach generally results in excellent performance with
virtually no effort.
Optimization for a specific SPARC system can be done by specifying the -XT=name option,
where name is one of the system names found in the table in “Target Machine Group (T)” on
page 131. This option controls the instructions generated by the compiler plus the properties
of the instruction pipeline and system cache assumed by the compiler. The compiled
programs remain compatible across all SPARC systems, except that there are bugs in older
versions of the SunOS emulation of the -cg92 level of instructions on older processors.
n option, where n can range from 0 to 5.
Apogee User’s Manual Page 13
Page 14
Apogee Software, Inc.
The VAST optimizing preprocessors from Pacific-Sierra Research are separately priced options
available with the Apogee compilers. If purchased, they are invoked by specifying the -Xvast
option. Please see "Appendix A: A 5-Minute VAST Guide," as well as the appropriate VAST
User’s Guide. If you are using Solaris 2 and you have purchased the multiprocessor VAST
preprocessor, automatic parallelization of your program may be done with -Xvast=mp.
The KAP optimizing preprocessors from Kuck & Associates are separately priced options
available with the Apogee compilers. If purchased, they are invoked by specifying the -Xkap
option. Please see "Appendix B: A 5-Minute KAP Guide," as well as the appropriate KAP
User’s Guide. If you are using Solaris 2 and you have purchased the multiprocessor KAP
preprocessor, automatic parallelization of your program may be done with -Xkap=mp.
Apogee-C offers several modes for dealing with the differences between traditional C and
ANSI C. The default mode is ANSI compatible with some relaxed requirements. Other modes
offer support for traditional C. See Chapter 8 for details.
Apogee-C++ offers several modes for dealing with the differences between cfront-like C++ and
ARM or ANSI C++. The default mode is ANSI compatible with a number of extensions. Other
modes offer support for cfront-like C++. See Chapter 8 for details.
Apogee-FORTRAN offers several modes for dealing with different FORTRAN dialects. The
default mode is ANSI compatible with support for many extensions. Other modes offer
support for non-ANSI features. See Chapter 7 for details.
Apogee-FORTRAN offers support for a wide variety of FORTRAN input formats. See
“FORTRAN Source File Format” on page 64 for details.
Apogee-FORTRAN offers support for changing the compiled precision of numeric types
declared in the program. See control-variable ftype on page 73 for details.
The Apogee compilers can output cross-reference tables. See control-variable xref on
page 101 for details.
The Apogee compilers and the optimizing preprocessors each require that certain restrictions
on programming usage (as specified in the ANSI C, C++ and FORTRAN standards) be met in
order to apply full optimization. The restrictions required by the compilers are discussed in
Chapter 6: "Programming Restrictions", page 133. The restrictions required by KAP are
discussed further in the KAP User’s Guide. Some programs contain latent violations of these
ANSI restrictions. Such programs may fail when high degrees of optimization are applied. A
systematic process of fixing or working around any such violations may then be necessary to
get the best program performance.
A particularly frequent violation of this sort is "save-usage" in FORTRAN programs. See
“Control-Variable save — SAVE Variables in FORTRAN” on page 77 for the details. The
-Xsave option may be used to work around this problem.
The Apogee compilers use the standard calling sequence, so compiled modules from other
compilers may be intermixed and linked. However, Apogee-FORTRAN uses a different
interface to FORTRAN I/O in order to increase speed, so FORTRAN programs doing I/O may
not be intermixed. Also, because of internal implementation issues in C++ such as name
mangling, C++ object files from different compilers may not be intermixed.
Page 14 Apogee User’s Manual
Page 15
Chapter 1
Chapter 1Introduction to the Apogee
Compilers
The Compilation System
The Apogee optimizing compilers are part of a compilation system having several components
that are used together to compile and execute source programs.
These components are:
1)The Apogee-C compiler. This compiler accepts C source files and compiles them to
produce assembly files, which express the compiled program in symbolic machine
language form. This compiler includes a preprocessor for the C preprocessing
language. This compiler may also include the single or multiprocessing version of the
KAP-C or VAST-C preprocessosrs, which are optionally available. When executing,
this compiler is itself composed of several UNIX processes.
2)The Apogee-C++ compiler. This compiler accepts C++ source files and compiles them
to produce assembly files, which express the compiled program in symbolic machine
language form. This compiler includes a preprocessor for the C++ preprocessing
language. When executing, this compiler is itself composed of several UNIX processes.
If the source files contain template definitions, this compiler may produce instantiationinformation (.ii) files that will be used by a prelinker.
3)The Apogee-FORTRAN compiler. This compiler accepts FORTRAN source files and
compiles them to produce assembly files, which express the compiled program in
symbolic machine language form. This compiler may also include the single or
multiprocessing version of the KAP-F or VAST-F preprocessors, which are optionally
available. When executing, this compiler is itself composed of several UNIX processes.
Apogee User’s Manual Page 15
Page 16
Apogee Software, Inc.
4)The UNIX assembler. This assembler takes assembly files and assembles them to
produce relocatable object files. Object files express the compiled program in a binary
machine language form.
5)The C++ templates prelinker. There are situations in C++ programs using templates
where the absence of certain compiler generated functions (template instantiations) is
only detectable immediately prior to the final linking phase. The prelinker program
determines whether there are any such missing template instantiations, and reinvokes
the compiler on one or more source files, using information provided by the compiler
via .ii files (see “Control-Variable tmpl — Template Instantiation Mode in C++” on
page 87). This prelinker is called just before the final link phase on all object files.
6)The UNIX link editor. The link editor takes one or more relocatable object files and
binds them together to create a single object file. The result can be either a relocatable
object file, which is suitable for input to a subsequent invocation of the link editor, or
an executable object file, which is ready to be executed by UNIX.
7)The patch program. There are situations in C++ programs where certain pieces of code
(constructors for static variables) need to be run before the main program starts, or
after the main program ends. Under Solaris 1 (SunOS), a special program called ’patch’
runs after the link editor, and modifies the final executable file to create the necessary
links to run such code. The Solaris 2 compiler does not require this program because
the assembler and linker provide the same facility in other ways.
Normally one or more source files comprise a program. These source files can be written in C,
C++, FORTRAN 77/90, or in assembly language. In addition, each source file can contain one
or more routines.
The compilation system can be used in a number of different ways to prepare a program such
as this for execution, for example:
case 1)All of the source files can be passed to the system with one command
case 2)The source files can be passed to the system individually to produce
case 3)Some source files and some relocatable object files can be passed to the
case 4)C, C++, and FORTRAN 77/90 source files can be given to the system
Page 16 Apogee User’s Manual
line invocation, with the result being a single executable object file.
one relocatable object file per source file. A final invocation of the
system can produce an executable object file from the relocatable object
files.
system, with the result being a single executable object file.
one at a time or in groups, with an option which indicates that
processing should stop after production of assembly files. Later
invocations of the system can carry the processing through to the
production of the executable object file, or can stop after production of
relocatable object files.
Page 17
Chapter 1: Introduction to the Apogee Compilers
The Compilation System
case 5)The C preprocessor is normally applied to C source files. However, it
can also be applied to FORTRAN source files. This preprocessing can
be followed by normal compilation, or the system can be told to stop
after writing the preprocessed output to a file. Later invocations of
the system can produce an executable object file, or stop at some one
of the other intermediate stages.
case 6)The KAP-C or VAST-C optimizing preprocessor may or may not be
applied to each C source file prior to compilation. The KAP-F or
VAST-F optimizing preprocessor may or may not be applied to each
FORTRAN source file prior to compilation. This preprocessing will
usually be followed by normal compilation, but the system can be told
to stop after writing the preprocessed output to a file.
case 7)The link editor can be invoked repeatedly, binding in more relocatable
object files with each invocation. For each step except the last, the
output is a relocatable object file. For the last step, the output is an
executable object file.
The best way to use the compilation system depends on your situation. For example, case 1)
above is the simplest approach when you have a set of source files and you only want to
execute the program (this case is also the default behavior of the system). Case 2) above is
often used during program development, when only modified files need to be recompiled.
One part of each compiler, called the driver, controls the actions of the system. The driver is
invoked by the command line that starts the system, and when invoked runs as a single UNIX
process. The driver looks at the set of options passed to it, as well as the suffix of each file
name it is passed. These files and options direct the behavior of the driver as it invokes
and/or directs the behavior of the remainder of the system.
The components of the compilation system communicate with each other by writing and
reading temporary files. For example, when the KAP-F preprocessor is run, the result of KAP
is placed in a temporary FORTRAN source file, and this temporary file is then processed by
the compiler. By default, all temporary files are placed in the directory "/tmp". A directory
other than "/tmp" can be used by setting the environment variable TMPDIR to the desired
directory path-name.
Chapter 2 contains a detailed discussion of the command line used to invoke the compilation
system. The following examples are given as an introduction to that discussion.
For the first example, suppose the driver is passed a mixture of FORTRAN 77/90, C, C++ and
assembly source files with no command line options (thus invoking the default behavior of the
driver). Under these circumstances, case 1) above applies. Specifically the driver will:
•pass each of the given FORTRAN 90 source files to the FORTRAN 90 compiler for
compilation,
•pass each of the given FORTRAN 77 source files to the FORTRAN 77 compiler for
compilation,
•pass each of the given C source files to the C compiler for C preprocessing and
compilation,
Apogee User’s Manual Page 17
Page 18
Apogee Software, Inc.
•pass each of the given C++ source files to the C++ compiler for C++ preprocessing and
compilation,
•pass all of the resultant assembly files and all of the given assembly source files to the
assembler for assembly, and
•pass all of the resultant relocatable object files to the link editor to produce a single
combined executable object file.
•invoke a patch program for C++ executables to take care of constructor calls before the
main program begins.
A point worth noting for this example is that all drivers will pass FORTRAN files to the
FORTRAN compiler, C files to the C compiler, C++ files to the C++ compiler, and assembly files
to the assembler.
As a second example, suppose the driver is passed a mixture of FORTRAN, C and assembly
source files, but is also given the -Xvast command line option (which directs it to use the
appropriate VAST preprocessor). Under these circumstances, the driver will:
•pass each of the given FORTRAN source files successively through the VAST-F
preprocessor for optimization prepr ocessing and then through the FORTRAN compiler
for compilation,
•pass each of the given C source files successively through the C compiler for C
preprocessing, through the VAST-C preprocessor for optimization preprocessing, and
then through the C compiler for compilation,
•pass all of the resultant assembly files and all of the given assembly source files to the
assembler for assembly, and
•pass all of the resultant relocatable object files to the link editor to produce a single
combined executable object file.
•invoke a patch program for C++ executables to take care of constructor calls before the
main program begins.
As a third example, suppose the driver is passed a single FORTRAN source file and is also
given the -c command line option. (The -c option directs the driver to stop prior to calling
the link editor.) Under these circumstances, the first half of case 2) above applies. Specifically
the driver will:
•pass the given FORTRAN source file to the FORTRAN compiler for compilation, and
then
•pass the resultant assembly file to the assembler for assembly, leaving the resultant
relocatable object file in the current directory.
This third example is the case commonly used in make files to cause recompilation when a
source file or any of its antecedents has changed.
As a fourth example, suppose the driver is passed a set of relocatable object files and no
options. Under these circumstances, the second half of case 2) above applies. Specifically the
driver will pass the given files to the link editor, which will bind them together to produce a
single executable object file.
Page 18 Apogee User’s Manual
Page 19
Chapter 1: Introduction to the Apogee Compilers
Optimization
This fourth example is the case commonly used in make files to create the executable object file
when any of the relocatable object files have changed.
There is a point worth noting regarding the first and fourth examples. In UNIX, you must
explicitly pass to the link editor the names of subroutine libraries containing any intrinsicroutines needed by the compiled program. In the default case, this information does not come
from the object files being linked, but from the particular driver you have invoked. The C
driver passes by default just the libraries needed by C programs, while the C++ driver passes
by default the libraries needed by C++ programs and the libraries needed by C programs.
Similarly, the FORTRAN drivers pass by default the libraries needed by FORTRAN programs
and the libraries needed by C programs. Thus if FORTRAN programs are among the
relocatable object files being linked, you must either invoke the FORTRAN driver to do the
linking, or you must augment the list of libraries passed to the link editor by using the -l
option.
Optimization
The distinguishing characteristic of the Apogee compilers is their ability to aggressively
optimize programs. This characteristic has the following consequences:
•Programs execute faster. The amount of execution time saved varies strongly with the
particular source program and with the way it is written, but some time is saved for
almost all programs and a very significant amount of time is saved for some
programs.
•Since optimization requires more time and more memory during compilation,
applying it to a program is not always an effective use of computer resources. For
example, during program development a program may only be executed for a short
time each time it is compiled. In this case, optimization may require more compilation
time than it saves in program execution time. Because of this, the Apogee compilers
permit you to control the extent of the optimization in a number of ways.
•The optimization applied by the compilers depends on certain programming
restrictions that are part of the standard language definition for each language. If a
source program violates these restrictions, optimization applied to the source program
sometimes produces an object program that fails. (This failure may take the form of
different results from the program, or it may be something more dramatic, such as a
program abort.) Because of this requirement:
1)the compilers permit you to control the natur e of the optimization in a number
of ways, and
2)you may find it desirable to modify the program to conform to the standard
language definition in order to be able to apply optimization to it.
•An optimized object program differs from an unoptimized object program in a
number of ways, for example:
1)The basic control flow of the program (i.e., its tests, branches, loops, and so
forth) can be changed.
Apogee User’s Manual Page 19
Page 20
Apogee Software, Inc.
2)Even where the control flow is not changed, computations will probably be
done in a quite different order than the one expressed in the source code.
3)The registers of the processor are used to hold quantities across longer sections
of the program. (For example, a "variable" of the source program may never
appear in memory at all.)
Because of these facts, any interaction you have with the optimized program at the assembly
code level will become harder. One of these interactions is the use of the debugger. Debugging
optimized code is very difficult because of the changes to the program.
The following is a list of some of the optimizations that are applied by the Apogee compilers:
•Common Subexpression Elimination. If a value that has already been computed is
unnecessarily recomputed, the first result can be held in a processor r egister and r eused
instead of being recomputed. Sometimes the value is a repeated expression in the
source code. Sometimes it is below the level of the source code. For example, if there
are two FORTRAN references to a real array A(I), with no intervening assignment to
I, the value 4*I needed to address the array in memory does not have to be
recomputed.
•Constant Folding and Constant Propagation. Expressions involving constant operands
can be computed during compilation. Assignment of constant values to variables can
be propagated forward to the next use of the variable.
•User function inlining. Calls to small user functions can be replaced by the code they
call. This saves the overhead of making a function call and creates additional
opportunities for optimization by providing the optimizer with greater scope on which
to work.
•Code Motion. Values computed within a loop that are the same each time through the
loop can be computed once, either before or after the loop, as appropriate. The code
that computes such values can be moved a significant distance, for example,
completely outside of a large nested loop.
•Dead Code Elimination. Code that will never be executed or whose results will never
be used can be eliminated. This can be individual computations, or whole sections of
code. Such code can result from poor programming, but more commonly results from
the fact that other optimizations have removed all uses of a value.
•Strength Reduction. Within loops, multiplication operations involving values that
change linearly with the loop iterations can often be replaced with suitable addition
operations.
•Induction Variable Elimination. Loop control variables that are not needed can be
eliminated. This situation is common in loops after strength reduction has been
applied.
•Control Flow Improvements. Several kinds of improvements can be applied to the
control flow of the program. For example, unconditional transfers to unconditional
transfer instructions can be eliminated.
Page 20 Apogee User’s Manual
Page 21
Chapter 1: Introduction to the Apogee Compilers
Control of Compiler Behavior
•Loop Unrolling. Code within loops can be replicated one or more times. This
decreases the loop control overhead and increases the opportunities for scheduling.
•Scheduling. Instructions can be reordered in a way that impr oves the utilization of the
fine-grained-parallelism available on the target computer.
It is a characteristic of optimization that it is possible to do a better job when more of the
program is given to the compiler at one time.
Consider the following example. Suppose a variable is referenced both before and after a call
to a routine. The code will execute faster if this variable can be loaded once into a processor
register and used from that register both before and after the call. If the routine being called,
or any routines it can call, could possibly modify the variable in memory, then the value in the
register after the call may not be valid, and a second load instruction must be generated by the
compiler. However, if the compiler can analyze all of these routines and determine that this
variable could not possibly be modified, then the load instruction need not be generated.
Given this characteristic, it is generally true that you will obtain better performance when
more of the program is given to the compiler at a single invocation. In fact, if the whole
program is given to the compiler and the compiler is informed of this fact, then the highest
degree of optimization can be achieved.
For small programs, the whole program can easily be given to the compiler in one invocation.
For large programs, however, the process of giving most or all of the program to the compiler
at one invocation has several drawbacks:
•It requires significant additional time and memory to do the compilation, and
•It is counter to the usual organization of make files, which typically cause the
invocation of the compiler only on the changed portions of the program.
These drawbacks must be balanced against the importance of program performance. In the
typical program development process, most source code changes occur early in the project,
during the coding and debugging phases. It makes sense to use low levels of optimization and
give the program to the compiler in small pieces during these phases. Later, during validation
and/or performance tuning, compilation is less frequent and you may want to use high levels
of optimization and give all or most of the program to the compiler at one invocation. This
latter usage may require modification of the concerned make files to support it, possibly as an
additional mode. In any case, for a large project, it probably makes sense to evaluate the
degree of performance improvement achieved for the program by compiling all or most of it at
once, and to balance this against the additional resources required to do the larger
compilation.
Control of Compiler Behavior
The Apogee compilers give you much flexibility in controlling their behavior during
compilation. Some of the aspects of compiler behavior that you can control are:
•The sort of progress that is made towards the production of an executable object file
(as discussed above).
Apogee User’s Manual Page 21
Page 22
Apogee Software, Inc.
•The sorts of optimization that are applied by the compilers, and the extent to which
they are applied.
•The dialect of the source language that was used in the source program, and/or the file
format that was used to encode the source program.
•The target computer.
•The sorts of listings, diagnostics, symbolic debugging information, or other output that
the compilers should produce.
•The sorts of resource utilization limits that are to be placed on the compilers.
For some aspects of the control of a compiler‘s behavior, there is an established UNIX tradition
that dictates the details of the control mechanism. This applies particularly to the organization
of the compilers into the kind of compilation system discussed above and to the options that
are used to direct the compilation system activity (such as the -c option, which stops activity
before invoking the link editor).
For other aspects of the control of the compiler‘s behavior, there is no established UNIX
tradition, and mechanisms specific to the Apogee compilers are used.
Control of the compiler‘s behavior can be exercised in two different places:
•On the command line, with command line options and with the nature of the files
passed to the compilers.
•Within the source files, by way of a suitable construct that is an extension of the source
language. For the Apogee compilers, this construct takes the form of pragma
directives.
Some aspects of the compiler‘s behavior need only be controlled at the level of the command
line. For these aspects, there are suitable command line options. Most aspects of the compiler‘s
behavior, however, are appropriately controlled from either the command line or the source
file, depending on the circumstances. Consider, for example, the degree of optimization to be
applied. This will usually be controlled most conveniently from the command line. However,
if the nature of a certain routine required that a certain sort of optimization be disabled for that
routine, it would be more convenient to put the disabling directive with the routine. There are
other examples with exactly the opposite properties (i.e., it is usually more convenient to place
them in the source program, but sometimes better to place them on the command line).
To satisfy this dual usage need, a control scheme is used that permits control to be exercised on
either the command line or in the source file, strictly at your discretion. The basic idea is that of
a set of control-variables. For each controllable aspect of the compilers‘ behavior, there is a
control-variable, and the value currently assigned to this variable dictates the compiler‘s
behavior. These variables can be given initial values on the command line, and their values can
be changed at any point in a source file by a suitable pragma directive. For example, a controlvariable named mopt controls the main optimizations applied by the compilers. A value of
mopt=0 means no optimization, while a value of mopt=3 means a high degree of optimization.
If mopt is set to 3 on the command line, and no pragma directives change this, the whole
compilation will be done with a high degree of optimization. If however, pragma directives
changed the value to 0 for one routine, no optimization would be done on that routine.
Control-variables are discussed in detail in Chapter 3, Chapter 4, and Chapter 5.
Page 22 Apogee User’s Manual
Page 23
Chapter 2
Chapter 2Invoking the Compilers
Compiler Invocation Command
The Apogee-C compilation system is invoked by a command line of the form:
apcc [options] files
The Apogee-C++ compilation system is invoked by a command line of the form:
apCC [options] files
The Apogee-FORTRAN 77 compilation system is invoked by a command line of the form:
apf77 [options] files
The Apogee-Fortran 90 compilation system is invoked by a command line of the form:
apf90 [options] files
In all command lines, files is a list of file names, as discussed in the next section, and options is a
list of options, as discussed after the section on files.
Files
With either invocation command, files can be any mixture of the following kinds of files, as
determined by the file name suffix:
SuffixMeaning
.cA C or C++ (for apCC) source program.
.CA C++ source program.
Apogee User’s Manual Page 23
Page 24
Apogee Software, Inc.
.CCA C++ source program.
.ccA C++ source program.
.C++A C++ source program.
.c++A C++ source program.
.CXXA C++ source program.
.cxxA C++ source program.
.cppA C++ source program.
.iA C or C++ source program that has already been preprocessed.
.fFor apf77, a FORTRAN-77 source program. For apf90, a Fortran 90
source program in fixed format.
.forSame as .f.
.FFor apf77, a FORTRAN-77 source program that should be
preprocessed by the C preprocessor before compilation. Not
supported by apf90 in this release.
.f90A FORTRAN 90 source program in free format.
.F90Not supported in this release.
.incA Fortran 90 include file. If the first letter is an upper-case ’V’ the file
(Else)A file intended for the link editor.
The files need not be in the current directory. Absolute or relative path names can be used.
The default assumption of all compilation systems is that the passed files together comprise a
single program that you would like to prepare for execution. Thus the default behavior of both
systems is to process all of the passed files appropriately according to their kind, and then to
combine the results to yield a single executable object file. The following specific steps are
taken to achieve this:
1)All C/C++ and FORTRAN 77/90 source files are compiled to produce assembly source
files, which are placed in a temporary directory. All source files with .c, .C, .cxx,.cpp, .i, .F or .F90 extensions are preprocessed by the appropriate preprocessor
before compilation (this is redundant but harmless for .i files).
2)All assembly source files, either produced in step 1 or given as input, are assembled to
produce object files in the current directory, each of whose names have .o substituted
for the previous file name suffix. Any previous file with the same name is removed.
Page 24 Apogee User’s Manual
Page 25
Chapter 2: Invoking the Compilers
Fortran 90 File Names
3)All object files, either produced in step 2 or given as input, are passed to the link
editor, which combines them and links them to produce a single executable object file
in the current directory named a.out.
4)For C++ compilations under Solaris 1, the patch program is invoked.
5)If only one file which was a source file was given to the compilation system, and no
errors have occurred, then the .o file created from that source file is deleted.
Fortran 90 File Names
WARNING! When compiling modules, Apogee-Fortran 90 creates files that start with the
upper-case letter V, and files that end with the extension .vo. In particular, if you have a
Fortran 90 source file named prog.f90, and it defines a module named foo, then after
compiling prog.f90 the following 2 files will exist:
Vfoo.inc
foo.vo
Users should be careful not to create file names that begin with V, or end with .vo. If you are
using makefiles, you may want to add a line to any "clean" or "clobber" rules in your makefiles
such as:
/bin/rm -f V*.inc *.vo
Options
The default behavior described above can be changed and/or extended in various ways by the
use of options. The options described below can be given. Any other options given are
ignored by the compilers and passed through to the link editor.
The C/C++ preprocessor is not available for use with Fortran 90 programs in version 4.0 of the
Apogee compilers. Consequently several options are immaterial or have slightly changed
meaning for the user of Fortran 90. In a Fortran 90 context, the following are not meaningful:
-A, -D, and -U.
-Aname [ (tokens) ] Associates name as a predicate with the specified tokens as if by an
#assert preprocessing directive. The set of "preassertions"
automatically defined by the compiler are machine dependent. See
the appropriate appendix for the compiler you have.
-cStop the compilation before invoking the link editor, leaving the .o
files in the current directory.
-CRetain comments in the C preprocessor output.
-cg87Compile instructions for the old SPARC cpu’s without square root.
This is an abbreviation for -Xcg=87.
Apogee User’s Manual Page 25
Page 26
Apogee Software, Inc.
-cg89Compile instructions for the old SPARC cpu’s with square root but
-cg92Compile instructions for SPARC cpu’s meeting the version 8
-cg94Compile instructions for SPARC cpu’s meeting the version "v8plus"
-Dstring(There must not be whitespace between -D and string.) Define names.
-dalignAssume that double word objects referred to indirectly will always be
-dryrunWrite, to stderr, the name and arguments for each process that
-EWrite preprocessor output to stdout and stop the compilation. When
-fastThis is an abbreviation for -O -dalign -native. It provides a
-gInclude symbolic debugging information in the assembly files, and
without integer multiply and divide (version 7). This is an
abbreviation for -Xcg=89.
architecture specification except for quad-precision. This is an
abbreviation for -Xcg=92.
architecture specification except for quad-precision, which is
appropriate for UltraSPARC processors. This is an abbreviation for
-Xcg=94.
This option applies only to source files passed through the C
preprocessor. string can be of the form name=def or name. In the first
case, name is defined with value def exactly as if a corresponding
#define statement had occurred as the first line of the program. In
the second case, name is defined with the value 1. The -D option has a
lower precedence than the -U option, see below.
properly aligned, so double word load and store instructions can be
used. This assumes that the unusual case in the SPARC ABI which
permits doubles to be misaligned never arises. This is an abbreviation
for -Xalnref=0.
would be invoked during compilation, plus the name of each
temporary file that would be unlinked, but do not actually do any
compilation.
KAP is used, it is the KAP output that is written to stdout. When
VAST is used, it is the VAST output that is written to stdout. When
no optimizing preprocessor is used in C, it is the C prepr ocessor output
that is written to stdout. For C/C++ preprocessor output, comments
are removed from this result by default (but see -C above), while line
number information is included. For Fortran 90 files, the FORTRAN77 output produced by VAST/f90 is written to stdout. No compiler
is called on any file.
capability similar to the SunSoft compiler’s -fast switch.
cause the default optimization level to be -O1. The effect of -g is
exactly as if -XO=1,g had been written as the first option of the
command line. (This ensures that "-g -O" is the same as "-O -g".) In
C++, this causes functions declared with the inline specifier to NOT
be inlined. See also -g0, below.
Page 26 Apogee User’s Manual
Page 27
Chapter 2: Invoking the Compilers
Options
-g0("0" = zero.) Like -g, but still do inlining of functions declared with
the inline specifier. This usually improves both compile-time and
code-size, but makes it very difficult to debug inline functions.
-HWrite the pathnames of included files to stdout and stop the
compilation. Any source files to be preprocessed are passed through
the preprocessor, but normal preprocessing result files are not
produced. Instead, a list of the pathnames of all files included during
the preprocessing is written onto stdout. No compiler is called on
any file (so FORTRAN include statements have no effect). Also see
the -M option, below.
-Idir(Whitespace is optional between -I and dir.) This option changes the
search order used to find files named in either the #include
statement (C/C++) or the include statement (FORTRAN).
For #include statements, this search order is as follows:
•For file names that are absolute pathnames, use only the
named file.
•For file names that are not absolute pathnames and that are
enclosed in quotation marks, search relative to the following
directories, in the listed order:
1)If control-variable inclpath has the value
absolute, the directory containing the primary
source file. If control-variable inclpath has the
value relative, the directory containing the file that
contains the #include statement (these two
directories differ only for nested #include
statements).
2)The directories listed in any -I options, in the order
the options occur on the command line.
3)The directories on the "standard list".
•For file names that are not absolute pathnames and that are
enclosed in angle brackets, search relative to the following
directories, in the listed order:
1)The directories listed in any -I options, in the order
the options occur on the command line.
2)The directories on the "standard list".
The "standard list" is a list of two directories:
•The directory where the Apogee-supplied include files have
been installed, and
•/usr/include
For include statements, the search order is as follows:
Apogee User’s Manual Page 27
Page 28
Apogee Software, Inc.
-KAccept the Kernighan&Ritchie (K&R) dialect of C. This is an
-keeptempDo not remove any temporary files created during compilation.
-lx(There must not be whitespace between -l and x. "l" = lowercase "L".)
-Ldir(There must not be whitespace between -L and dir.) This option is
-MWrite make dependencies to stdout and stop the compilation. Any
-M1("1" = one.) Like -M but do not emit dependencies for include files
-nativeThis is an abbreviation for -Xcg=native.
-noexThis is an abbreviation for -Xc-=exceptions.
-nolibSuppress all -l options the driver would otherwise have generated.
•For file names that are absolute pathnames, use only the
named file.
•For file names that are not absolute pathnames, search relative
to the following directories, in the listed order:
1)The directory containing the file that contains the
include statement.
2)The directories listed in any -I options, in the order
the options occur on the command line.
abbreviation for -Xc=knr.
This option is passed to the link editor, where it directs the link editor
to search a library named libx. Various extensions are applied to
libx, depending on whether dynamic or static libraries are to be
searched. The -l option differs from the other options in that it can be
intermixed with the file names, and the relative placement among the
file names has significance. See the description of ld(1).
passed to the link editor, where it directs the link editor to look in dir
when looking for libx before looking in the standard library
directories. See the description of ld(1).
source files to be preprocessed are passed through the preprocessor,
but normal preprocessing result files are not produced. Instead, a list
of dependency lines determined by the use of (possibly nested)
#include statements and suitable for input to the UNIX make
program is written onto stdout. Neither the FORTRAN 77 compiler
nor the part of the C/C++ compiler after preprocessing is called on any
file (so FORTRAN include statements have no effect though
#include statements in .F files are processed). This option is not
meaningful to apf90 in release 4.0.
which are from the "standard list" of system include dir ectories. See-I
above for the definition of the "standard list".
Page 28 Apogee User’s Manual
Page 29
Chapter 2: Invoking the Compilers
Options
-o outfile(There must be whitespace between -o and outfile.) This option
permits naming the output file something other than the default rules
would have generated. Certain restrictions on the suffix of
outfile are
enforced if compilation is stopped before calling ld. This is to
prevent accidental overwriting of the source file, for instance. This is
often used to direct the link editor to place the executable object file in
a file named
outfile rather than a.out. See the description of ld(1).
-O(O = capital letter o) Turn on a generally useful level of global
optimization. This option is an abbreviation for -XO=3, see the next
paragraph.
-On(O = capital letter o) Ther e must not be whitespace between-O and n.
Turn on optimization at level
n, where n can be 0 (zero) through 5. In
general terms, these values mean:
0(zero) No optimization.
1Local (basic-block scope) optimization only.
2-O1, plus intraprocedural global optimization, scheduling,
and variables may reside in registers.
3-O2, plus more extensive global optimizations.
4-O3, plus interprocedural global optimization and inlining.
5-O4, plus more extensive inlining and global optimizations.
Caution must be used in handling object (.o) files produced by -O4
and -O5. In these modes, when multiple files are passed to the
compiler, interprocedural optimization across files occurs, so the
resultant object files are dependent on each other for correct
execution. If a change is made in one of these source files, all of the
related files must be recompiled.
This option is an abbreviation for -XO=
n. See “Optimization Group
(O)” on page 129 for the detailed meaning of control-group O. As
described in Chapter 4 and Chapter 5, if no specification of
optimization is given, the result is equivalent to -O1.
-PThis option applies only to C/C++ source files. All C/C++ source
files are only preprocessed, with the preprocessing result for each file
written to a file name that has .i substituted for the file name suffix
of the source file. Comments are removed from this result by default
(see -C above), but line number information is included. The C/C++
compiler is not called on the preprocessed results.
-pSet up the output code for profiling via prof(1). This is an
abbreviation for -Xprof=1. If compilation and link editing are done
in separate steps and -p is used during compilation, it must also be
used during link editing. Some profiling information can be gathered
by linking with -p without compiling with -p.
Apogee User’s Manual Page 29
Page 30
Apogee Software, Inc.
-pg(Supported in Solaris 1 (SunOS) only.) Set up the output code for
-PICGenerate Position Independent Code. This is an abbreviation for
-picGenerate Position Independent Code, assuming that the Global Offset
-SStop the compilation before invoking the assembler and leave all of the
-target wordIgnored. Included for compatibility reasons.
-uIn FORTRAN 77/90, process declarations as if there were an
-Uname(There must not be whitespace between -U and name.) This option
-vWrite to stderr, the name and arguments for each process that is
-VWrite the version numbers of each process invoked to stdout.
-verboseWrite to stderr, the name and arguments for each process that is
-wSuppress warning messages. This is an abbreviation for -Xdiag=0.
-Wc,arg1[,arg2...]Hand off the arguments arg1 to process c where c is in the following
profiling via gprof(1). This is an abbreviation for -Xprof=2. If
compilation and link editing are done in separate steps and -pg is
used during compilation, it must also be used during link editing.
-Xaddr=PIC.
Table is less than 8 kilobytes. This is an abbreviation for -Xaddr=pic.
assembly source files produced by the compilation in the current
directory.
IMPLICIT NONE statement present, whether or not there is such a
statement. This is an abbreviation for -Ximplicit=0.
applies only to source files passed through the C/C++ preprocessor.
Any initial definition of name is removed. Such an initial definition can
be created by the -D option, or can be one of the symbols that are
predefined in a particular environment. A -U option overrides a -D
option for the same name regardless of the order of the options on the
command line. See the index entry for -D for references to predefined
symbols.
invoked during compilation, plus the name of each temporary file that
is unlinked.
invoked during compilation, plus the name of each temporary file that
is unlinked.
This serves to suppress warnings from preprocessors, but not from the
assembler or linker.
list. For example, to pass "-arg" to the assembler, use a command line
similar to: "apcc -Wa,-arg foo.c".
pC/C++ preprocessor
kKuck & Associates preprocessor (KAP)
vPacific-Sierra Research preprocessors (VAST), including
-whereWrite to stderr, a trace of the process of locating the license file and
the other processes of the compiler.
-xFPut each function in a separately relocatable text section. This switch
supports the SPARCworks Analyzer mapfile function for Solaris 2
only. This is an abbreviation for -Xrelfunc=1.
-Xcprog(There must not be whitespace between -X and cprog.) Assign initial
values for any number of control-variables, where cprog is a controlprogram as defined in Chapter 3. For example,
-Xmopt=4,inline=joe,unroll=8
assigns an initial value of 4 for control-variable mopt, an initial value
of "joe" for control-variable inline, and an initial value of 8 for
control-variable unroll.
-X options can be repeated. The full set of -X options, -XX options,
and options that are abbreviations for -X options, are processed in
left-to-right order, with the rightmost assignment prevailing in the
case of duplicate assignments. (Note that -g is an exception to this
rule: it is processed first, regardless of its relative position.) Particular
care is needed when using control-groups because they contain
implicit assignments to a number of control-variables.
The initial values assigned in this fashion on the command line are
established as the value in effect at the start of each source file
processed by the compilation system. The value in effect can be
changed for part or all of each source file by pragma directives that
occur within the file.
Chapter 3 contains a complete description of control-programs.
Chapter 4 contains a complete description of the meaning of each
control-variable. Chapter 5 contains quick reference tables for all
control-variables.
-XXcprog(There must not be whitespace between -XX and cprog.) Assign non-
changeable values for any number of control-variables, where cprog is
a control-program as defined in Chapter 3. This option differs from
-X above in that the values assigned by cprog do not change (in this
compilation) regardless of whether pragma directives or other
command-line options are seen. -XX options can be repeated, and can
be mixed with -X options. See the left-to-right rule stated above
under the -X option.
Apogee User’s Manual Page 31
Page 32
Apogee Software, Inc.
-XKkopt(There must not be whitespace between -XK and kopt.) Specify one
-XV
vopt(There must not be whitespace between -XV and vopt.) Specify one
-Y
c,dirSpecify a new pathname, dir, for the locations of the processes specified
-#Write to stderr, the name and arguments for each process that is
-##Like -#, but do not actually do any compilation. In csh scripts, the #
option to be passed the KAP preprocessor. The relative order of -XK
options is preserved. Equivalent to -Wk,-
kopt.
option to be passed the VAST preprocessor. The relative order of -XV
options is preserved. Equivalent to -Wv,-
vopt.
by c, where c is one or more of the following:
pC/C++ preprocessor
kKuck & Associates preprocessors (KAP)
vPacific-Sierra Research preprocessors (VAST), including
VAST/f90
ffront-end
iinterprocedural analyzer
bback-end (optimizer/code generator)
aassembler
llink editor
Sdirectory containing the startup routines.
Idefault include directory
Lfirst default library directory searched by ld(1).
Usecond default library directory searched by ld(1).
For example, to link with startup routines from another directory, use a
command line similar to the following:
apcc -YS,/usr/new/lib a.o b.o c.o
If a new pathname is specified for a process that would otherwise not
have been invoked, this pathname will be ignored with one exception.
In the Apogee-C/C++ compiler, the C/C++ pre-processor is not
implemented as a separate UNIX process; the pre-processing function
is incorporated into the C/C++ front-end. However, if a -Yp,dir option
is given, the driver will use a file named cpp in directory dir as the preprocessor. The location of the standard UNIX cpp varies among
installations, but it is usually in /lib.
invoked during compilation, plus the name of each temporary file that
is unlinked. In csh scripts, the # character must be escaped.
characters must be escaped.
Page 32 Apogee User’s Manual
Page 33
Chapter 3
Chapter 3Control-Variables and
Control-Programs
Control-Variables
The basic idea of control-variables is to control the behavior of the compiler by assigning values
to variables. This chapter discusses the concept of control-variables. Chapter 4 contains a
detailed discussion of the meanings for all control-variables. Chapter 5 contains a quick
reference table of the values of all control-variables.
There is a control-variable for each of a number of controllable aspects of the compiler’s
behavior. During compilation, the values currently assigned to these variables govern the
compiler’s behavior at that point. Control-variables are conceptually similar to variables in
programming languages. Specifically, they have the following properties:
•Each control-variable has a unique name. (This name is case-sensitive and is always
composed of lowercase letters.)
•The set of control-variable names is fixed (one example is the control-variable named
mopt). You cannot create new control-variables.
•Each control-variable has a particular type in the sense that there is a certain set of
values that may be legally assigned to it.
•Each control-variable has a definite assigned value at all points throughout each
C/C++ or FORTRAN 77/90 source file. This value can change at different points
within the source file (depending on the occurrence of pragma directives in the source
file).
•Each control-variable has a particular scope that governs the range of the source file
over which changes to its value have effect.
Apogee User’s Manual Page 33
Page 34
Apogee Software, Inc.
•Each control-variable has two default values. The first-default-value applies when no
mention is made of the control-variable. The second-default-value applies when the
control-variable name is used with no accompanying assigned value.
•Control-variables exist only during compilation; they have no existence at run-time.
The value assigned to a control-variable at any point in a source file is established by the
following rules:
•At the start of each source file, the value established by command line processing is
assigned to the control-variable. The -X and the -XX command line options are used
for this purpose.
•If this value was established via the -XX option, it does not change throughout the
source file. Otherwise, proceeding sequentially through the source file, if a pragma
directive that assigns a value to the control-variable is encountered, the newly assigned
value is established until it is changed by another assignment or until the end of the
source file is reached.
A pragma directive, or simply "pragma," is a statement in the source code of the program
which is syntactically equal to a comment, but which can communicate information to the
compilation system. One use of pragmas in the Apogee compilers is to manipulate the value(s)
of control-variable(s) and/or control-group(s).
The notion of scope for a control-variable is similar to the notion of scope for a programming
language variable in one important way: it governs the range of the program over which the
variable has effect. However, the scope of a control-variable is quite different from the scope of
a programming language variable in the way it accomplishes this purpose. Specifically, the
notion of scope for a control-variable has the following properties:
•Each control-variable has one of five possible scopes:
1)Compilation Scope.
2)File Scope.
3)Routine Scope.
4)Loop Scope.
5)Line Scope.
•The scope of a control-variable dictates a corresponding set of scope-points for the
variable, as follows:
1)For control-variables with compilation scope, there is one scope-point: at the
start of compilation, after the processing of the control-variable assignments on
the command line, but before the processing of any source text fr om any sour ce
file.
2)For control-variables with file scope, there is a scope-point at the start of each
file, when the first token of non-pragma non-comment source language text is
encountered, i.e., after the processing of any pragma directives that precede
this first token of true source language text.
Page 34 Apogee User’s Manual
Page 35
Chapter 3: Control-Variables and Control-Programs
Control-Groups
3)For control-variables with routine scope, there is a scope-point at the start of
each routine, when the first token of text that defines a new routine is
encountered.
4)For control-variables with loop scope, there is a scope-point when the first
token of an iterative source language statement is encountered. (For
FORTRAN77/90, the do statement; for C/C++ the for, while and do
statements.)
5)For control-variables with line scope, there is a scope-point at the start of each
source line, after the processing of any pragma directive on the preceding line
is completed.
•The scope-points for a control-variable are the only points at which the compiler reads
the value currently assigned to the control-variable and uses this value to govern the
compiler’s (future) behavior.
These rules about control-variable assignment and control-variable scope have the following
effect:
•Pragma directives assigning values to control-variables may be written at any point in
any source file where pragma directives can be written, regardless of the scope of the
control value.
•Pragma directives assigning values to control-variables will have the effect of doing
the specified assignment and establishing the current value of the control-variable,
regardless of the scope of the involved control-variable. The only exception to this is:
if a value was established for the control-variable via the -XX option on the command
line, the assignment will be ignored.
•The current value established for a control-variable will have no effect on the behavior
of the compiler until the next scope-point for that control-variable. At this next scopepoint, the currently established value will be read by the compiler and saved for use in
governing the behavior of the compiler until the succeeding scope point is
encountered.
•A control-value with compilation scope behaves as if it were always set via the -XX
option.
•A value assigned to a control-variable with a pragma directive that occurs after the
last scope-point in the file for that control-variable will never be applied by the
compiler.
Control-Groups
There is a rich set of individual control-variables, with each control-variable governing a
particular detailed aspect of the compiler’s behavior . This arrangement provides flexibility for
those circumstances that need it, but it can also place an undue burden on you to set large
numbers of control-variable values. A facility for grouping control-variables is provided to
ease this burden. See “Control-Group Reference Tables” on page 129 for control-group
reference tables.
Apogee User’s Manual Page 35
Page 36
Apogee Software, Inc.
Control-groups have the following properties:
•Each control-group has a unique name. (This name is case-sensitive and is always a
single uppercase letter.)
•There is a particular set of control-variables that are said to be in the control-group.
•Each control-group has a particular type in the sense that there is a certain set of values
that may be legally assigned to it.
•Control-groups do not possess values in the same way that control-variables do. The
assignment of a particular value to a control-group is interpreted as an abbreviation for
the assignment of some particular set of values to the control-variables in the group.
•Each control-group has a second-default-value, which is the value assigned to the
control-group when its name is used without an accompanying assigned value.
(Control-groups do not have first-default-values. If a control-group is not mentioned,
and there is no other assignment to a control-variable in that control-group, then the
first-default-value of that control-variable applies.)
Control-Expressions
Control-variables may be assigned values of any of the following types: integers, names, pairs,
or lists of names or pairs. Values of these types are created by the evaluation of controlexpressions. Control-expressions may be formed as follows:
•Integer constants written using decimal notation may be used as integer values. For
example "1" and "47" are possible integer values.
•Integer expressions may be formed using plus and minus operators. For example,
"1+4+8-2" yields "11". Parentheses may not be used, and evaluation is strictly left-toright. For example, "5-1+3" and "11-1-3" both yield "7".
•Name values may be written using any characters except equal ("="), comma (","), plus
("+"), minus ("-"), and colon (":"). The first character must not be percent ("%") or a
numeric digit. Note that this permits names formed by the identifier rules of either C
or FORTRAN as well as permitting most UNIX file names or path names. For example,
"simple3" and "gorp/foo_bar" are possible name values.
•The pair operator, written using the colon character (":") as a separator, may be used to
form pair values. Pair values must have a name as the first part of the value, but may
have either a name or an integer as the second part of the value. For example, "a:2",
"b:1", and "c:joe" are possible pair values.
•The list addition operator, written using the plus character ("+"), may be used to form
list values. Items in the list may be either names, pairs or a mixture. For example
"a+b+c" is a list containing three names, while "a:2+b:1+c:joe+d" is a list
containing three pairs and one (unpaired) name. If a name is duplicated in a list, the
rightmost one prevails. For example, "a:10+b+a:5" yields "b+a:5" and "a:10+b+a"
yields "b+a".
Page 36 Apogee User’s Manual
Page 37
Chapter 3: Control-Variables and Control-Programs
Control-Assignments
•The list subtraction operator, written using the minus character ("-"), may be used to
form list values by deleting elements from a list value. For example, "a+b+c-a" yields
"b+c". If an item is not in the list, the deletion is ignored, for example "a+b-c" yields
"a+b". Parentheses may not be used, and evaluation is strictly left-to-right. For
example, "a-a+b" yields "b" and "a-b-c+b" yields "a+b".
•The "value of" operator, written using the percent character ("%"), may be used to
extract the current value of any control-variable. For example, "%inline+a" yields
the list currently assigned to control-variable inline with the name "a" added to the
list.
•The special token "%all" may be used as a name to denote the set of all possible
names that are applicable for the control-variable to which it is assigned.
Control-Assignments
A value is assigned to a control-variable or a control-group by writing a control-assignment,
which is of the form:
control-variable=control-expression
or
control-group=control-expression
where the control-expression is optional and the "=" is sometimes optional. From the
compiler-invocation command line, such a control-assignment may accomplished with the use
of the -X switch:
-Xcontrol-variable=control-expression
or
-Xcontrol-group=control-expression
To take a simple example, if you wish to assign the value 2 to the control-variable named
mopt, either of the following forms are permissible:
mopt=2mopt2
Note that from the compiler-invocation command line, the -X switch may be used to specify
either of these control-assignments:
-Xmopt=2-Xmopt2
Similarly, if you wish to assign the value 4 to the control-group named O, either of the
following forms are permissible:
O=4O4
Apogee User’s Manual Page 37
Page 38
Apogee Software, Inc.
If the control-expression starts with a name value, the equal sign is required. For example, to
assign the name ansi to the control-variable named c, only the following form is permissible:
c=ansi
The control-expression is optional, and if it is omitted, the "=" must be omitted. Omitting both
of these is an abbreviation for assigning to the control-variable or control-group its seconddefault-value. For example, to assign to control-variable mopt its second-default-value (in this
case, "3"), you need only write:
mopt
Or, to assign to control-group O its second-default-value (in this case "3"), you need only write:
O
Control-Programs
A control-program is written as a sequence of control-assignments.
Within control-programs, blanks may be inserted as desired, with these restrictions:
•blanks can not be inserted within names or numbers, and
•blanks may not be used at all in control-programs that appear on the command line,
because blank is a separator of command line options.
Within control-programs, the control-assignments are usually separated by commas. However:
•Blanks may be used instead of commas when not on the command line, and
•The commas are optional after a control-assignment that ends with an integer constant.
For example, to assign 3 to mopt and to assign joe+pete to inline, any of the following
forms are permissible (blank is denoted by "∆"):
All control-programs are processed left to right, so if duplication of assignment occurs, the
rightmost assignment takes precedence. For example, assume mopt is assigned a value of 4 by
the assignment of 5 to O. Then:
O=5,mopt=2
assigns 2 to mopt, while
mopt=2,O=5
assigns 4 to mopt.
These rules concerning the permissible forms for writing a control-program are summarized in
name-value: := {any string not containing equal, comma, plus, minus or colon, and not
starting with percent or with a numeric digit.}
pair: := name ":" name | name ":" integer-value
plus-op: := "+" | "-"
Writing Pragma Directives
Pragma directives can be written in either C/C++ or FORTRAN 77/90.
In C/C++, the syntax of a pragma directive is:
#pragma apge cprog
Where:
•#pragma is case-sensitive and must start in column 1,
•apge is case-sensitive,
•cprog is a control-program, and
Apogee User’s Manual Page 39
Page 40
Apogee Software, Inc.
•these fields are separated by whitespace.
In FORTRAN 77/90, the syntax of a pragma directive is:
c$pragma apge
cprog
where:
•c$pragma is case-insensitive and must start in column 1 (i.e., it is a FORTRAN 77/90
comment statement),
•apge is case-insensitive,
•cprog is a control-program, and
•these fields are separated by whitespace.
The purpose of the apge token is to identify the pragma directive as being directed at an
Apogee compiler , rather than some other compiler. Without this identification token, now used
by several different brands of compilers, a pragma directed at one compiler may remain
unnoticed in a large program and cause a totally unexpected result on another compiler.
The C/C++ and FORTRAN 77/90 compilers issue diagnostics as follows:
•if the pragma token (#pragma or c$pragma) is recognized, but the apge token is not
present, a remark diagnostic message is issued (see “Diagnostic Control-Variables” on
page 62).
•if the pragma token (#pragma or c$pragma) is recognized and the apge token is
present, but the control-program is malformed, an error is issued.
Page 40 Apogee User’s Manual
Page 41
Chapter 4
Chapter 4Control-Variable
Definitions
This chapter defines and explains the meaning of each control-variable. The explanations are
grouped by classes of control-variables that have related functions.
Chapter 5 (page 105) contains reference tables that list all the control-variables alphabetically
and give the important properties of each one, i.e., the name, abbreviation, scope, type and/or
range of values, first-default-value, second-default-value and a brief (one or two sentence)
explanation of the meanings of the various values that can be assigned to the control-variable.
Read this chapter if you need an explanation of what a control-variable does; consult Chapter 5
if you need a reminder of what a control-variable does. Both chapters also cover controlgroups.
Optimization Control-Variables
The control-variables discussed in this section govern the kind and the extent of the
optimizations performed by the compiler. A subset of these control-variables forms the
variables in the control-group named O.
Introduction to Optimization
The Apogee compilers are highly optimizing compilers,that is they can apply a high degree of
optimization to compiled programs. A non-optimizing compiler does a straightforward,
"obvious" job of translating the source program to a machine language program, so that the
structure of the program (as represented by the computational operations performed and the
logical flow of control) remains unchanged during translation. On the other hand, an
optimizing compiler:
Apogee User’s Manual Page 41
Page 42
Apogee Software, Inc.
1)does a careful analysis of the source program in order to discover various basic
properties of the variables and statements of the program, and then
2)performs a series of transformations called
optimizations on the program so that the
resulting machine language program runs faster but still produces the same answers.
However, the structure of the resulting optimized program may differ very
significantly from the structure of the original source program.
These analyses and optimizations are performed in a sequence determined by the design of the
compiler. In the Apogee compilers, they are intermixed, i.e. some analyses are performed after
some optimizations. Furthermore, some analyses and optimizations are repeated because other
optimizations open up new opportunities.
When being compiled, a routine is divided into units called
basic-blocks before analysis or
optimization is applied. Specifically, a basic block is a sequence of computational operations
which is entered only at the beginning of the sequence and which is exited only at the end of
the sequence (where it can transfer to zero, one, or more than one other basic blocks). For the
optimizer, the important property of a basic block is that if any of the operations of the block
are executed, all of them are executed. Basic blocks are not the same thing as statements in the
source program — each basic block may contain only part of a source statement, or a basic
block may contain several source statements. Consider the following examples:
(FORTRAN)1A = B + C
D = E * F
G = H/I
IF ( A .LE. D ) GO TO 5
. . .
(C)a = b < c ? d + e : f * g ;
The FORTRAN example has 4 statements in a single basic block, while the C example has at
least three basic blocks within one statement.
Analyses or optimizations that are applied by examining and/or changing each basic block
separately are called local analyses or optimizations. Analyses or optimizations that involve
more than one basic block are called global analyses or optimizations. Analysis or
optimizations that involve more than one routine are called interprocedural analyses or
optimizations.
It is worth noting that applying interprocedural analysis to multiple files on the same
command line creates dependencies in the resulting code. If one of the files is changed, then all
must be compiled again. Several control-variables control optimizations which are
interprocedural in nature, and control-group O tends to turn them on at levels of O4 and higher.
Page 42 Apogee User’s Manual
Page 43
Chapter 4: Control-Variable Definitions
Optimization Control-Variables
Control-Variable alias — Alias Analysis
Alias analysis is concerned with the issue of deciding whether two memory references in the
program may possibly reference the same object at run-time. The results of alias analysis are
used at many points throughout the optimizer and affect the results of many different
optimizations. To illustrate this point, consider the following two statements:
X = 4*A*B/(2*C-D)+E*F
Y = M/(N+O-P)-5*Q
If it can be determined that X is a completely different object in memory than any of M, N, O, P,
or Q, then the optimizer is free to compile code which starts the evaluation of the second
expression before the result is stored into X. Also, if Y is different than any of A, B, C, D, E, or F,
then the two statements can be completely interchanged, or if other conditions were met, one
might be hoisted out of a loop even if the other could not be hoisted, etc.
If two memory references can be determined to always refer to distinct objects in memory, we
say the references are independent. If that determination cannot be made, we say the
references possibly interfere. To illustrate the different factors that go into such decisions,
consider the following FORTRAN and C fragments:
REAL X, Y, U(10), V(5)float x,y;
EQUIVALENCE (U(1),V(1))union p{float u[10], v[5]};
. . .float a,b,c,d,e,f,g,h
X = A + Bint i,j;
Y = C - D. . .
. . .x = a + b;
U(6) = E*Fy = c - d;
V(J) = G*H. . .
. . .p.u[5] = e*f;
U(I) = G/Hp.v[j] = g*h;
U(I+1) = E/F. . .
. . .p.u[i] = g/h;
p.u[i+1] = e/f;
. . .
In these programs, it can be seen that:
•the references to X and Y are independent by simply examining the declarations of X
and Y.
•the references to U(6) and V(J) are independent by examining both the declarations
of U and V and the fact that the U subscript is the constant value 6 (with the implicit
assumption that the value of J does not overindex V, which is a restriction applied by
both the FORTRAN and C standards).
•the references to U(I) and U(I+1) are independent if the flow of the program is
examined to establish that the two subscripts have distinct values (for example, there
cannot be an I=I-1 statement between the two statements).
Apogee User’s Manual Page 43
Page 44
Apogee Software, Inc.
The alias control-variable is used to govern the degree of alias analysis performed.
Specifically:
-Xalias=0Alias analysis is not performed. The compiler assumes that all
memory references possibly interfere with all of the other memory
references of the program. This has a severe impact on optimization,
inhibiting most optimizations.
-Xalias=1Alias analysis based on declarations is performed, i.e. the declarations
of the variables used in the references are examined to determine if
interference is possible. The majority of cases of independence are
detected by this level of analysis.
-Xalias=2Alias analysis based on declarations and on constant subscripts is
performed, i.e. non-pointer array references that have differing
constant subscript values in a common subscript position are marked
as independent. Analysis at this level is important for numericallybased programs, particularly those that use multidimensional arrays in
inner loops; it is less important or not useful for other programs.
-Xalias=3 or 4Alias analysis is augmented by use of flow-sensitive considerations in
subscripts. Analysis at this level is important for numerically-based
programs, particularly those that use arrays in inner loops; it is less
important or not useful for other programs. Future product
enhancements will distinguish the 3 and 4 values.
The alias control-variable has routine scope, accepts values of 0 through 4, and is a member
of the O control-group. The first-default-value is alias=1 and the second-default-value is
alias=4.
Call modification analysis is concerned with the issue of determining the set of memory objects
that can be referenced or can be modified as the result of calling a routine. For example, any
variable passed by reference as an argument of a call could be referenced or could be modified
by the called routine. Other examples of variables that could be referenced or modified are any
global variables (C/C++) or any common block variables (FORTRAN 77/90). More esoteric
examples for C/C++ are any variables whose pointers were passed to some called routine on
earlier calls, or any variables that can be pointed to from global variables, etc.
The callmod control-variable is used to govern the degree of call modification analysis
performed. Specifically:
-Xcallmod=0No call modification analysis; assume each call references/modifies
everything.
-Xcallmod=1Intraprocedural call modification analysis, i.e the code of the routine
being called is not examined. The determination is made on the basis
of which objects are available to the called routine and on "worst case"
assumptions about what the called routine might do.
Page 44 Apogee User’s Manual
Page 45
Chapter 4: Control-Variable Definitions
Optimization Control-Variables
-Xcallmod=2Interprocedural call modification analysis, i.e. for each call, the code of
the called routine is examined to determine if it actually references or
modifies the objects available to it. This analysis is only done if it is
possible to determine which routine is being called and if the called
routine is available. (All routines in all files passed to the compiler on
this invocation of the compiler are "available".)
Caution must be used in handling object files produced by crossfile
interprocedural optimization (callmod=2). When multiple source
files are passed to the compiler with callmod=2 enabled, the
resultant object files are dependent on each other for correct
execution. If a change is made to one of the source files, all of the
related files must be recompiled.
The callmod control-variable has routine scope, accepts values of 0 through 2, and is a
member of the O control-group. The first-default-value is callmod=1 and the second-defaultvalue is callmod=2.
Control-Variable cih — Cross-Iteration Hoisting
Cross-iteration hoisting is a term used to describe the motion (or hoisting) of code from one
iteration of a loop to the (dynamically) previous iteration of a loop. Note that since loops wrap
around on themselves, this is not actually moving code from basic-block to basic-block, but
instead is generating values in one dynamic occurrence of a basic-block to be used in a later
dynamic occurrence of the same basic-block. The goal is to increase the separation between
the issuing of long-latency operations (such as loads that are cache-misses) and the use of their
results.
The cross-iteration hoisting optimization is governed by the cih control-variable. Specifically:
-Xcih=0Do not do cross-iteration hoisting.
-Xcih=1Do cross-iteration hoisting.
The cih control-variable has routine scope and accepts values of 0 or 1. The first-defaultvalue is cih=0 and the second-default-value is cih=1.
Control-Variable constp — Constant Propagation
Constant propagation is an optimization that takes constant values assigned to variables and
uses those values instead of the variables where there are uses of the variables with no
intervening assignments to the variables.
The constant propagation optimization is governed by the constp control-variable.
Specifically:
-Xconstp=0Do not do constant propagation.
-Xconstp=1Do local constant propagation.
-Xconstp=2Do global constant propagation.
Apogee User’s Manual Page 45
Page 46
Apogee Software, Inc.
The constp control-variable has routine scope, accepts values of 0 through 2, and is a member
of the O control-group. The first-default-value is constp=0 and the second-default-value is
constp=2.
Control-Variable copyp — Copy Propagation
Copy propagation is an optimization that takes variable values assigned to other variables and
uses those values instead of the other variables where there are uses of these other variables
with no intervening assignments.
The copy propagation optimization is governed by the copyp control-variable. Specifically:
-Xcopyp=0Do not do copy propagation.
-Xcopyp=1Do local copy propagation.
-Xcopyp=2Do global copy propagation.
The copyp control-variable has routine scope, accepts values of 0 through 2, and is a member
of the O control-group. The first-default-value is copyp=0 and the second-default-value is
copyp=2.
Control-Variable domain — Optimization Domain
The main optimizations are done on each routine separately. These optimizations require an
amount of time and memory that goes up dramatically for large routines. Normally the main
optimizations are done over the whole routine. One way to reduce the time and space
requirements of the main optimizations is to do them separately over each of the top-level
loops in the program. For a large program with several top-level loops, this may substantially
cut the time and space requirements for compilation, without significantly degrading the
runtime performance of the resulting program.
The domain control-variable governs this behavior. Specifically:
-Xdomain=0Apply the main optimizations to each outermost loop separately.
-Xdomain=1Apply the main optimizations to the whole routine.
The domain control-variable has routine scope, accepts values of 0 and 1. The first-defaultvalue and the second-default-value are both domain=1.
Control-Variable fcm — Forward Code Motion
Forward code motion is an optimization that moves instructions out of loops in the forward
direction, i.e. moves them forward to a point after the loop. The usual candidates for such
motion are store instructions that do not need to be executed each time through the loop, but
can instead be executed once after the loop.
Page 46 Apogee User’s Manual
Page 47
Chapter 4: Control-Variable Definitions
Optimization Control-Variables
The forward code motion optimization is governed by the fcm control-variable. Specifically:
-Xfcm=0Do not do forward code motion.
-Xfcm=1Do forward code motion for loops without conditional control flow.
-Xfcm=2Do forward code motion for all loops.
The fcm control-variable has routine scope, accepts values of 0 through 2, and is a member of
the O control-group. The first-default-value is fcm=0 and the second-default-value is fcm=1.
Control-Variable flex — Optimization Flexibility
The Apogee compilers are organized as a variety of UNIX processes of different capabilities,
with each compilation process being called by the driver process as appropriate according to
the options and files given on the command line. Some of these processes are capable of a
high-degree of optimization, and some of them do "quick" compilation, without the overhead
of the I/O and the extensive internal data structures that optimization requires.
Most of the optimization control-variables have routine scope, because optimization is usually
done on a routine-by-routine basis, and because that is a logical place for the user to wish to
exercise control.
However, this presents a dilemma. If the driver sees a low compilation level on the command
line, it will start a quick compiler process on a file, and that file may contain a pragma
increasing the compilation level past the capabilities of the process already compiling.
Accordingly, by default, it is a restriction that pragma statements may not increase the
optimization level of any of the control-variables in the O group past the level found on the
command line. The flex control-variable is available to override this restriction. Specifically:
-Xflex=0Assume that none of the control-variables in control-group O will
increase past the values given to them on the command line, so timesaving parts of the compiler that are not capable of performing all
optimizations can be invoked by the driver when indicated by the
options found on the command line.
-Xflex=1Assume that control-variable values in control-group O may increase
past the values given to them on the command line, so slower but
more capable parts of the compiler must be invoked by the driver.
The flex control-variable has compilation scope and accepts values of 0 and 1. The firstdefault-value is flex=0 and the second-default-value is flex=1.
Control-Variable flow — Control Flow Optimization
Control flow optimization improves the control flow of the program. Unreachable code is
eliminated, GOTO's that transfer to GOTO's are collapsed, adjacent basic blocks are merged
when possible, and branches are simplified. Usually these optimizations are only applicable
after other optimizations on the program have occurred, such as the propagation of a constant
into a test condition.
Apogee User’s Manual Page 47
Page 48
Apogee Software, Inc.
An important disadvantage of control flow optimization is that it changes the control structure
of the program so that it may become very difficult to debug the program.
The control flow optimization is governed by the flow control-variable. Specifically:
-Xflow=0Do not do control flow optimization.
-Xflow=1Do control flow optimization.
The flow control-variable has routine scope, accepts values of 0 and 1, and is a member of the
O control-group. The first-default-value is flow=0 and the second-default-value is flow=1.
Control-Variable fltacc — Floating Point Expression
Rearrangement & Numerical Accuracy
Some optimizations of floating point expressions are mathematically equivalent, but are not
necessarily always computationally equivalent. The following are some examples:
Change from:To:
X*Y+X*ZX*(Y+Z)
X/Y/ZX/(Y*Z)
X/2.00.5*X
For most algorithms, these optimizations will not cause a significant change in the accuracy of
the results. For some numerically sensitive algorithms, however, they may degrade the
accuracy of the results.
The ANSI FORTRAN-77 standard permits expression rearrangements of this sort in
FORTRAN 77, so long as any parentheses in the expression are honored. The ANSI C/C++
standard does not permit this sort of expression rearrangement.
If you are using the KAP preprocessor, see the KAP User’s Manual for information on the
roundoff option.
If you are using the VAST preprocessor, see the VAST User’s Manual for information on the
-ea and -gr options.
This aspect of optimization is under the control of the fltacc control-variable. Specifically:
-Xfltacc=0Do no rearrangement of floating point expressions that may change the
result of the expression. This applies to all languages.
-Xfltacc=1In C/C++, do no rearrangement of floating point expressions that may
change the result of the expression, but in FORTRAN 77/90, permit
such rearrangements so long as any parentheses in the expression are
honored.
-Xfltacc=2Permit expression rearrangement, even across parentheses in the
expression. This applies to all languages.
The fltacc control-variable has routine scope and accepts values of 0 through 2. The firstdefault-value is 1, and the second-default-value is 2.
Page 48 Apogee User’s Manual
Page 49
Chapter 4: Control-Variable Definitions
Optimization Control-Variables
Control-Variable fltedge — Floating Point Limits
Floating point values may be either numeric or non-numeric (NaN, INF, etc.). Furthermore,
floating point computations involving non-numeric values may be “signalling” or may be
“quiet”, i.e. they may or may not result in the raising of exceptions, as determined by the rules
of the IEEE Standard 754 and the rules of the target processor.
Optimization may change the behavior of programs that deal with non-numeric values. For
example, if a signalling computation is “dead”, i.e. its result is never used, optimization will
eliminate the computation and the exception will not get raised. As another example, the IEEE
rules require that quiet comparisons involving non-numeric values always yield false, so an
option that eliminated the comparison “A is equal to A” would change the result if A
contained a non-numeric value. In addition, an optimization that changed "A not greater than
B” to “A less than or equal to B” would also change the result if either A or B contained a nonnumeric value.
Some control of this situation is offered by the fltedge control-variable. Specifically:
-Xfltedge=1Do no optimization that changes the behavior of the program if nonnumeric values occur and are used in quiet computations. (The
implementation of this mode is not perfect in the Apogee compilers.
In some cases, comparisons are modified in a way that changes their
behavior. For example, expression (!(a>b)) is changed to (a<=b),
which is incorrect if a and b are unordered.)
-Xfltedge=2Do optimizations that may change the behavior of the program if nonnumeric values occur and are used in quiet computations, but do not
optimize the special case of testing a variable for equality or nonequality to itself. (This mode is provided to permit normal
optimization, but also to provide the ability to program a test for nonnumeric values).
-Xfltedge=3Do optimizations that may change the behavior of the program if nonnumeric values occur and are used in quiet computations.
The fltedge control-variable has routine scope and accepts values of 1 through 3. The firstdefault-value is fltedge=2 and second-default-value is fltedge=3.
Apogee User’s Manual Page 49
Page 50
Apogee Software, Inc.
Control-Variable fltfold — Floating Point Constant Folding
Constant folding is an optimization that evaluates expressions involving constants during
compilation rather than during execution. This optimization may be controlled for floatingpoint constants by the fltfold control-variable, as follows:
-Xfltfold=0During compilation, do not evaluate expressions involving floatingpoint constants.
-Xfltfold=1During compilation, evaluate expressions involving floating-point
constants and arithmetic operators, but do not evaluate expressions
involving intrinsic functions applied to floating point constants.
The fltfold control-variable has routine scope and accepts values of 0 through 2. The firstdefault-value and second-default-value are both fltfold=2.
Control-Variable intedge — Integer Limits
Some optimizations can only be done if it is known that the values are not near the "edge" of
the permissible range of values for the variables involved. For integer variables, this factor is
governed by the intedge control-variable. Specifically:
-Xintedge=0Assume that integer overflow can occur during integer operations. Do
no optimization that would change the program behavior if it does
occur.
-Xintedge=1Assume that the effects of integer overflow during integer operations
can be ignored in applying optimizations.
The intedge control-variable has routine scope and accepts values of 0 and 1. The firstdefault-value is intedge=0 and the second-default-value is intedge=1.
Induction variables are variables that are used for controlling loop iterations, or variables
derived from them. Often in loops many variables are incremented (or decremented) in
parallel as subsequent iterations of the loop are executed. The goal of induction variable
replacement is to reduce the number of such variables, by using some of them for more than
one purpose. This reduces the amount of code in the loop, as well as the number of registers
required, thereby increasing the performance of the loop. Specifically:
-Xivrep=0Do not attempt induction variable replacement optimizations.
-Xivrep=1Attempt to perform induction variable replacement optimizations.
The ivrep control-variable has routine scope and accepts values of 0 and 1. The first-defaultvalue is ivrep=0 and the second-default-value is ivrep=1.
Page 50 Apogee User’s Manual
Page 51
Chapter 4: Control-Variable Definitions
Optimization Control-Variables
Control-Variable memlimit — Scope of Main Optimizations
The process of program optimization requires memory at compile time. Extensive
optimization of large programs may require more (virtual) memory than is permitted to the
compilation job by operating system limits, or than can be reasonably supported by actual
memory of the host computer. In order to provide an alternative to simply using whatever
(virtual) memory is needed, some of the optimizations that require large amounts of memory
estimate their memory requirements in advance and compare it to the value specified by the
memlimit control-variable. Specifically:
-Xmemlimit=
The memlimit control-variable has file scope and accepts integer values. The first-defaultvalue and second-default-values are both 0.
nIf the estimated memory requirement to perform a requested
optimization exceeds
whose estimated requirements do not exceed n megabytes is chosen
instead, and a warning message is issued. n=0 means the compiler
always proceeds with the requested optimizations.
n megabytes, some lower optimization level
Control-Variable mopt — Main Optimizations
A certain collection of optimizations are called the main optimizations in the Apogee
compilers. These are:
•common subexpression elimination,
•backwards hoisting code out of loops, and
•strength reduction and reassociation
These optimizations are achieved in the Apogee compilers by a unified process of backwards
code motion that moves most computations to their "earliest compute points".
The main optimizations are governed by the mopt control-variable. Specifically:
-Xmopt=0Do not do any of the main optimizations.
-Xmopt=1Do the main optimizations locally.
-Xmopt=2Do the main optimizations locally and globally on a flow-free basis.
-Xmopt=3Do the main optimizations globally.
-Xmopt=4Do the main optimizations globally (including strength-reduction and
reassociation for loops with very complex control flow).
The mopt control-variable has routine scope, accepts values of 0 through 4, and is a member
of the O control-group. The first-default-value is mopt=1 and the second-default-value is
mopt=3.
Apogee User’s Manual Page 51
Page 52
Apogee Software, Inc.
Control-Variable reg — Register Allocation
Register allocation is concerned with optimizing the use of the fast registers of the target
processor. This is important because referencing a quantity from a register takes only a fraction
of the time required to reference a quantity from memory. It requires careful attention because
there are typically many more quantities that could be usefully placed in registers than there
are registers to hold them, and the selection of the best subset of these quantities to actually
place in the registers is a very difficult problem.
A few quantities must be allocated to registers, such as the first few parameters when a routine
is called. Beyond that, there are two kinds of quantities that are candidates for being held in a
register:
•Any intermediate value involved in the evaluation of expressions or the execution of
the statements of the language. These include all the subexpressions of the evaluated
expressions, all the quantities involved in addressing expressions, etc.
•Register-candidate variables. In FORTRAN, a variable is a register-candidate variable
if it is a scalar (i.e., not an array or array element, and not a structure or structure
component) and is neither in COMMON nor EQUIVALENCE, nor marked SAVE. In
C/C++, a variable is a register-candidate variable if it is a scalar, has automatic storage
duration, and its address is not taken with the & operator. (The register declaration
is ignored by the Apogee-C and Apogee-C++ compilers.)
Register allocation in the Apogee compilers occurs at three levels: interprocedural (between
routines), global (within one routine), and local (within one basic block).
Interprocedural register allocation is done by a bottom-up traversal of the call-graph tree.
(Where possible, i.e., where caller-callee relationships are known, callee’s are processed before
callers.) This permits the global and local allocation around a call site to take into account the
allocation that has already occurred for the callee. Thus the caller may be able to use registers
that would normally be scratch registers according to the calling convention. Since all floating
point registers are scratch registers on SPARC, the benefit of this scheme can be significant.
Global register allocation is done using a priority-based graph coloring algorithm. A register
interference graph is built to guide the allocation algorithm. Local register allocation is done
after global register allocation.
See the discussion of the sched control-variable for a discussion of the relationship between
register allocation and scheduling.
Many times there will not be enough registers available to hold all of the candidate values. In
this case, spill code will be inserted to move register values to and from memory
The allocation of registers is governed by the reg control-variable. Specifically:
-Xreg=0Do not allocate register-candidate variables to registers.
-Xreg=1Allocate register-candidate variables to registers, and do global and
local register allocation only.
Page 52 Apogee User’s Manual
Page 53
Chapter 4: Control-Variable Definitions
Optimization Control-Variables
-Xreg=2Allocate register-candidate variables to registers, and do
interprocedural and global and local register allocation, but without
reordering routines for interprocedural allocation.
-Xreg=3Allocate register-candidate variables to registers, and do
interprocedural and global and local register allocation, including
reordering routines for interprocedural allocation.
The reg control-variable has routine scope, accepts values of 0 through 3, and is a member of
the O control-group. The first-default-value is reg=0 and the second-default-value is reg=3.
Caution must be used in handling object files produced by interprocedural optimization.
When multiple source files are passed to the compiler with interprocedural optimization
enabled, the resultant object files are dependent on each other for correct execution. If a
change is made to one of the source files, all of the related files must be recompiled.
The ANSI C and C++ standards require intrinsic-routines to do some error checking. For
example, the math routines are expected to set the variable errno on either a domain or range
error, and to provide certain specific values on range overflow or underflow. If intrinsicroutines are inlined, they can be faster if it is known that these checks are not required. In
C/C++, the routine sqrt can only be inlined if the safeintr control-variable is set to the
value 1. For some programs, this speed up can have a significant performance impact.
The safeintr control-variable can be used to inform the compiler that error checking in
intrinsic routines does not need to be done, as follows:
-Xsafeintr=0Assume that the normal error checking must be done in intrinsic
routines.
-Xsafeintr=1Assume that domain or range errors will not occur in intrinsic
routines.
The safeintr control-variable has loop scope and accepts values of 0 and 1. The firstdefault-value is safeintr=0 and the second-default-value is safeintr=1.
Control-Variable sched — Scheduling
Most modern RISC processors have some degree of instruction-level parallelism, i.e. the
execution of certain instructions overlaps in time with the execution of other nearby
instructions. The degree and circumstances of this parallelism vary widely from processor to
processor, but they all have the property that some particular choice of ordering of the
instructions will run faster than other choices. Scheduling is the optimization that reorders
instructions to take advantage of whatever instruction-level parallelism exists on the target
machine. This optimization is naturally very dependent on the specified target machine (see
the pipe control-variable).
Apogee User’s Manual Page 53
Page 54
Apogee Software, Inc.
A classic dilemma for compilers is whether to do scheduling before or after register allocation.
Doing scheduling after register allocation has the effect of constraining the extent of the
reorderings the scheduler can perform. Doing scheduling before register allocation increases
the register pressure and causes more spill code. To deal with this, the Apogee compilers split
up the job. Global register allocation is done first, then one pass of scheduling which takes
register pressure into account, then local register allocation, and finally a second pass of
scheduling (if needed).
Scheduling is governed by the sched control-variable. Specifically:
-Xsched=0Do not schedule instructions.
-Xsched=1Schedule instructions using pass 1 only.
-Xsched=2Schedule instructions using both passes.
The sched control-variable has routine scope, accepts values of 0 through 2, and is a member
of the O control-group. The first-default-value is sched=0 and the second-default-value is
sched=2.
Control-Variable unroll — Loop Unrolling
The loop unrolling optimization takes certain loops and replicates the code in them several
times. This increases the code size, but it also lowers the overhead of testing the loop
conditions and it increases the scope for the application of other optimizations, such as
scheduling.
Only certain loops can be unrolled.
The loop unrolling optimization is governed by the unroll control-variable. Specifically:
-Xunroll=0Do not unroll loops.
-Xunroll=1Unroll loops under automatic control.
-Xunroll=nwhere n>1. Always unroll loops (that can be unrolled), and unroll
them n times.
The unroll control-variable has loop scope, accepts integer values, and is a member of the O
control-group. The first-default-value is unroll=0 and the second-default-value is
unroll=1.
The number of iterations taken by a loop to be unrolled is not usually known during
compilation. Therefore the process of unrolling the loop must account for the possibility of "fixup" executions of the loop body, and must generate code for these executions.
For example, assume a loop is to be unrolled 4 times. This unrolled loop body will then execute
the code of the original loop a number of times that is some integer multiple of 4. However, if
the original loop code called for (say) 15 executions of the loop, the unrolled loop can execute 3
times, accomplishing 12 executions of the original loop body, but there remain 3 executions of
the original loop body that must be done by "fix-up" code.
Page 54 Apogee User’s Manual
Page 55
Chapter 4: Control-Variable Definitions
Optimization Control-Variables
The unrollexact control-variable may be used to inform the compiler that fix-up code is
not necessary, as follows:
-Xunrollexact=0
No assertions are being made about the number of iterations of
unrolled loops.
-Xunrollexact=1
If the value of unroll is greater than 1, the number of iterations
taken by any unrolled loop will always be either zero or an exact
multiple of the value of unroll. When true, this permits the
compiler to use faster code for the unrolled loop. If this is given when
it is not true, program failure is highly probable.
The unrollexact control-variable has loop scope and accepts values of 0 or 1. The firstdefault-value is unrollexact=0 and the second-default-value is unrollexact=1.
Control-Variable whole — Whole Program Compilation
A number of optimizations must make "worst case" assumptions about the parts of the
program that are not visible to the optimizer when it is doing the optimizations. If the whole
program is being given to the compiler on one invocation of the compiler, and the compiler is
informed of this fact, then these optimizations can do a better job.
This information can be given to the compiler by the whole control-variable. Specifically:
-Xwhole=0Do not assume the whole source program is present in this
compilation.
-Xwhole=1Assume the whole source program is present in this compilation,
thereby enabling optimizations which depend on this knowledge.
One of the optimizations performed when whole=1 (and when reg=3) is the use of nonstandard calling sequences. When this optimization is applied, the registers used to pass
parameters to the subroutine are adjusted to the requirements of the subroutine, rather than
being limited to a standard convention.
The whole control-variable has compilation scope and accepts values of 0 and 1. The firstdefault-value is whole=0 and the second-default-value is whole=1.
Control-Variable xopt — Extra Optimizations
A variety of small optimizations that are applicable to only a minority of programs are
available in the compiler as "extra" optimizations that may be enabled by the xopt controlvariable. Specifically:
-Xxopt=0Do not do any extra optimizations.
-Xxopt=nwhere 1 ≤ n ≤ 5. Do various extra optimizations, of an increasing level
of aggressiveness (and with an increasing compilation time
requirement), for increasing values of n.
Apogee User’s Manual Page 55
Page 56
Apogee Software, Inc.
The xopt control-variable has routine scope, accepts values of 0 through 5, and is a member of
the O control-group. The first-default-value is xopt=0 and the second-default-value is
xopt=4.
Control-Variable zone — Expansion of Zones
The definition of a program "zone" and a discussion of the restriction on side-effects within
zones is given in “Side-effects Within a Zone” on page 136. The effect of this restriction is that
the compiler is free to do certain kinds of rearrangement of the order in which subexpressions
are evaluated. As an optimization, this kind of expression rearrangement may also be applied
to wider regions of the program. Specifically:
-Xzone=0Do not do the zone expansion optimization.
-Xzone=1Attempt to expand, beyond single zones, the size of the regions over
which subexpression evaluation order is rearranged.
Please note that use of zone=1 does not imply any additional restrictions on the program other
than zone restriction stated in “Side-effects Within a Zone” on page 136.
The zone control-variable has routine scope and accepts values of 0 and 1 and is a member of
the O control-group. The first-default-value is 0 and the second-default-value is 1.
Control-Variables inline, noinline, deflib, inllev and sinllev —
Routine Inlining
The inlining optimization takes the code of a called routine and inserts it directly into the code
of the calling routine in place of the call. This usually increases the overall code size, but it also:
•Saves the overhead of a subroutine call and return and the passing of parameters.
•Frequently opens up additional optimization opportunities. For example, a subroutine
may be coded to deal with several different cases, with a constant value being passed
to distinguish the cases. Once such a routine is inlined, optimizations such as constant
propagation and control flow optimization may be able to reduce the code to be
executed. As another example, the call may be inside a loop, and once inlined, it may
be possible to move portions of the subroutine outside the loop.
In Apogee-C/C++, both intrinsic and user routines may be inlined. In Apogee-FORTRAN,
only intrinsic routines may be inlined. KAP-C and KAP-F also have inlining capabilities.
VAST-C and VAST-F also have inlining capabilities.
The point in the program at which a routine is called is termed a call site. The decision as to
whether to inline the called routine is made separately at each call site. In other words, the
same routine may be inlined at some call sites, and not inlined at others. The factors that
influence this decision are as follows:
1)Factors from the nature of the called routine:
•Some intrinsic-routines are always inlined, others are not available to the
compiler in an expandable form.
Page 56 Apogee User’s Manual
Page 57
Chapter 4: Control-Variable Definitions
Optimization Control-Variables
•For a user routine, the routine source code may or may not be available. (It is
only available if it is in the same file as the calling routine, but see the join
control-variable.)
•The size of the called routine.
•The number of places from which this routine is called.
2)Factors from the nature of the call site:
•The call may be an indirect one, via pointers in C/C++ or routine parameters
in FORTRAN, so that it is not possible during compilation to determine the
actual routine called.
•The loop nesting level of the call site.
•The size of the calling routine, including any previously inlined routines.
3)The value of the inline control-variable at the call site. This control-variable accepts
a list such that each list member may be either a name or a pair, where the first
member of the pair is a name and the second member of the pair is an integer. If the
name of the called routine occurs in the call site value of the list, it is a candidate for
inlining at this point according to automatic rules in the compiler, which use the
integer value, if it is given, as a priority for the named routine.
4)The value of the noinline control-variable at the call site. This control-variable
accepts a list of names. If the name of the called routine occurs in the call site value of
the list, the routine is not inlined.
5)For intrinsic routines, the value of the deflib control-variable at the call site. This
control-variable accepts the following values:
-Xdeflib=0By default, do not inline intrinsic-routines.
-Xdeflib=1By default, inline intrinsic-routines under automatic
6)For user routines, the call site value of the inllev control-variable. This controlvariable accepts the following values:
-Xinllev=0Do not do inlining of user routines.
-Xinllev=nwhere n is 1 through 5. Do inlining of user routines, with
higher levels indicating increasing levels of
aggressiveness in doing the inlining.
7)The sinllev control-variable is similar to inllev except that it controls routines
declared with the explicit inline specification in the source or routines declared
inside class definitions.
The inline control-variable has line scope and accepts list values as described above. The
first-default-value and the second-default-value are both the empty list.
Apogee User’s Manual Page 57
Page 58
Apogee Software, Inc.
The noinline control-variable has line scope and accepts list values as described above. The
first-default-value and the second-default-value are both the empty list.
The deflib control-variable has line scope and accepts values of 0 through 2. The firstdefault-value is deflib=1 and the second-default-value is deflib=2.
The inllev control-variable has file scope and accepts values of 0 through 5, and is a member
of the O control-group. The first-default-value is inllev=0 and the second-default-value is
inllev=3.
The sinllev control-variable has line scope, accepts values of 0 through 5. The first-defaultvalue is sinllev=3 and the second-default-value is sinllev=5.
Control-Variables profile and pstat — Profiling Feedback to
Inlining
The inlining optimization can be much more effective if it gets accurate information concerning
the relative priority of the routines in the program which might be inlined. One good way to
get this information is to compile the program for profiling (see the prof control-variable),
execute the program with some representative data, and then make the results of this profiling
run available to the optimizer on a second compilation of the program. This can be done with
the pstat and the profile control-variables.
The pstat control-variable accepts a name, which is taken to be the name of a file which
contains the output of a previous profiling run using prof(1) applied to the program now
being compiled. This file is read, and the routine names and the number of times each routine
was called is saved.
The profile control-variable is a special control-variable whose value cannot be set by
writing control-assignments, but is set only when information is read from a profile output file
whose name is given by the pstat control-variable. The value is always an ordered list of
pairs of the form name:frequency, where name is the name of a routine and frequency is an
integer. The current value of profile may be obtained by a reference of the form %profilen,
where n is an integer, which yields the first n pairs of the list. The usual use for the value of
profile is to set the value of the inline control-variable. For example,
-Xinline=%profile20 would set the value of inline to have the names and the relative
priorities as given on the first 20 lines of the pstat file.
An example using these control-variables might be:
In the first line, we compile the program with profiling on (-p) and with general optimization
on (-O), but without inlining (O level below 4). Do not turn on inlining in the first pass, or you
won’t gather data on many of the most interesting routines because they will already be
inlined! Then run the program, to produce a trace of the calls. Next run prof(1) using
arguments to list all functions (including static functions) and sort by number of calls instead of
percentage of runtime. On Solaris 1 (SunOS) use the -a and -n options to prof; on Solaris 2
Page 58 Apogee User’s Manual
Page 59
Chapter 4: Control-Variable Definitions
Target Computer Control-Variables
use the -c and -g options. Note that the output from the prof program is redirected to a file
called PROF.OUT. Finally, we compile the program again. This time we compile without
profiling, but with full optimization including inlining. Further we tell the compiler the name
of the file containing the output of prof, and tell it to inline the top 30 routines.
The pstat control-variable has compilation scope and accepts a name value. The firstdefault-value and the second-default-value are both the null name.
The profile control-variable has compilation scope and accepts only lists of pairs as read
from the pstat file.
Control-Group O — Optimization
For a discussion of control-groups, see “Control-Groups” on page 35. The O control-group
provides a convenient way to set values for those control-variables which govern
optimization, namely the alias, callmod, constp, copyp, fcm, flow, inllev, mopt, reg,sched, unroll, xopt and zone control-variables.
Six levels of optimization are available with O:
-XO=0No optimization.
-XO=1Local optimization only.
-XO=2O=1, plus variables may reside in registers, intraprocedural global
optimization, and scheduling.
-XO=3O=2, plus more extensive global optimizations.
-XO=4O=3, plus interprocedural global optimization and inlining.
-XO=5O=4, plus more extensive inlining and global optimizations.
The values assigned to the member control-variables for each these O values is given in the O
control-group table in “Optimization Group (O)” on page 129.
The first-default-values for the member control-variables are the same settings that are
established by the O=1 assignment. The second-default-value for O is O=3. Note that on the
command line, -O is an abbreviation for -XO=3, and -On is an abbreviation for -XO=n.
Caution must be used in handling object files produced by crossfile interprocedural
optimization. When multiple source files are passed to the compiler with either O4 or O5
enabled, the resultant object files are dependent on each other for correct execution. If a
change is made to one of the source files, all of the related files must be recompiled.
Target Computer Control-Variables
The control-variables discussed in this section specify the properties of the target computer.
The compilers and preprocessors need three different classes of information about the target
computer:
•The instruction set. At the moment, there are four nested levels of implementation of
the SPARC instruction set found in commercially distributed SPARC processors.
Apogee User’s Manual Page 59
Page 60
Apogee Software, Inc.
•The instruction pipeline. The relative timing and overlap relationships between the
various SPARC instructions define the properties of the instruction pipeline in the
SPARC processor. There are many different instruction pipelines, possessing widely
varying properties, found in commercially distributed SPARC processors.
•The cache. There are many different cache implementations, possessing widely
varying properties, found in commercially distributed SPARC systems.
The control-variables cg and pipe are used to specify the instruction set and instruction
pipeline, respectively. The KAP options chs, chl, and sasc are used to specify the cache
properties. All five of these controls are members of control-group T.
Control-Variable cg — Target Computer Instruction Set
The instruction set that the compiler should use is specified by the cg control-variable, with the
following settings:
-Xcg=87Limit compiled instructions to those available on the old SPARC CPUs
without square root. The missing instructions are simulated with
subroutines or with other combinations of instructions. Example: the
SPARCstation-1’s processor.
-Xcg=89Limit compiled instructions to those available on the old SPARC CPUs
with square root but without integer multiply, integer divide, and
floating multiply single to double. The missing instructions are
simulated with subroutines or with other combinations of instructions.
Example: the SPARCstation-2’s processor.
-Xcg=92Limit compiled instructions to those available on the SPARC CPUs that
implement the version 8 architecture specification except for the quad
precision floating point operations. The quad precision operations are
done with subroutines. Examples: microSPARC, SuperSPARC,
hyperSPARC.
-Xcg=94Limit compiled instructions to those available on the SPARC CPUs that
implement the version 9 architecture specification. Example:
UltraSPARC.
SPARC systems are in theory compatible in both directions across differences in instruction set
implementation. This is done by providing, in the operating system, emulation of the newer
instructions when running on the older machines. However, this scheme has the following
ramifications:
•When available in the cpu, the square root, integer multiply, and integer divide
instructions are much faster than the equivalent subroutines. However, when they are
not available in the cpu and must be emulated, these instructions are much slower than
the equivalent subroutines. Most of the time, these instructions do not dominate the
performance-critical sections of a program, so the choice will not have a large
performance impact. There are some programs however, where these instructions are
important enough to have a very significant effect on the performance.
Page 60 Apogee User’s Manual
Page 61
Chapter 4: Control-Variable Definitions
Target Computer Control-Variables
•Use of the new instructions on an old machine creates a dependence on the operating
system. At a minimum, the OS version in use must be recent enough to contain the
proper emulation code. More significantly, this has historically been a problem area,
with a number of known OS bugs.
The cg control-variable has compilation scope, accepts values as shown above, and is a
member of the T control-group. The first-default-value is cg=89 and the second-default-value
is cg=92. Note that on the command line, -cg87 is an abbreviation for -Xcg=87, -cg89 is an
abbreviation for -Xcg=89, and so forth for the other values.
The instruction pipeline that the compiler should assume for the target machine is specified by
the pipe control-variable, with the following settings:
-Xpipe=generic Assume a generic target pipeline.
-Xpipe=iu0fpu0 Assume the target pipeline is the (FJ MB86900, WTL 1 164) chip pair, or
equivalent.
-Xpipe=iu0fpu1 Assume the target pipeline is the (FJ MB86900, WTL 1 167) chip pair, or
equivalent.
-Xpipe=iu1fpu2 Assume the target pipeline is the (FJ MB86901, WTL 3170) chip pair,
or equivalent.
-Xpipe=iu2fpu3 Assume the target pipeline is the (CY 7C601, TI 8847) chip pair, or
equivalent.
-Xpipe=iu2fpu4 Assume the target pipeline is the (CY 7C601, WTL 3171) chip pair, or
equivalent.
-Xpipe=iu2fpu5 Assume the target pipeline is the (CY 7C601, TI 602) chip pair, or
equivalent.
-Xpipe=iu3Assume the target pipeline is the FJ MB86903 chip.
-Xpipe=superAssume the target pipeline is the TI TMS390Z50 (SuperSPARC) chip.
-Xpipe=super2Assume the target pipeline is the SuperSPARC II chip.
-Xpipe=hyperAssume the target pipeline is the CY 7C620 (hyperSPARC) chip.
-Xpipe=microAssume the target pipeline is the TI TMS390S10 (MicroSPARC) chip.
-Xpipe=micro2Assume the target pipeline is the MicroSPARC II chip.
-Xpipe=ultraAssume the target pipeline is the UltraSPARC chip.
-Xpipe=powerup Assume the target pipeline is the Weitek PowerUp chip.
The instruction pipeline information is used by the compiler primarily to schedule
instructions, but is also used to a certain extent in other areas, such as selection and use of
faster instructions when there is a choice.
Apogee User’s Manual Page 61
Page 62
Apogee Software, Inc.
The pipe control-variable has compilation scope, accepts the name values listed above, and is a
member of the T control-group. The first-default-value is pipe=generic and the seconddefault-value is pipe=super.
Control-Group T — Target Computer
For a discussion of control-groups, see “Control-Groups” on page 35. The T control-group
provides a convenient way to specify the instruction set to be used by the compiler (the cg
control-variable), the pipeline implementation of this instruction set which the compiler uses
primarily to schedule instructions (the pipe control-variable), and various cache parameters
used by the KAP preprocessors (the chs, chl and sasc KAP options, specifying cache size (in
K bytes), cache line-length (in bytes), and cache set-associativity, respectively). The cache
parameters are specified for all levels of cache. By specifying the system product name of the
target computer, all of these parameters are set with a single -XT=target switch.
The list of all values, and the values assigned to the member control-variables and KAP options
for each of these T values, is given in the T group table in the section “Target Machine Group
(T)” on page 131. For example, the SPARCstation 2 computer, which supports square root but
does not support integer multiply, uses the (CY 7C601, TI 602) chip pair, has a primary cache
size of 64KB, has a cache line length of 32 bytes, and has a direct mapped cache (no secondary
cache). Thus -XT=ss2 is an abbreviation for:
Giving a correct description of the target computer to the compiler is important in some
situations, but is not important in many situations. When doing performance-critical work on
newer SPARC processors, an accurate specification can be quite important. On older SPARC
processors or when the last few percentage points of performance are not critical, an accurate
specification is not important and the generic value usually suffices.
The compiled programs remain compatible across all SPARC systems, except that there are
bugs in older versions of the SunOS emulation of the -cg92 level of instructions on older
processors.
The first-default-value and second-default-value for the T control-group are generic.
Diagnostic Control-Variables
Each of the diagnostic messages that the compiler can produce is classified into one of the
following categories:
Standard(For FORTRAN only.) A standard message diagnoses some language
usage that the compiler will accept, but that is a violation of the ANSI
standard, i.e., it is one of the accepted language extensions.
RemarkA remark message diagnoses some language usage that the compiler
will accept, but that the compiler regards as unconventional usage.
WarningA warning message diagnoses some language usage that the compiler
will accept, but that the compiler regards as questionable usage.
Page 62 Apogee User’s Manual
Page 63
Chapter 4: Control-Variable Definitions
Diagnostic Control-Variables
ErrorAn error message diagnoses a violation of the syntax or semantics of
the language being compiled. Object code will not be produced, but
compilation will continue past the point of the error for the purpose of
possibly diagnosing additional errors.
Fatal ErrorA fatal error message diagnoses a problem of such severity that the
compilation cannot continue past the point of the error. Object code
will not be produced.
Internal ErrorAn internal error message diagnoses a problem with the logic of the
compiler itself. Internal errors should be reported to the appropriate
support personnel (contact your compiler support supplier). The
source code that created the internal error will need to be reported to
the support personnel so the message can be reproduced.
The response of the FORTRAN compiler to standard messages is controlled by the stddiag
control-variable. The response of both compilers to the other messages is controlled by the
diag and the quit control-variables.
Control-Variable diag — Diagnostic Output Level
The level of diagnostic messages output by the compiler is controlled by the value assigned to
control-variable diag, as follows:
-Xdiag=0Output only error and fatal error messages. Do not output remark or
warning messages.
-Xdiag=1Output only warning, error, and fatal error messages. Do not output
remark messages.
-Xdiag=2Output remark, warning, error, and fatal error messages.
These messages are output on stderr. Note that the error and fatal error messages cannot be
suppressed.
The diag control-variable has line scope and accepts values of 0 through 2. The first-defaultvalue is diag=1 and the second-default-value is diag=2. When a diag=0 assignment is
given, a suppress=w option is generated for KAP. When a diag=0 assignment is given, a
-qw option is generated for VAST. Note that a -w option on the command line is an
abbreviation for -Xdiag=0.
Apogee User’s Manual Page 63
Page 64
Apogee Software, Inc.
Control-Variable quit — Diagnostic Quit Level
The compiler will exit normally (with an exit status of 0) at the end of compilation if it does not
encounter any situation that generates a message. The exit status when diagnostic messages
are encountered is controlled by the value assigned to control-variable quit, as follows:
-Xquit=0Exit abnormally (exit status=1) if error or fatal error message situations
were encountered, exit normally otherwise.
-Xquit=1Exit abnormally (exit status=1) if warning or error or fatal error
message situations were encountered, exit normally otherwise.
-Xquit=2Exit abnormally (exit status=1) if remark or warning or error or fatal
error message situations were encountered, exit normally otherwise.
Notice that these exits are defined in terms of whether the message situation was encountered,
not whether the message was output. The effect of this control is independent of the setting of
control-variable diag.
The quit control-variable has compilation scope and accepts values of 0 through 2. The firstdefault-value is quit=0 and the second-default-value is quit=1.
Control-Variable stddiag — Standard Diagnostics (FORTRAN
only)
The handling of standard messages in the FORTRAN compiler is controlled by the value
assigned to control-variable stddiag. Specifically:
-Xstddiag=0Do not output standard messages, i.e., accept the normal extensions to
the ANSI language without comment.
-Xstddiag=1Output standard messages for (nearly all of) the language situations
encountered that are extensions to the ANSI standard.
-Xstddiag=2Output standard messages for (nearly all of) the language situations
encountered that are extensions to the ANSI standard, and if any such
messages were output, exit abnormally at the end of compilation.
The stddiag control-variable has line scope and accepts values of 0 through 2. The firstdefault-value is stddiag=0 and the second-default-value is stddiag=1.
FORTRAN Source File Format
FORTRAN 77 Statement Format
A wide variety of file formats are now in common use for encoding FORTRAN source
programs. The Fortran 90 standard explicitly codified two forms, as described in "Fortran 90
Statement Format", page 69.
Page 64 Apogee User’s Manual
Page 65
Chapter 4: Control-Variable Definitions
FORTRAN Source File Format
The early FORTRAN compilers all accepted the "classic" fixed-format punched-card-oriented
encoding, namely:
ColumnMeaning
1Comment indicator if C or *.
1..5Statement label (numeric).
6Continuation indicator (indicates initial line if blank, or continuation
line if non-blank).
7..72Statement.
73..80Ignored (usually card sequence number).
Some FORTRAN source files still use this encoding. However, it is not very convenient to use
when preparing terminal input, and new issues are raised on systems like UNIX that have
variable line lengths in files. The response to these issues has been that a newer format which
uses tab characters has come into common use, and a variety of conventions for encoding
source lines in variable length lines have been used by UNIX FORTRAN compilers.
Tab-format lines are identified by the occurrence of a tab character within the first six
characters of a non-comment line. If a line is a tab-format line, the following rules apply:
•A numeric statement label, up to five characters long, can precede the tab character, or
alternately, the statement label can be missing, so the tab character is the first character
of the line.
•If the first character after the tab character is not a digit from 1 through 9, then this is
an initial line, and the statement starts with this first character after the tab character.
•If the first character after the tab character is a digit from 1 through 9, then this is a
continuation line, and the statement continues starting with the first character after
this numeric digit.
There are several obvious ways to encode FORTRAN lines in files with variable line lengths
(and they all appear to have been tried). Some of the issues are:
•There may or may not be non-blank characters at the end of the line that need to be
ignored.
•If there are such characters, they may start at column 73, at column 121, at column 133,
etc.
•If there are such characters, they may or may not be present in fixed-format lines, and
independently, they may or may not be present in tab-format lines.
•Any trailing blanks at the end of the line may or may not have been stripped off in the
conversion from a fixed-format form to a file with variable line lengths.
The various established formats that take different points of view on these issues can be
simulated by appropriate setting of the three control-variables fcols, fblank, and ftab.
The fblank control-variable governs the interpretation of short lines, i.e., lines to which a
nonzero fcols value applies and which do not possess that many characters. The values of
fblank have the following meaning:
-Xfblank=0Do not pad short lines with blanks.
-Xfblank=1Pad each short line with blank characters until it is exactly fcols
characters long before scanning it for statement information. This only
has a meaningful effect if these blank characters form part of the
statement on the line, i.e., they are not just blank characters following
the statement. One example of where trailing blank characters are part
of the statement is when a string with blanks in it wraps around the
end of the line onto a continuation line.
The fblank setting has no significance when fcols=0, and it does not apply to tab-format
lines when ftab=2.
The fblank control-variable has compilation scope, accepts values of 0 or 1, and is a member
of the F control-group. The first-default-value and second-default-value are both fblank=1.
If you are using KAP, you should not use the fblank control-variable. KAP input always
uses the behavior of fblank=1. If you are using VAST, you should not use the fblankcontrol-variable. VAST input uses the behavior of fblank=1, unless -ef is given to allow free
format input..
The fcols control-variable is used to indicate the number of columns scanned for statement
information. Specifically:
-Xfcols=0The whole line is scanned for statement information — no characters in
the line are ignored, regardless of the line length.
-Xfcols=nwhere n>0. Only the first n characters of any line longer than n
characters are scanned for statement information. Characters past this
point are ignored.
The fcols control-variable has compilation scope, accepts any nonnegative integer value, and
is a member of the F control-group. The first-default-value is fcols=72 and the seconddefault-value is fcols=0. If you are using KAP, you should not use the fcols controlvariable. The corresponding KAP option is scan, which can accept values of 72, 120, or 132,
with 72 being the default. See the KAP User’s Guide. If you are using VAST, you should not
use the fcols control-variable. The corresponding VAST options are -gu which sets 132column fixed form input, -g2 which sets 120-column fixed form input, or -ef which is
equivalent to fcols=0.
Control-Variable ftab — FORTRAN Tab Statements
The fcols value always applies to fixed-format lines. It may or may not apply to tab-format
lines, depending on the value of the ftab control-variable.
Page 66 Apogee User’s Manual
Page 67
Chapter 4: Control-Variable Definitions
FORTRAN Source File Format
The ftab control-variable governs tab-format lines. Specifically:
-Xftab=0Tab-format lines are not accepted. They generate an error message.
-Xftab=1Tab-format lines are accepted, but only the first fcols characters of
any tab-format line longer than the fcols value are scanned for
statement information. Characters past this point are ignored. Note
that the visual registration of the cutoff point on a terminal screen
may not agree between tab-format lines and non-tab-format lines. In
both cases, fcols physical characters will be scanned. On non-tabformat lines, this means fcols-6 characters of the statement field will
be scanned, while for tab-format lines, the number of statement field
characters scanned will depend on the length of the label field, the
presence of a continuation character, etc.
-Xftab=2Tab-format lines are accepted, and the whole line is scanned for
statement information. No characters in the line are ignored,
regardless of the line length.
The ftab control-variable has compilation scope, accepts values of 0 through 2, and is a
member of the F control-group. The first and second-default-values are ftab=2. If you areusing KAP, you should not use the ftab control-variable. KAP input always uses the
behavior of ftab=1. If you are using VAST, you should not use the ftab control-variable.
Control-Group F — FORTRAN Statement Format
For a discussion of control-groups, see “Control-Groups” on page 35. The F control-group
provides a convenient way to set values for the fcols, ftab, and fblank control-variables
using mnemonic terms. The values accepted for F are as follows:
-XF=classicWhich means fcols=72, ftab=0, fblank=1. This mode simulates
the "classic" FORTRAN input format, except that it will work if blanks
have been stripped from short lines.
-XF=sun72Which means fcols=72, ftab=2, fblank=1. This mode provides
the SunSoft FORTRAN default mode. This mode is the first-defaultvalue for each of these control-variables and is thus the default mode
of the compiler.
-XF=sun132Which means fcols=132, ftab=2, fblank=1. This mode provides
the SunSoft FORTRAN "-e" mode.
-XF=svs72Which means fcols=72, ftab=0, fblank=0. This mode provides
the SVS FORTRAN 72-column mode, and the MIPS FORTRAN
"-col72" mode.
-XF=svs120Which means fcols=120, ftab=0, fblank=0. This mode provides
the SVS FORTRAN default mode and the MIPS FORTRAN
"-col120" mode.
-XF=normalWhich means fcols=72, ftab=1, fblank=0. This mode will accept
"normal" FORTRAN files, i.e., files without long lines, with or without
sequence numbers, and with or without tab-format lines.
Apogee User’s Manual Page 67
Page 68
Apogee Software, Inc.
-XF=vax72Which means fcols=72, ftab=1, fblank=1. This mode provides
the VAX FORTRAN default mode and the MIPS FORTRAN
"-noextend_source" mode.
-XF=vax132Which means fcols=132, ftab=1, fblank=1. This mode provides
the VAX FORTRAN "/EXTEND_SOURCE" mode and the MIPS
FORTRAN "-extend_source" mode.
-XF=mips72Which means fcols=72, ftab=2, fblank=0. This mode provides
the MIPS FORTRAN default mode.
-XF=unix72Which means fcols=72, ftab=2, fblank=1. This mode works for
files that were originally 72-column fixed-format files, but might have
had some unlimited length tab-format lines added to the file and/or
might have had trailing blanks stripped.
-XF=unixWhich means fcols=0, ftab=2, fblank=1. This mode assumes
there are no characters to be ignored.
The first-default-values for these three control-variables are fcols=72, ftab=2, and
fblank=1, i.e., the same settings that are established by the F=sun72 assignment. The seconddefault-value for these three control-variables are fcols=0, ftab=2, and fblank=1, which is
the same as the F=unix assignment. The second-default-value for F is sun132.
The maximum number of continuation lines permitted for any single FORTRAN statement is
specified by the value assigned to the fcont control-variable. For example, fcont=50 would
permit up to 50 continuation lines.
The fcont control-variable has compilation scope and accepts any integer value greater than
or equal to 19. The first-default-value is fcont=99 and the second default-value is
fcont=200.
Control-Variable fstmt — FORTRAN Statement Buffer
Control-variable fstmt is used in Apogee-FORTRAN to control the size of internal buffers
used during the scanning of FORTRAN statements. It must be given a value that is the larger
of:
•The number of characters in the longest single line in the source file (including
characters that may be ignored because of the fcols setting), and
•The number of characters in the longest single FORTRAN statement in the source file,
including all continuation lines and including any blank characters supplied because of
the fblank setting.
The fstmt control-variable has compilation scope and accepts any integer value greater than
or equal to 4095, subject to memory limitations. The first-default-value is fstmt=4095. The
second-default-value is fstmt=16383.
Page 68 Apogee User’s Manual
Page 69
Chapter 4: Control-Variable Definitions
FORTRAN Source File Format
Control-Variable case — FORTRAN Case Sensitivity
Early FORTRAN was implemented on machines with only one case of letters in their character
set, so the language definition is phrased in terms of only one case of letters. This leaves open
the issue of how to treat identifiers in FORTRAN compilers on systems with both cases of
letters in their character set. The two common solutions are:
•Case-insensitivity. Identifiers are the same if they use the same letters, ignoring the
issue of case, i.e., joe, JOE and Joe are logically all the same identifier.
•Case-sensitivity. Identifiers are the same only if their letters match, including the case
of the letters, i.e., joe, JOE and Joe are all different identifiers.
The case control-variable is used to govern this feature in Apogee-FORTRAN. Specifically:
-Xcase=0Compile with case-insensitive treatment of identifiers.
-Xcase=1Compile with case-sensitive treatment of identifiers.
Any symbols named in CEXTERN statements are treated in a case-sensitive manner regardless
of the setting of case.
The case control-variable has file scope and accepts values of 0 and 1. The first-default-value
is case=0 and the second-default-value is case=1. When a case=1 assignment is given, a
case option is generated for KAP. There is no corresponding option for VAST.
Control-Variable dline — FORTRAN Debug Lines
A feature provided by many FORTRAN compilers is the use of a special character in column 1
to provide a limited conditional compilation facility. The dline control-variable is used to
govern this feature in Apogee-FORTRAN. Specifically:
-Xdline=0Treat lines with D or d or X or x in column 1 as comments.
-Xdline=1Treat lines with D or d or X or x in column 1 as statements to be
compiled.
The dline control-variable has line scope and accepts values of 0 and 1. The first-defaultvalue is dline=0 and the second-default-value is dline=1. When a dline=1 assignment is
given, a dlines option is generated for KAP. When a dline=1 assignment is given, a -dk
option is generated for VAST.
Fortran 90 Statement Format
The Fortran 90 standard explicitly codified two forms of source statement: fixed-form and
free-form. Fixed-form is similar to the column-oriented punch card format described on
page 65. Free-form uses whitespace to separate tokens.
Apogee-Fortran 90 uses a combination of the value of the sform control-variable and the
filename suffix (eg, .f or .f90) to determine whether the source form is processed according
to fixed-form or free-form rules.
Apogee User’s Manual Page 69
Page 70
Apogee Software, Inc.
By default, files with the suffix .f90 are interpreted as being in the new free-form style, and
files with the suffix .f (or equivalently .for) are interpreted as being in the backwardcompatible fixed-form style. This behavior can be explicitly overridden by the sform controlvariable as described in the next section. For description of the interpretation by the compiler
of all recognized suffices, see "Files", page 23.
Control-Variable sform — FORTRAN 90 Statement Format
Fortran 90 defines two source forms: free and fixed. Each input file must be entirely in one
form or the other, though different files using different source forms may be mixed on the
command line.
Fixed source form was defined in the standard to provide backward compatibility with
FORTRAN-77 (and older) programs. Nominally this form limits source lines to 72 column
(unless non-default kind characters are used). Hence this form is similar to that obtained with
-XF=classic as described above.
Free source form permits each source line to contain from 0 to 132 columns and there are no
restrictions on where a statement (or portion thereof) may appear within a line. Blanks and
other whitespace characters are used to separate lexical tokens.
The sform control-variable governs Fortran 90 source form. Specifically:
-Xsform=0Use the suffix of the filename to determine whether fixed- or free-form
source is used. For files with the suffix .f90, free-form source lines
will be assumed. For files with the suffix .f or .for, fixed-form
source lines will be assumed.
-Xsform=1Assume fixed-form source lines, regardless of file suffix.
-Xsform=2Assume free-form source lines, regardless of file suffix.
The sform control-variable has compilation scope and accepts integer values 0 through 2. The
first-default-value is sform=0 and the second default is sform=2.
FORTRAN 77 Compilation
Control-Variable alnstd — FORTRAN Standard
Common/Equivalent Layout
The ANSI FORTRAN-77 standard specifies the data layout that must be used in common
blocks and in equivalence classes produced by the EQUIVALENCE statement. This specification
states that:
•Each integer or real variable occupies one "storage unit".
•Each double precision or complex variable occupies two "storage units", and
•The "storage units" of a common block or equivalence class must be placed in memory
sequentially, with no padding between them.
Page 70 Apogee User’s Manual
Page 71
Chapter 4: Control-Variable Definitions
FORTRAN 77 Compilation
This specification conflicts with the alignment requirements of many target computers, which
require that double precision variables be placed only on double-word boundaries in order to
be accessed via double-word load and store instructions. Consider the following example:
DOUBLE PRECISION D1, D2
INTEGER I
COMMON D1, I, D2
It is impossible for both double precision variables to be aligned on double word boundaries if
only a single word separates them.
One possible response to this situation is to place the variables in memory the way the
standard specifies, but then compile all references to any resulting misaligned variables using
special code that references the variable in smaller pieces (i.e., if a misaligned double-word
needs to be loaded into a register, load each word separately and reassemble the parts in
registers).
This solution meets the requirements of the standard, but it can have an adverse effect on the
speed of the program. In fact, if a misaligned variable is referenced in a tight loop of the
program, the adverse effect can be very significant.
The possibility of this kind of slow-down needs to be balanced against the practical fact that
there are very few programs that would fail to work properly if the compiler was simply to
violate the standard and place an additional word of padding wherever it was needed to avoid
misalignment. (The only programs that would fail when this is done would be programs that
overlaid two different declarations on the same memory area and counted on the
correspondence between these declarations that is specified by the standard.)
Since this sort of failure is so rare, both modes of storage layout are available, governed by the
alnstd control-variable. Specifically:
-Xalnstd=0Deviate from the data layout specified by the ANSI FORTRAN-77
standard for common blocks and equivalence classes by inserting
extra padding whenever necessary to meet the target computer data
alignment requirements. In rare cases, this can cause program failure.
-Xalnstd=1Do the data layout for common blocks and equivalence classes in
strict accordance with the ANSI FORTRAN-77 standard. The
compiled code for referencing any variables thereby misaligned will
be slower; in rare cases it can cause a significant program slowdown.
Also see the related alnref control-variable. If any misaligned data
is referenced indirectly, alnref=0 cannot be used.
The alnstd control-variable has routine scope and permits values of 0 and 1. The firstdefault-value is alnstd=0 and the second-default-value is alnstd=1. Note that pragmatism
won over religious fervor so that strict ANSI compliance is not the default mode of the
compiler on this one point.
Apogee User’s Manual Page 71
Page 72
Apogee Software, Inc.
Control-Variable cmul — Complex multiply
Given the complex multiply (a+ib)*(c+id), the real part is (a*c-b*d). If a*c and b*d are
nearly the same in magnitude, the evaluation of a*c-b*d in the same precision as a may lose
many significant bits from the final result. Improved accuracy can be achieved if the entire
operation is done in a higher precision, with the final result then converted to the original
lower precision. The control-variable cmul provides this capability.
The above issue exists for both single precision and double precision complex multiplies.
However, the control-variable cmul only controls single precision operations. Double
precision operations are always done in double precision despite the potential loss of precision,
because the higher precision (quad) does not exist on current machines as native instructions,
and the cost of doing quad precision by emulation is too high.
-Xcmul=4Do single precision complex multiplies in single precision, in spite of
the potential for loss of significant bits.
-Xcmul=8Do single precision complex multiplies in double precision. This mode
is more costly in terms of runtime performance, even though the
compiler uses the fsmuld instruction in -Xcg92 mode which
combines single-to-double conversion and multiplication in the same
instruction at no extra cost.
The cmul control-variable has line scope and permits values of 4 and 8. The first default-value
is cmul=8 and the second default is cmul=4.
Control-Variable comname — COMMON Block Name Format
The control-variable comname affects the transformation of names of common blocks, in order
to be compatible with different purposes.
As described in the section on “Transformation of Symbol Names” on page 150, there are 4
general classes of global symbols: data and function symbols in C/C++, and data and
subprogram (e.g., function and subroutine) symbols in FORTRAN. The only global data
symbols of interest in FORTRAN are the names of common blocks.
Common block names can interact with each of the other 3 classes of global names in ways
which may be useful at some times and problematic at other times.
Since all FORTRAN programs in UNIX environments are automatically linked with C object
files, the transformation of FORTRAN subprogram and common block names (by default) is
designed to avoid conflict. This preserves a clean global symbol space for FORTRAN
programmers.
In addition, FORTRAN subprogram and common block names may be transformed differently
from each other in order to permit a programmer to use the same name for a subprogram and a
common block. Some old programs require this, as they sometimes did use the same names in
this manner in an environment which always distinguished between common block symbols
and subprogram symbols.
Sometimes, however, when a programmer is explicitly trying to combine objects written in C
with objects written in FORTRAN, this default transformation becomes a problem.
Page 72 Apogee User’s Manual
Page 73
Chapter 4: Control-Variable Definitions
FORTRAN 77 Compilation
Other interactions occur when developers wish to combine object files compiled with one
compiler with object files compiled with another compiler. Obviously the same name
transformation rules must be used by both compilers in order to obtain the expected behavior.
These conflicting situations necessitate the existence of the control-variable comname.
By default, common block names are transformed in the same manner as FORTRAN
subprogram names. If a programmer wishes to use the same name for a FORTRAN
subroutine or function as for a common block, a non-default value of the control-variable
comname is required. Which non-default value to use depends on what other effects the
programmer is trying to achieve.
If the programmer wishes to disambiguate common block names from all 3 other classes of
names by using a unique transformation, comname should be set to the value 2. When the
user specifies -Xcomname=2, common block names have a dollar sign (’$’) appended to the
end of the symbol name. If a C programmer needs to reference this data symbol, this can
cause a problem. ANSI-C does not permit the dollar sign character in symbol names, although
some older non-ANSI compilers do permit dollar signs. (Apogee-C permits dollar signs in
symbol names except in strict ANSI mode.)
Users who wish to reference FORTRAN common block names in C programs which cannot
use dollar signs in symbol names should compile their FORTRAN code with -Xcomname=0,
in order to suppress the dollar sign. When compiling in this mode, the transformation used
for common block symbols is the same as the transformation used for global data symbols in
C, permitting programmers to reference a common block named, for example, "cbname" as a C
extern data object (much like a C struct) with the name "cbname".
-Xcomname=0Apply the name transformation for C global data symbols to common
block names.
-Xcomname=1Apply the name transformation for FORTRAN global function
symbols to common block names. Note that this can cause a conflict if
a common block and a function have the same name.
-Xcomname=2Apply the name transformation of FORTRAN global data symbols to
common block names. The data symbol transformation is guaranteed
to avoid name conflicts with FORTRAN function names.
The comname control-variable has file scope and permits values of 0, 1 or 2. The first and
second default-values are both comname=1.
Control-Variable ftype — FORTRAN Types
A common request of FORTRAN users is for a way to change the compiled precision of the
numeric types declared in the program, without making any source code changes. For
example, the user may wish to compile the program so that REAL variables are treated by the
compiler as DOUBLE PRECISION. Some of the reasons for requests of this nature are:
•The user wishes to experiment with the numeric stability (or other numeric property)
of the algorithm.
•The user wishes to benchmark the performance of the program using different
numeric precisions.
Apogee User’s Manual Page 73
Page 74
Apogee Software, Inc.
•A program is being ported between machines that have different numeric precisions.
However, there are some complexities to requests of this nature. For example:
•Just which kinds of declarations should have their compiled meanings changed? For
example, if you want to change REAL to DOUBLE PRECISION, do you mean to change
just those variables declared REAL, or also to change those variables declared REAL*4?
In a program where different programmers with different styles of writing declarations
have been coding, you probably want to change both. On the other hand, in a program
where precision-sensitive portions have been coded using REAL*4 and non-precisionsensitive portions have been coded using REAL, you probably only want to change
REAL.
•What about association via COMMON or EQUIVALENCE? Changing types in this manner
may cause some programs that counted on particular patterns of association to fail.
Consider the following program fragment:
INTEGER A(10), J
REAL X
COMMON /B/ X, J
EQUIVALENCE (A(1), X)
Under the normal interpretation, A(2) and J will be associated and the program may
count on this for correct behavior. However, if REAL is compiled as DOUBLEPRECISION, the increased size of X causes this to no longer be true, and the program
may fail.
•What about the type of constants? What about the type of function return values?
What about the types assigned by the IMPLICIT statement? In all of these cases it
seems likely the user would wish a change comparable to that applied to variables.
The scheme used in Apogee-FORTRAN is to:
•Permit a fairly detailed specification of the interpretation to be placed on each of the
different kinds of integer, logical, and floating-point type declarations, so that issues
like REAL vs. REAL*4 can be handled explicitly by the user.
•Treat function return values and the types assigned by the IMPLICIT statement the
same way as variables of the same type.
•Treat REAL constants the same way as REAL variables are treated.
•Treat DOUBLE PRECISION constants the same way as DOUBLE PRECISION variables
are treated.
•Treat constants with an Q exponent the same way as REAL*16 variables are treated.
•Permit integer types to be given sizes as large as 8 bytes, but treat an 8-byte integer in a
"4 in 8" manner, i.e. 8 bytes are allocated in memory, but only four of the bytes are used
to carry the integer.
•Leave COMMON/EQUIVALENCE association alone, since there is nothing obvious and
systematic that can be done. Note that since integer types can be changed, the above
example can be handled explicitly.
Page 74 Apogee User’s Manual
Page 75
Chapter 4: Control-Variable Definitions
FORTRAN 77 Compilation
The ftype control-variable is used to govern the interpretation to be placed on each of the
declared types in the program. Each of the possible types is given an abbreviated name (e.g. r
denotes real, r4 denotes real*4, etc.), and ftype accepts a list of pairs, the first member of
the pair being an abbreviated name, and the second member being the precision the compiler
should apply to that type. Specifically, the list members may be any of the following:
nCompile variables declared as real using length n, n=4|8|16, 1st
r:
default 4, 2nd default 8.
r4:
nCompile variables declared as real*4 using length n, n=4|8|16, 1st
default 4, 2nd default 4.
d:nCompile variables declared as double precision using length n,
n=4|8|16, 1st default 8, 2nd default 16.
r8:nCompile variables declared as real*8 using length n, n=4|8|16, 1st
default 8, 2nd default 8.
r16:nCompile variables declared as real*16 using length n, n=4|8|16,
1st default 16, 2nd default 16.
i:nCompile variables declared as integer using length n, n=1|2|4|8,
1st default 4, 2nd default 8, where 8 means "4 in 8".
i1:nCompile variables declared as integer*1 using length n,
n=1|2|4|8, 1st default 1, 2nd default 1, where 8 means "4 in 8".
i2:nCompile variables declared as integer*2 using length n,
n=1|2|4|8, 1st default 2, 2nd default 2, where 8 means "4 in 8".
i4:nCompile variables declared as integer*4 using length n,
n=1|2|4|8, 1st default 4, 2nd default 4, where 8 means "4 in 8".
l:nCompile variables declared as logical using length n, n=1|2|4|8,
1st default 4, 2nd default 8, where 8 means "4 in 8".
l1:nCompile variables declared as logical*1 using length n,
n=1|2|4|8, 1st default 1, 2nd default 1, where 8 means "4 in 8".
l2:nCompile variables declared as logical*2 using length n,
n=1|2|4|8, 1st default 2, 2nd default 2, where 8 means "4 in 8".
l4:nCompile variables declared as logical*4 using length n,
n=1|2|4|8, 1st default 4, 2nd default 4, where 8 means "4 in 8".
Complex variables are not included in the above list because they are always composed of two
parts following the normal FORTRAN rules. Specifically:
•Variables declared complex have the rules of real applied to each half.
•Variables declared double complex have the rules of double precision applied
to each half.
•Variables declared complex*n have the rules of real*m applied to each half, where
m=n/2.
Apogee User’s Manual Page 75
Page 76
Apogee Software, Inc.
The effect of several options from SUN FORTRAN can be accomplished with the ftype
control-variable as follows:
Sun optionApogee equivalent
-i2-Xftype=i:2+l:2
-i4(1st default, specifically -Xftype=i:4+l:4)
-r4-Xftype=d:4
-r8-Xftype (2nd default, e.g., -Xftype=r+d+i+l or equivalently,
-Xftype=r:8+d:16+i:8+l:8)
The ftype control-variable has routine scope and permits values which are lists of pairs, as
specified above. The first-default-value is the null-list and the second-default-value is
r+d+i+l.
Apogee-FORTRAN supports the NONE option of the IMPLICIT statement, as defined by the
MIL-STD 1753 extension to FORTRAN. If present in a routine, this statement requires that all
FORTRAN variables be explicitly declared, rather than acquiring a type by the implicit
declaration mechanism of FORTRAN. This concept matches most post-FORTRAN languages,
and is frequently convenient during program development or modification. A number of
UNIX systems offer the additional capability of applying this restriction from the command
line. Apogee-FORTRAN supports this capability via the -u command line flag and the
implicit control-variable. Specifically:
-Ximplicit=0The program is processed as if an IMPLICIT NONE statement were
present, whether or not there is actually one present.
-Ximplicit=1The program is processed normally.
The implicit control-variable has routine scope and permits values of 0 and 1. The firstdefault-value is implicit=1 and the second-default-value is implicit=0. Note that -u on
the command line is an abbreviation for -Ximplicit=0.
Control-Variable onetrip — One-Trip DO Loops in FORTRAN
In FORTRAN-77, the number of trips through each DO loop is dictated by the loop conditions.
If they indicate that no executions of the loop are to be done, then none are done. In
FORTRAN-66, all DO loops are defined to execute at least once, even if the loop conditions
indicate that no executions of the loop are to be done.
Any DO loop will fall into one of the following categories:
1)The loop conditions never indicate a zero trip count.
2)When the loop conditions indicate a zero trip count, the program works whether either
zero or one trips of the loop take place.
3)When the loop conditions indicate a zero trip count, the program depends (for correct
behavior) on the fact that zero executions take place.
Page 76 Apogee User’s Manual
Page 77
Chapter 4: Control-Variable Definitions
FORTRAN 77 Compilation
4)When the loop conditions indicate a zero trip count, the program depends (for correct
behavior) on the fact that one execution does take place.
Loops of types 1, 2 and 4 will work when the compiler implements FORTRAN-66 behavior,
while loops of types 1, 2, and 3 will work when the compiler implements FORTRAN-77
behavior. A compiler can only support both type 3 and type 4 loops by offering both kinds of
behavior. This is governed in Apogee-FORTRAN by the control-variable onetrip.
Specifically:
-Xonetrip=0The loop will execute zero times when the trip count is zero (the
FORTRAN-77 language).
-Xonetrip=1The loop will execute once when the trip count is zero (the
FORTRAN-66 language).
Use of onetrip=1, where it is known there are no type 3 loops, also offers a small
performance advantage. (Use of onetrip=1, where there are some type 3 loops, will give
program failure, just as use of onetrip=0, where there are some type 4 loops, will also give
program failure.)
The onetrip control-variable has loop scope and permits values of 0 and 1. The first-defaultvalue is onetrip=0 and the second-default-value is onetrip=1. When a onetrip=1
assignment is given, a onetrip option is generated for KAP. When a onetrip=1 assignment
is given, a -eo option is generated for VAST.
Control-Variable save — SAVE Variables in FORTRAN
FORTRAN SUBROUTINEs or FUNCTIONs may be coded to expect that values placed into
local variables during one invocation of the routine will still be intact in these same variables
after the routine exits and is then re-invoked. This programming convention is termed saveusage for the variables in question.
Save-usage is fairly common in older FORTRAN programs for the simple reason that it always
worked in early FORTRAN implementations because such implementations used static
allocation for local variables. However, save-usage is not permitted in ANSI FORTRAN-77
unless either:
•each variable so used is named in a SAVE statement in the routine, or
•the routine has a "global" SAVE statement, i.e. one that names no variables, and thus
applies to all local variables.
Because of these rules, all programs with undeclared save-usage are nonstandard.
Furthermore, since either a stack-based or a register-based allocation of local variables is
typically faster on modern RISC computers, most modern FORTRAN implementations have
shifted away from a static allocation of local variables, thus causing such programs to fail.
In addition to explicit SAVE statements, the save control-variable may be used to supply an
implicit global SAVE statement, as follows:
-Xsave=0Do not provide an implicit global SAVE statement.
-Xsave=1Provide an implicit global SAVE statement, whether or not any SAVE
statements are already present.
Apogee User’s Manual Page 77
Page 78
Apogee Software, Inc.
In addition to the save control-variable, Apogee-FORTRAN implements IMPLICIT SAVE and
IMPLICIT AUTOMATIC statements to allow users a greater degree of control (see the Apogee-
FORTRAN Reference Manual for a description of these statements). These mechanisms
interact to allocate variables to one of three states: in a register, on the stack, or statically,
according to the rules below. In order to simplify the description below, variables can attain an
intermediate state called "marked as saved". The rules are:
•All variables in common blocks are allocated statically.
•All variables initialized via a DATA statement are allocated statically
•Arrays and structures in the main program are allocated statically.
•All local variables named in a SAVE statement are marked as saved. It is an error for
any of these variables to also appear in an AUTOMATIC statement.
•All local variables whose names start with a letter in an IMPLICIT SAVE statement,
except those that appear in an AUTOMATIC statement, are marked as saved.
•If an explicit or implicit global SAVE statement occurs in the routine, all local variables
are marked as saved, except for those variables named in AUTOMATIC statements, or
whose names start with a letter in an IMPLICIT AUTOMATIC statement.
•Certain local variables are considered to be register-candidates (see the description of
the reg control-variable). For such variables, a flow analysis is done to determine if
there are any control-flow paths in the routine that could possibly lead to a use of the
variable without a preceding definition of the variable. If there is such a path, and if
the variable is marked as saved, then it is given a static allocation, otherwise it is given
a register-based allocation. (And, if there is such a path and the variable is not marked
as saved, a warning message is issued.)
•Non-register-candidate variables are given a static allocation if they are marked as
saved, otherwise they are given a stack-based allocation.
The implications of these rules are as follows:
•Local variables will get either a register-based or a stack-based allocation unless they
get marked as saved. Thus undeclared save-usage will probably cause program failure
with Apogee-FORTRAN.
•Register-candidate variables marked as saved will get static allocation if there is any
possibility of save-usage, but they will get register-based allocation otherwise, despite
being marked as saved.
•Since local arrays will usually be given stack allocation, there is a possibility that a
program with extremely large local arrays will exceed the operating system limit on the
size of the stack.
KAP also has an option affecting save-usage, the save option. Check the KAP manual for
details. Any insertion of SAVE statements done by KAP will appear to the compiler exactly as
if they had occurred in the original program.
Page 78 Apogee User’s Manual
Page 79
Chapter 4: Control-Variable Definitions
FORTRAN 77 Compilation
When KAP is used in memory-management mode, it will sometimes move local variables into
a common block, for the purpose of optimizing the use of the processor data cache. This will
result, of course, in the compiler giving such variables a static allocation.
VAST also has an option affecting save-usage, the -xon=t option. See the VAST manual for
details. Any insertion of SAVE statements done by VAST will appear exactly as if they had
occurred in the original program.
When VAST is used in memory-management mode, it will sometimes move local variables
into a common block, for the purpose of optimizing the use of the processor data cache. This
will result, of course, in the compiler giving such variables a static allocation.
If you suspect that undeclared save-usage is present in a program, the best remedy is to
inspect the logic of the program, discover which variables expect values to be preserved across
invocations in this fashion, and then name all of these variables in a SAVE statement. This
gives you a standard-conforming program and a program that is most likely to give good
performance with most FORTRAN compilers.
If the resources to do this inspection are not available, the second best remedy is to choose one
of the following options:
•Place an explicit global SAVE statement into the routine.
•Set the control-variable save to 1 for the routine.
Both of these options are less desirable than selective SAVE statements because they will
typically have a larger performance impact. The first option is better than the second because
it makes the program comply with the standard. The only real advantage of the second option
is that it can be given on the command line, and thus does not require any modification of the
source files. It is also a quick way to see if undeclared save-usage is the problem when you are
experiencing program failure on a program being moved to Apogee-FORTRAN from a
compiler that uses static allocation for local variables (for example, SUN FORTRAN).
Notice that recursion is a related topic. Most recursive algorithms would expect a local
variable given a value in a routine to retain that value across a call, even if that call caused
another invocation of this same routine to assign a different value to the variable. This
convention is termed recursive-usage of the variable in question. Stack-based and registerbased allocation of a variable permit recursive-usage, but static allocation does not. See
“Recursion (FORTRAN)” on page 142 for a discussion of recursion in Apogee-FORTRAN.
One side aspect of static versus automatic (stack) allocation is apparent on Solaris 2 systems.
By default the maximum stack size allowed is 8MB or so, in order to cause termination of
programs with infinite recursion bugs before they exhaust the system of virtual memory. The
problem occurs when large arrays in Fortran programs are given automatic (stack) allocation;
it is easy for large arrays (or several smaller arrays in different routines) to exceed the Solaris
limit. Forcing static allocation of (some of) these arrays can work around the problem.
The save control-variable has routine scope and accepts values of 0 or 1. The first-defaultvalue is save=0 and the second-default-value is save=1. When a save=1 assignment is
given, a save=all option is generated for KAP. When a save=1 assignment is given, a
-xon=t option is generated for VAST.
Apogee User’s Manual Page 79
Page 80
Apogee Software, Inc.
Control-Variable vms — VAX/VMS Compatibility
Most of the FORTRAN extensions implemented in VAX/VMS FORTRAN are compatible
extensions. (See Chapter 7). For a few items, however, the VAX/VMS FORTRAN behavior is
incompatible with either the ANSI FORTRAN 77 standard or with usual UNIX FORTRAN
behavior or with SUN FORTRAN behavior. The behavior of Apogee-FORTRAN for these items
is governed by the vms control-variable., which accepts a list of names, as follows:
-Xvms=reclIn FORTRAN, when recl is included in the value of vms, for the
RECL=s specifier of either the OPEN or INQUIRE statements, s is
interpreted as the number of bytes in the record if the file is formatted,
or as the number of 4-byte words if the file is unformatted. (Note that
this behavior is VAX/VMS compatible, but is not quite compatible
with SUN FORTRAN under -xl mode, which does not deal with the
INQUIRE statement nor with the case where the
formatted/unformatted distinction is dynamic).
-Xvms=quoteIn FORTRAN, when quote is included in the value of vms, the
double-quote character is interpreted as the start of an integer constant
written in octal notation. Without vms=quote, the double-quote
character is interpreted as a string delimiter.
-Xvms=bslashIn FORTRAN, when bslash is included in the value of vms, the
backslash character (\) in strings is interpreted as denoting itself.
When bslash is omitted from the value of vms, the backslash
character (\) in strings is interpreted by UNIX conventions, i.e. it is an
escape character.
-Xvms=paramIn FORTRAN, when param is included in the value of vms, the
alternate PARAMETER statements are accepted (without enclosing
parentheses and where the types are determined by the constants).
When param is omitted from the value of vms, only ANSI-style
PARAMETER statements are accepted (with enclosing parentheses and
where the types are determined by the names).
The vms control-variable has line scope and accepts values which are lists containing one or
more of the following names: recl, quote, bslash, and param. The first-default-value is the
null list, and the second-default-value is recl+quote+bslash+param.
Note that to support VMS compatibility, some library routines are provided in two forms.
For example, a FORTRAN subroutine named IDATE exists in two forms (the default form
which accepts one argument: an integer array argument of three elements for day, month,
and year; and a VMS-compatible form which accepts three integer scalar arguments:
month, day, and year). To use the VMS-compatible version of a FOR TRAN library routine,
the Apogee VMS-compatible library must be requested explicitly at link-time by using the
switch -laV77, which will be passed to the link editor.
Page 80 Apogee User’s Manual
Page 81
Chapter 4: Control-Variable Definitions
C/C++ Compilation
C/C++ Compilation
Control-Variable c — C/C++ Language Modes
Apogee-C/C++ has six basic modes, three of which specify and govern the C dialect accepted
by the compiler, three of which specify and govern the C++ dialect accepted by the compiler.
These modes are controlled the c control-variable, as follows:
-Xc=ansiIn this mode, the compiler complies completely with the ANSI C
standard (ANSI X3.159-1989) as a "conforming hosted
implementation", i.e., it supports all of the standard header files.
-Xc=knrIn this mode, the compiler is largely compatible with the definition of
the C language as given in "The C Language" by Kernighan & Ritchie
and is closely compatible with the UNIX pcc compiler.
-Xc=mixedIn this mode, the compiler is essentially an ANSI compiler, except that
a few extensions are added to ease the job of porting existing K&R
code to ANSI. See Chapter 8 for a discussion of these extensions.
-Xc=armIn this mode the compiler accepts the C++ language as defined in The
Annotated Reference Manual
and will track the ANSI standard being developed.
-Xc=cpSimilar to arm, except that it allows for several anachronisms and is
less restrictive. Programs that compile under both arm and cp modes
will behave identically.
-Xc=cfrontIn this mode, the compiler accepts the C++ language accepted by
AT&T Cfront Compiler and generates compatible object code. This
option can take an additional value of either :21 or :30.
-Xc=cfront:21 enables compatibility with AT&T Cfront 2.1, while
-Xc=cfront:30 enables compatibility with AT&T Cfront 3.0.
-Xc=cfront is equivalent to -Xc=cfront:30.
In addition to these six basic modes, any subset of the three names const, volatile, and
signed may be added to the value of control-variable c, forming a list value. When the basic
mode is c=knr, the use of any of these names indicates that the corresponding qualifier in the
ANSI C language is to be recognized. For example, c=knr+const+volatile indicates K&R
compatibility, but with the const and volatile type qualifiers of ANSI C also recognized.
An additional value, noknr, can be added to the mixed or ansi C modes (for example,
-Xc=mixed+noknr). This value causes the compiler to emit warnings on declarations and
definitions of any function without a prototype. When noknr mode is enabled, a warning is
also emitted when the compiler encounters a use of a function that has not been previously
declared or defined.
An additional value inline may be given with all of the C modes. The default is "off" which
tells the compiler to not recognize inline as a keyword. To enable recognition of inline in
C programs as a keyword, add inline from control-variable c (for example,
-Xc=mixed+inline). Note that inline is always recognized as a keyword in C++ modes.
by Margaret A. Ellis & Bjarne Stroustrup,
Apogee User’s Manual Page 81
Page 82
Apogee Software, Inc.
An additional value c_func_decl can be given along with the arm, cp and cfront C++
modes. This value relaxes the prototype requirements of the C++ language to those of the C
language for functions declared within an extern "C" block. This value is not meant for
direct use in user code, but is meant to enable the use of C style system include files in the C++
environment.
An additional value stdlib can be given with all of the C++ modes. If stdlib is added to the
control-variable value (for example, -Xc=arm+stdlib) the compiler will use a templatized
version of include files and library. The behavior of the include files is changed by adding a
-D__STDLIB on the command-line as an additional pre-defined preprocessor macro (for other
predefined macros, see the appendix specific to your computer). Objects compiled with
stdlib are generally not compatible with objects compiled without stdlib due to differences
in the include files. The default is as though stdlib has not been added to the control-variable
value.
An additional value array_nd can be given with all of the C++ modes. The default is "on"
which tells the compiler to recognize array new and array delete operators. To disable
recognition of array new and array delete, subtract array_nd from control-variable c (for
example, -Xc-=array_nd or -Xc=arm-array_nd).
An additional value rtti can be given with all of the C++ modes. The default is "on" which
tells the compiler to recognize RTTI (runtime type identification) keywords, thus enabling RTTI
behavior. To disable RTTI, subtract rtti from control-variable c (for example, -Xc-=rtti or
-Xc=cp-rtti).
An additional value wchar_t may be given with all of the C++ modes. The default is "on"
which tells the compiler to recognize wchar_t as a keyword, and also to add -D_WCHAR_T
and -D__WCHAR_T_IS_KEYWORD as built-in predefined preprocessor macros. The former
macro is used in various include files provided by the compiler to ensure that at most one
definition of the wchar_t type is seen. The latter macro is provided for you to protect your
code which depends on wchar_t being a distinct C++ type, such as when instantiating a
template for all built-in types. To disable recognition of wchar_t as a keyword (and distinct
type) subtract wchar_t from control-variable c (for example, -Xc-=wchar_t). See also the
description of control-variable wchart on page 84. Note the distinction between wchart
which is a control-variable affecting the type used to store wchar_ts, and wchar_t which is
value for the c control-variable affecting whether wchar_t is a typedef or a distinct built-in
type..
An additional value bool may be given with all of the C++ modes. The default is "on" which
tells the compiler to recognize bool as a keyword, and also add -D_BOOL_DEFINED and
-D__BOOL_IS_KEYWORD as built-in predefined preprocessor macros. The former macro can
be used to protect your own definition of bool, perhaps as follows
The latter macro is provided for you to protect your code which depends on bool being a
distinct C++ built-in type, such as when instatiating a template for all built-in types. To
disable recognition of bool as a keyword, subtract bool from control-variable c (for example,
-Xc=cp-bool).
An additional value old_for_init may be given with all of the C++ modes. In releases of
Apogee-C++ before 4.0, the default for old_for_init was on, giving the behavior provided
by cfront (where the scope of variables declared in init statements of for loops was larger
than the scope of the loop). As of release 4.0, the default in cfront mode remains on, but in
cp and arm modes the default is now off, which tells the compiler to limit the scope of
variables declared in init statements of for loops to the scope of the loop itself. This is as
required by the latest drafts of the Standard. If your code assumes the larger scope of the
variables, and you otherwise want to use cp or arm modes, you will need to add this value to
control-variable c (for example, -Xc=cp+old_for_init).
An additional value exceptions may be given with all of the C++ modes. In releases of
Apogee-C++ before 4.0, the default for exceptions was off. As of release 4.0, the default in
cfront mode remains off, but in cp and arm modes the default is now on, which tells the
compiler to generate all necessary data structures to support the use of C++ exceptions. This
protects your code (even if it does not use exceptions) if other code throws an exception across
your code. If you know that your code will run in an exception-free environment, you may
disable exceptions by subtracting it from control-variable c (for example,
-Xc-=exceptions) to completely eliminate the impact of exceptions on your code. For
further discussion of exception handling, see “Exception Handling” on page 161.
The c control-variable has file scope and accepts name values of ansi, knr, const,
volatile, signed, mixed, arm, cp, cfront, noknr, stdlib, array_nd, rtti, wchar_t,
bool, inline, old_for_init, or exceptions. The first-default-value for apcc is
c=mixed and the second default value is c=ansi. The first default-value for apCC is c=cp,
and the second-default-value is c=arm. Note that -K on the command line is an abbreviation
for -Xc=knr.
Control-Variable char — Signedness of plain char in C/C++
ANSI C/C++ has three different character types, char, signed char, and unsigned
char. It is clear from the standard that these are three distinct types for purposes such as
determining if two expressions have the same type. However, the standard leaves as
"implementation-defined" the issue of whether quantities declared as type char are to be
implemented with a representation that has a sign bit or not. In Apogee-C/C++, this choice is
governed by the value of the control-variable char. Specifically:
-Xchar=signedThe representation for char is the same as signed char.
-Xchar=unsignedThe representation for char is the same as unsigned char.
Bit fields of type int are similarly left "implementation-defined" in ANSI C/C++. ApogeeC/C++ uses signed int unless the bit field is only one bit, in which case unsigned int is
used.
The char control-variable has file scope and accepts name values of signed or unsigned.
The first and second-default-values are signed.
Apogee User’s Manual Page 83
Page 84
Apogee Software, Inc.
Control-Variables sizet and wchart — Definitions of types size_t
and wchar_t in C/C++
There are situations in C and C++ where the compiler must know information about the types
size_t or wchar_t, even if they are not defined. Therefore, the compiler has a built-in
expectation of the manner in which these types are going to be defined, if at all. A mismatch
between the compiler’s expectation and the definition in a program can cause incorrect
behavior.
Normally, these types are defined in one or more system include files. The compiler’s built in
expectations have been set to match the definitions in standard system include files under the
Solaris 1 and Solaris 2 environments. However, if for any reason a nonstandard set of system
include files is being used, the options below can change the compiler’s built-in expectations to
match the setting in the include files.
The sizet and wchart control-variables can have the following values:
-Xsizet=uintThe definition for size_t is unsigned int.
-Xsizet=ulongThe definition for size_t is unsigned long.
-Xsizet=ushort The definition for size_t is unsigned short.
-Xwchart=uintThe definition for wchar_t is unsigned int.
-Xwchart=ulong The definition for wchar_t is unsigned long.
-Xwchart=ushortThe definition for wchar_t is unsigned short.
-Xwchart=uchar The definition for wchar_t is unsigned char.
-Xwchart=intThe definition for wchar_t is int.
-Xwchart=longThe definition for wchar_t is long.
-Xwchart=short The definition for wchar_t is short.
-Xwchart=charThe definition for wchar_t is char.
-Xwchart=schar The definition for wchar_t is signed char.
Note that sizet is not allowed to have signed types.
No default-values are listed because the values change from system to system, and between
operating systems.
Page 84 Apogee User’s Manual
Page 85
Chapter 4: Control-Variable Definitions
C/C++ Compilation
Control-Variable fltdbl — Single vs. Double Arithmetic
K&R C does not do any floating-point arithmetic in single-precision. Objects of type float
are always automatically converted to type double before use by an arithmetic operator, and
while being passed as an argument or while being returned as a function result. ANSI C treats
type float as a normal type, doing arithmetic operations on float objects in single-precision
and doing no automatic conversion to double. This means that the efficiency of singleprecision arithmetic cannot be utilized in K&R programs unless the fltdbl control-variable is
used, as follows:
-Xfltdbl=0For C in c=knr mode, perform arithmetic on float objects in singleprecision, and do not convert float function arguments and return
values to double. Files compiled in this mode cannot be correctly
linked with files compiled using the normal K&R floating-point
model.
-Xfltdbl=1For C in c=knr mode, perform arithmetic on float objects in singleprecision, but convert float function arguments and return values to
double. Files compiled in this mode can be linked correctly with files
compiled using the normal K&R floating-point model.
-Xfltdbl=2For C in c=knr mode, perform arithmetic on float objects in
double-precision, and convert float function arguments and return
values to double. This is the normal K&R floating-point model.
The fltdbl control-variable has routine scope and accepts values of 0, 1, and 2. The firstdefault-value is fltdbl=2, and the second-default-value is fltdbl=1.
Control-Variable inclpath — Include File Searching
There is a strongly established UNIX tradition for the order in which directories are searched
for files named in #include statements, except for one strange case. This case arises when a
relative file name is used inside quotation marks on an #include statement that is itself in a
file already being included via another #include statement. Recent UNIX implementations
usually start this search with the directory containing the file that contains the #include
statement being processed. Earlier UNIX implementations started with the directory
containing the original (top-level) source file. Also, there is a comment in the ANSI C standard
that the standards committee favored "in principle" the earlier approach, but did not actually
specify it in the standard.
Apogee User’s Manual Page 85
Page 86
Apogee Software, Inc.
In Apogee-C, this choice is governed by the value of the inclpath control-variable.
Specifically:
-Xinclpath=relative
In C, while searching for files specified in an #include statement that
uses a relative file name delimited with quotation marks, look first in
the directory containing the file that contains the #include statement
being processed.
-Xinclpath=absolute
In C, while searching for files specified in an #include statement that
uses a relative file name delimited with quotation marks, look first in
the directory containing the original (top-level) source file.
All of the SUN C compilers use the behavior specified by inclpath=relative.
The inclpath control-variable has file scope and accepts values of relative or absolute.
The first-default-value is inclpath=relative, and the second-default-value is
inclpath=absolute.
Control-Variable join — Combining Programs
The Apogee compilers do several kinds of interprocedural optimizations, i.e. optimizations that
occur across or between routines. Such optimizations require the compiler to have knowledge
of other routines at the time it is compiling a routine, and may also require the compiler to
modify the order in which it does the compilation of routines. Some of the available
intraprocedural optimizations are:
1)Call modification analysis (see the callmod control-variable).
2)Inlining in C (see the inllev control-variable).
3)Address leakage detection in C (triggered by xopt=4).
4)Interprocedural register allocation (see the reg control-variable).
Item 1 applies across all of the routines passed to the compiler on one call of the compiler.
However, items 2, 3, and 4 are limited in the sense that they apply only across the routines
within a single file (i.e. when compiling a routine, the compiler only has knowledge about the
other routines in the same file, not about routines that reside in other files).
If it is desired to increase the effectiveness of any of these optimizations within a program that
consists of multiple files, it is necessary to increase the number of routines in a file. This is of
particular importance for inlining, since the inlining will not occur unless the called routine is
in the same file as the calling routine.
Page 86 Apogee User’s Manual
Page 87
Chapter 4: Control-Variable Definitions
C++ Compilation
For FORTRAN, it is possible to increase the number of routines in a file by a simple UNIX cat
operation on the files. For C, however, the matter is not so simple because of variables with
file scope. The join control-variable can be used to combine together into one file all of the C
files passed to the compiler. Specifically:
-Xjoin=0Do not join together the C source files passed to the compiler.
-Xjoin=1Join together into one file all of the C source files passed to the
compiler. The files can only be joined if they meet the restriction that
each variable or function with external linkage must have identical
types in all files in which it occurs. (Static variables in different files
with the same name and potentially different types are correctly
resolved.) The compiler will continue to produce one output file for
each input file, however, all of the results of compilation will be
placed into the output file for the leftmost filename given to the
compiler. The "empty shell" output files produced for the other input
files will assemble and/or link without error, but they will not contain
any code.
The join control-variable has compilation scope and accepts values of 0 or 1. The firstdefault-value is join=0, and the second-default-value is join=1.
C++ Compilation
C++ Dialect
The dialect of C++ recognized by the compiler is controlled by the control-variable c, which is
described in "Control-Variable c — C/C++ Language Modes", page 81. Also see “C++
Language Definition” on page 158.
Control-Variable tmpl — Template Instantiation Mode in C++
The template mechanism of C++ creates some unique situations not found in C or FORTRAN.
A template function in C++ defines a function from which different copies (instantiations) can
be made by changing the types of the formal arguments. This task is done by the compiler.
However, the compiler does not always know how many copies, with what types of formal
arguments, are needed. This problem is even more serious if the definition and the use of a
template function appears in two different compilation units. Also, if the definition of a
template function is visible in multiple compilation units (because of its presence in an include
file), it is not desirable to create identical instantiations of this template in multiple object files,
when unique instantiations will suffice and will be linked correctly. Both class and function
templates have this problem.
The tmpl control-variable controls how the compiler determines which instantiations to make.
Note that this issue may be affected by the ANSI committee working on the C++ standard.
The tmpl control-variable and the entire instantiation mechanism may change in future
releases due to the committee’s decisions.
Apogee User’s Manual Page 87
Page 88
Apogee Software, Inc.
The possible values of the tmpl control-variable are:
-Xtmpl=noneIn this mode, the compiler does not instantiate any templates on its
own. The compiler honors pragmas that can be used to instantiate
needed functions. See page 160 for details on these pragmas, and
page 39 for information on pragmas in general..
-Xtmpl=usedIn this mode, the compiler creates all instantiations that are needed
within the current compilation unit. This option is sufficient for single
file programs, or for programs that define and use templates within a
single compilation unit. If any templates are defined and used in
multiple compilation units, they will be instantiated in all and thus can
cause symbol redefinition errors at link time.
-Xtmpl=allIn this mode, the compiler will instantiate all template entities
declared or referenced in the compilation unit. For each fully
instantiated template class, all of its member functions and static data
members will be instantiated whether or not they were used. Nonmember template functions will be instantiated even if the only
occurrence was a declaration.
-Xtmpl=localThis mode is similar to tmpl=used, except that all instantiations are
created as local variables or functions. This avoids symbol redefinition
errors at link time, at the cost of possibly having multiple static copies
of the same function in the final program.
-Xtmpl=retryThis option invokes the automatic template instantiation mechanism
described below. Normally, this mode creates a minimum number of
instantiations and shares them across multiple object files. However,
this mode requires recompilation of source files and therefore requires
that the source files be present at the link time. It also places
restrictions on movement of object files, which is to say that you
cannot move the source file between when you compile it and when
you link it.
-Xtmpl=x+noautoinclThe tmpl mode names can be augmented by adding the name
noautoincl. By default, if a referenced template definition has not
been found, then the compiler will automatically include a source file
with the same basename, if available, to try to find a template
definition. For example, if "tplate.h" contains a declaration of a needed
template, the compiler will try to include a source file named, say,
"tplate.c" to find the template definition. This automatic inclusion
mechanism may be disabled by adding the name noautoincl to the
tmpl control-variable name.
Page 88 Apogee User’s Manual
Page 89
Chapter 4: Control-Variable Definitions
C++ Compilation
The automatic instantiation mechanism invoked with the -Xtmpl=retry switch is a "linker
feedback'' mechanism. It works by providing additional information in the object file that is
used by a "prelinker'' to determine which template entities require instantiation so that the
program can be linked successfully. The prelinker is a separate program that detects any
missing instantiations just before linking and reinvokes the compiler to create those
instantiations. The linker feedback mechanism has implications for users and the 'make'
process, as described below.
When a program is compiled, the compiler generates a set of uniquely named symbols in the
generated object file. These symbols inform the prelinker:
1)which instantiations can be done by this compilation unit, if needed, and
2)which instantiations are required by this compilation unit.
The compiler also generates a .ii file (instantiation information file), whose prefix is the same
as that of the source file and whose suffix is .ii. This file is generated in the same directory
where the .o file is created. Neither the .ii file nor the .o file can be moved to any other
directory. The .ii file contains the set of options passed to the compiler and the directory
where the compiler was invoked. This file is used by the prelinker to reinvoke the compiler on
the corresponding source file, if needed.
Once a complete set of object files has been generated, apCC invokes the prelinker to
determine whether any new instantiations are required or if any existing instantiations are no
longer required. The prelinker works by looking for .ii files for each of the object files. If
any instantiations are missing, the prelinker reinvokes the compiler on source files that can
supply those instantiations. This process is repeated as long as more instantiations are needed
and as long as the prelinker can determine a source to supply each missing instantiation. Note
that instantiation of one template may create the need for other instantiations, thus requiring
multiple compilations of the same source file. When no more needed instantiations can be
created, the prelinker stops. If there are still missing instantiations, a linker error occurs.
Once the link process has finished (successfully or unsuccessfully), the .ii files are left
behind. From then on, any recompilation of those source files (whether by the user or by the
prelinker) uses the corresponding .ii files to determine which set of instantiations will be
needed for the final link. Minor changes in a source file, and subsequent compilation and
linking will not cause iterative recompilations each time, unless a new need for instantiations
is created. The prelinker will be invoked, but will find that all the required instantiations have
already been done. Recompilation will be done only if the .ii file is invalid. That is:
1)if additional instantiations come to be needed (in this or other files),
2)if existing instantiations are no longer required,
3)if a different set of command line options is used, or
4)if the .ii file has been deleted.
For this reason, the .ii files should not be deleted in the normal course of development.
However, if they are deleted, the recompilation and linking will succeed, but will require
iterative recompilation.
Apogee User’s Manual Page 89
Page 90
Apogee Software, Inc.
The tmpl control-variable has compilation scope and accepts values of none, used, all,
local, and retry. The first-default-value is used and the second-default-value is none.
General Code Control
Control-Variable addr — Data Addressing Mode
Compiled code can use efficient absolute references to data items unless that code will be
placed in a dynamically-linked library. If the code will be placed in a dynamically-linked
library, it must use "position-independent" references to data items. The addr control-variable
can be used to govern this feature, as follows:
-Xaddr=DATAGenerate absolute reference to items in data space.
-Xaddr=PICGenerate position-independent code.
-Xaddr=picGenerate position-independent code, but assume that the Global Offset
Table is less than 8 kilobytes.
The addr control-variable has compilation scope, and accepts names as values. The first and
second-default-values are addr=DATA.
Control-Variable alnref — Alignment of Indirect References
Most RISC processors have memory alignment restrictions which require that objects of length
n bytes be placed at addresses that are 0 modulo n in order to be accessed via the load and store
instructions for an object of that length. For example, double-word objects, such as FORTRAN
REAL*8 variables, must be placed at addresses that are evenly divisible by 8 in order to use
efficient double-word load and store instructions when accessing the object. If objects in
memory are misaligned, i.e. allocated so that they violate this alignment restriction, then less
efficient instructions must be used to access them. For example, a double-word object might be
accessed via two single-word load instructions if it was placed at an address that was evenly
divisible by 4, but not evenly divisible by 8.
In compiling C and FORTRAN for SPARC, there are two reasons why data might be
misaligned:
•In FORTRAN, the alnstd control-variable might be used to enforce strict ANSI data
layout. This may cause some double word items to be misaligned, but still aligned
according to single word rules.
•The SPARC stack layout is unique among RISC processors in requiring that some
double word parameters passed by value be misaligned as they are passed on the
stack. The rule for discovering if this applies to a given parameter involves scanning
the parameters left-to-right and counting words as follows:
1)For each reference parameter, count 1 word.
2)For each value parameter that is 4 bytes or less, count 1 word.
3)For each value parameter that is a structure, count 1 word.
Page 90 Apogee User’s Manual
Page 91
Chapter 4: Control-Variable Definitions
General Code Control
4)For each double word value parameter, count 2 words.
5)For a double word value parameter, if there is an even number of words
counted to its left (where 0 is even), then it is misaligned on the stack.
Compilers face two different kinds of situations in compiling memory references in a program:
•Direct references. When a memory object is referenced directly, via its declared name,
its memory layout is known, and thus its alignment/misalignment properties are
known. In this case, the compiler can generate the appropriate accessing instructions.
•Indirect references. When a memory object is referenced indirectly, via a run-time
pointer value, its memory layout is unknown, and thus its alignment/misalignment
properties are unknown. In this case the compiler must use "worst case" assumptions
to generate accessing instructions.
Examples of direct references ar e r eferences to variables via their own names, and references to
C parameters via the parameter name. Examples of indirect references are use of the C
dereference operator (*) and references to FORTRAN formal parameter names.
The dilemma for the compiler is what kind of accessing instructions to compile for indirect
references to double word objects. If single-word instructions are used, the program will run
properly when misaligned objects are present, but the performance of the program will be
negatively impacted. In fact, if there are indirect references to double-word objects in an
important loop, there may be a significant slowdown. On the other hand, if double-word
instructions are used, the performance will not be impacted, but legal programs may fail.
This choice of accessing instructions for indirectly referenced double-word objects is governed
by the alnref control-variable. Specifically:
-Xalnref=0Assume that double-word objects referred to indirectly will always be
properly aligned, so double-word load and store instructions can be
used.
-Xalnref=1Assume that double-word objects referred to indirectly may be
misaligned, so double-word load and store instructions can not be
used.
The important practical fact about this choice is that only a very few programs will fail if
alnref=0 mode used. For this failure to occur, there must first be a misaligned object, and
then it must be referred to indirectly. Some examples of how this could occur are as follows:
•In FORTRAN, in alnstd=1 mode, a misaligned double-word object might be passed
as an argument to a subroutine, and then referenced in that subroutine.
•In C, an argument to a subroutine is misaligned on the stack, and then its address is
taken and later dereferenced.
•In mixed C and FORTRAN, an argument to a C routine is misaligned on the stack, and
then its address is taken and passed to a FORTRAN subroutine as a reference
parameter which is then referenced.
Apogee User’s Manual Page 91
Page 92
Apogee Software, Inc.
•In mixed C and FORTRAN, in alnstd=1 mode for the FORTRAN routine, a
misaligned double-word object is passed as an argument to a C routine, which is then
dereferenced.
Notice that in pure FORTRAN (because there are no value parameters), unless the alnstd=1
mode is used, failure will never occur. Also notice that even in C, failure is not likely, since
even if a routine is passed a double, it is not common to refer to such numeric parameters via
a pointer.
The alnref control-variable has routine scope and accepts values of 0 and 1. Both the firstdefault-value and second-default value are alnref=1. The -dalign command line option is
an abbreviation for -Xalnref=0.
Control-Variable bss — Use of .bss section
Data items that do not require link-time initialization to specific non-zero values may be placed
in either the .data or .bss section. Binary program files are smaller if such items are placed
in .bss, but compatibility reasons may dictate placement in .data. This is governed by the
bss control-variable, as follows:
-Xbss=0All data will be placed in the .data section.
-Xbss=1Static uninitialized data and data initialized to zero may be placed in
either the .data section or .bss section according to automatic rules
within the compiler.
-Xbss=2Static uninitialized data will be placed in the .bss section; data
initialized to zero will be placed in the .bss section where possible.
The bss control-variable has routine scope, and accepts values of 0, 1, and 2. The first-default
value is bss=1, and the second-default-value is bss=2.
Control-Variable flat — Flat Register Model
SPARC processors use a concept called "register windows" for the integer registers (but not for
the floating point registers). The total set of integer registers implemented in the processor is
divided up into a number of overlapping subsets of 32 registers, each of which is called a
window, with the property that within any one routine, only the registers of one specific
window are available for use. When another routine is called, a new register window is
opened, so those registers can be used by the new routine, and when that routine exits, the
preceding window is restored. Most current SPARC processors have either 7 or 8 windows
available.
This scheme offers some advantages in terms of speed of passing and returning values in
registers, and in avoiding the necessity of saving registers across the calling of a subroutine.
However, it also offers the disadvantage that whenever the set of active subroutines is large
enough to use up the available windows, a time-consuming interrupt to the operating system
to save and/or restore register values is needed.
Page 92 Apogee User’s Manual
Page 93
Chapter 4: Control-Variable Definitions
General Code Control
Some programs do not experience this disadvantage. If the program never calls subroutines to
a nesting level equal to or greater than the number of available windows, there is no need to
"spill" the windows in this fashion. Similarly, if the program does call subroutines to a deep
nesting level, but does so only relatively infrequently, there will only be a small performance
impact.
Programs that do experience this disadvantage are programs that call subroutines to a deep
nesting level and do the subroutine calling and returning quite frequently compared to the
other computation in the program. Such programs can experience a significant or even severe
slowdown on SPARC processors due to the need to spill the register windows.
The flat control-variable is available to specify that the register window property is not to be
used when compiling a particular routine. The flat control-variable accepts a list of names.
If a routine's name is a member of this list at the start of the routine, then that routine will be
compiled in such a fashion that it does not request a new window when it is entered (and does
not return a window when it exits). This has the effect of removing any possibility that calling
the routine will trigger a register window spill. However, it also has the effect of slowing
down the compiled code of the routine because return address manipulation must now be
done explicitly, and because the number of free scratch registers that the routine has available
for performing computations without having to save or restore registers drops from 25 to 10.
The net effect of these various considerations is that the effect of the use of flat mode is very
dependent on the particular circumstances. For most programs and for most routines, flat
mode will cause a net slow down. However, if a routine is used in a fashion that frequently
triggers register window spill, and if the routine is not complicated enough so that the
reduction of available scratch registers causes a significant slow down in the compiled code for
the routine, then the use of flat mode may cause a significant speed up. For example, a short
C routine that implemented a highly recursive algorithm would be a good candidate for trying
flat mode.
An important restriction applies to the use of flat mode. C programs that use setjmp or
longjmp will not work if any routines are compiled in flat mode.
Independent of flat mode, some leaf routines are optimized so that they do not use a register
window.
The flat control-variable has routine scope and accepts as values a list of names. The firstdefault-value and the second-default-value are both the null list.
Control-Variable fltconst — Single Precision Floating Point
Constants
According to ANSI FORTRAN 77:
•a floating point constant written either without an exponent, or with an "E" exponent,
is of type REAL (i.e. REAL*4), and
•a floating point constant written with a "D" exponent is of type DOUBLE PRECISION
(i.e. REAL*8).
A strict reading of the standard would indicate that D1 and D2 should receive values that are
the same as if the program had been written:
REAL F1, F2
DOUBLE PRECISION D1, D2, D3
F1 = 1.231
D1 = F1
F2 = 1.232E0
D2 = F2
D3 = 1.233D0
In other words, 1.231 and 1.232E0 should be stored with REAL accuracy, while 1.233D0
should be stored with DOUBLE PRECISION accuracy.
Unfortunately, this "strict reading" behavior is not the behavior expected of most FORTRAN
compilers by most FORTRAN programmers, who would instead expect D1 and D2 to hold
representations of the respective constants that were accurate to full DOUBLE PRECISION
accuracy after the assignments. While such behavior is not given by a strict reading of the
standard, neither is it forbidden by the standard, since the standard does not give rules
governing required accuracy. Furthermore, such behavior is more "user-friendly" in most
circumstances.
In ANSI C, the situation is reversed, because the "natural" floating point constant (i.e., one
without a special suffix) is a double precision value.
The fltconst control-variable governs the stored accuracy of single precision floating point
constants. Specifically:
-Xfltconst=0For C, implement single precision floating point constants as indicated
by fltconst=4. For FORTRAN, implement single precision floating
point constants as indicated by fltconst=8.
-Xfltconst=4Implement single precision floating point constants with single
precision accuracy.
-Xfltconst=8Implement single precision floating point constants with double
precision accuracy when they are used in a context in which the value
would be converted to double precision before being used, such as
assignment to a double precision variable, or use as one operand of an
operator whose other operand is a double precision variable, etc.
The fltconst control-variable has file scope and permits values of 0, 4, and 8. The firstdefault-value is 0 and the second-default-value is 4.
Page 94 Apogee User’s Manual
Page 95
Chapter 4: Control-Variable Definitions
General Code Control
Control-Variable g — Symbolic Debugging
Symbolic debugging information may be included in the assembly files produced by the
compiler by use of the g control-variable, as follows:
-Xg=0Do not include symbolic debugging information in the assembly files.
-Xg=1Include the Solaris 1 form of symbolic debugging information in the
assembly file for use by a symbolic debugger. The Solaris 1 form of
debugging information is useful under Solaris 2 when running
products that have not been upgraded to accept the new form of
debugging directives.
-Xg=2Include symbolic debugging information in the assembly file for use
by a symbolic debugger. The form of debugging information placed
in the assembly file is determined by the OS in use.
The g control-variable has compilation scope and accepts values of 0, 1, and 2. The firstdefault-value is g=0, and the second-default-value is g=2.
Control-Variable glbreg — Use of Global Registers in Compiled
Code
The SPARC ABI (see the System V Application Binary Interface, SPARC Processor
Supplement) permits some flexibility with respect to the usage of six of the SPARC processor
registers, as follows:
•Global integer registers 2, 3, and 4 are reserved for the application software. System
software (including the libraries described in Chapter 6) preserves these registers’
values for the application. Their use is intended to be controlled by the compilation
system and must be consistent throughout the application.
•Global integer registers 5, 6, and 7 are reserved for system software. Because system
software provides the low-level operating system interface, including signal handling,
an application cannot change the registers and safely preserve the system values, even
by saving and restoring them across function calls. Therefore, application software
must not change these registers’ values.
This flexibility appears to have caused some confusion among software developers. Until
recently, compilers from SunPro did not appear to use any of the six registers, nor did normal
system software. The only use of these registers we have observed is in some rarely used
performance monitoring tools.
Newer compilers from SunPro have options to permit usage of these six registers. Clearly, the
ability to use g5 through g7 in compiled code would be useful for compiling system code,
however, Sun has recently published benchmark results where benchmark application code
uses g5 through g7, showing that it is at least possible to use these three registers in
application code under current system software.
The use of these six global registers by compiled code is controlled in Apogee compilers by use
of the glbreg control-variable, as follows:
Apogee User’s Manual Page 95
Page 96
Apogee Software, Inc.
-Xglbreg=g2Use global-register g2 in compiled code.
-Xglbreg=g3Use global-register g3 in compiled code.
-Xglbreg=g4Use global-register g4 in compiled code.
-Xglbreg=g5Use global-register g5 in compiled code.
-Xglbreg=g6Use global-register g6 in compiled code.
-Xglbreg=g7Use global-register g7 in compiled code.
-Xglbreg=applUse the global-registers which the SPARC ABI reserves for the
application, i.e., g2, g3, and g4.
-Xglbreg=systUse the global-registers which the SPARC ABI reserves for the system,
i.e., g5, g6, and g7.
-Xglbreg=%none Use none of the global-registers in compiled code.
combinationThe above values may be combined, for example, glbreg=g2+g4 will
use registers g2 and g4, or glbreg=appl+g6 will use registers g2, g3,
g4 and g6, or glbreg=syst-g7 will use global-registers g5 and g6.
The glbreg control-variable has file scope, and accepts as values a list of names. The first and
second-default-values are glbreg=appl.
Control-Variable kap — Use of theKAP Preprocessor
Versions of the KAP source-to-source optimizing preprocessors from Kuck & Associates are
optionally available for purchase with the Apogee compilers. SP KAP-C and MP KAP-C are
available with Apogee-C, and SP KAP-FORTRAN and MP KAP-FORTRAN are available with
Apogee-FORTRAN.
The versions of the preprocessors shipped by Apogee have been integrated with the Apogee
compilers, and perform a set of optimizations that complement those performed by the Apogee
compilers. See Chapter 1 for a discussion of the integrated packages.
Whether the KAP preprocessor is invoked for each compiler input file is determined by the
value of the kap control-variable at the start of that file. Specifically:
-Xkap=noDo not run the KAP preprocessor on this file.
-Xkap=spRun the KAP preprocessor on this file.
-Xkap=mpRun the KAP preprocessor on the file, passing the -concurrentize
option to KAP, so the file is compiled for use on multiple processors.
The MP KAP products require Solaris 2.2 or later.
When the KAP preprocessors have been used, the KAP control variable must also be specified
at link time so that appropriate libraries are referenced.
When running an application that was built using the MP KAP products, the environment
variable PARALLEL should be set to indicate the number of processors available for the
application. See the appropriate KAP User’s Guide for details.
Page 96 Apogee User’s Manual
Page 97
Chapter 4: Control-Variable Definitions
General Code Control
If the C preprocessor is also to be run, it is run before the KAP preprocessor. The KAP options
specified in -XK options on the command line and in the T control-group are passed to KAP.
The fcols, fblank, ftab, and dline control-variables should not be given values.
For a quick introduction to the KAP preprocessors, see "Appendix B: A 5-Minute KAP Guide",
page 173.
The kap control-variable has file scope and accepts either no, sp or mp as values. The firstdefault value is kap=no and the second-default value is kap=sp.
Control-Variable prof — Profiling
The performance monitoring tools prof and gprof and supported under Solaris 1 (Sun OS
4.x) and the prof tool is supported under Solaris 2 (SunOS 5.x) as follows:
-Xprof=0Do not set up for profiling.
-Xprof=1Set up for profiling with prof(1). This has two effects. First, during
compilation, counting code is placed into each routine. Second,
during link editing, libraries compiled for profiling with prof(1) are
used. If compilation and link editing are done in separate steps and
prof=1 is used during compilation, it should also be used during link
editing.
-Xprof=2Set up for profiling with gprof(1). This has two effects. First, during
compilation, counting code is placed into each routine. Second,
during link editing, libraries compiled for profiling with gprof(1) are
used. If compilation and link editing are done in separate steps and
prof=2 is used during compilation, it should also be used during link
editing.
The prof control-variable has compilation scope, and accepts values of 0, 1, and 2. The firstdefault-value is prof=0, and the second-default-value is prof=1.
Control-Variable relfunc — Routine Handling in Assembly Files
Normally all the routines in a file are put into a single text section in the assembly file.
However, some SPARCworks tools under Solaris 2 require that each routine be in a separate
section in order to function properly. This is governed by the relfunc control-variable, as
follows:
-Xrelfunc=0Put all routines in the same text section.
-Xrelfunc=1Put each routine in a separately relocatable text section.
The relfunc control-variable has routine scope and accepts values of 0 and 1. The firstdefault-value is relfunc=0 and the second-default-value is relfunc=1.
Apogee User’s Manual Page 97
Page 98
Apogee Software, Inc.
Control-Variable vast — Use of theVAST Preprocessor
Versions of the VAST source-to-source optimizing preprocessors from Pacific-Sierra Research
Corporation are optionally available for purchase with the Apogee compilers. SP VAST-C and
MP VAST-C are available with Apogee-C, and SP VAST-FORTRAN and MP VAST-FORTRAN
are available with Apogee-FORTRAN.
The versions of the preprocessors shipped by Apogee have been integrated with the Apogee
compilers, and perform a set of optimizations that complement those performed by the Apogee
compilers. See Chapter 1 for a discussion of the integrated packages.
Whether the VAST preprocessor is invoked for each compiler input file is determined by the
value of the vast control-variable at the start of that file. Specifically:
-Xvast=noDo not run the VAST preprocessor on this file.
-Xvast=spRun the VAST preprocessor on this file.
-Xvast=mpRun the VAST preprocessor on the file, passing the -concurrentize
option to vast, so the file is compiled for use on multiple processors.
The MP VAST products require Solaris 2.2 or later.
When the VAST preprocessors have been used, the VAST control variable must also be
specified at link time so that appropriate libraries are referenced.
If the C preprocessor is also to be run, it is run before the VAST preprocessor. The VAST
options specified in -XV options on the command line are passed to VAST.
For a quick introduction to the VAST preprocessors, see "Appendix A: A 5-Minute VAST
Guide", page 167.
The vast control-variable has file scope and accepts either no, sp or mp as values. The firstdefault value is vast=no and the second-default value is vast=sp.
See Chapter 6 for a discussion of the conditions under which a variable should be declared
volatile or a pointer should be declared "pointer to volatile". Once it has been determined that
(one of) these declarations should be made, there are several techniques that can be used.
These techniques can be used to declare individual variables or pointers volatile, or to declare
groups or classes of variables or pointers volatile. To start with, there are three basic
mechanisms:
1)If the source language is ANSI C/C++ or extended K&R C (but not if it is pure K&R C),
there is a volatile type qualifier in the language. This can be used to declare
individual variables volatile, to declare structures or arrays volatile, to declare portions
of structures volatile, or to declare pointer types to be "pointer to volatile".
Page 98 Apogee User’s Manual
Page 99
Chapter 4: Control-Variable Definitions
Miscellaneous Controls
2)If the source language is FORTRAN, there is a VOLATILE declaration statement in the
language. This can be used to declare individual variables volatile, to declare
structures or arrays volatile, to declare portions of structures volatile, or to declare
common blocks volatile.
3)In either language, the volatile, defvol and ptrvol control-variables are
available to determine which variables and pointers are interpreted as volatile by the
compiler. The volatile control-variable can be used to declare variables volatile.
The ptrvol control-variable can be used to declare pointer variables as “pointer to
volatile”. The defvol control-variable can be used to apply default volatility to
several classes of variables and pointers. (The volatile and ptrvol controlvariables take a list of names. The defvol control-variable takes the values ptr,stat, glob.)
The rules that apply to these three mechanisms for determining whether a variable is volatile
or a pointer is "pointer to volatile" are as follows:
1)Explicit Declaration. If the variable is declared volatile by use of a volatile declaration
in the language, it is volatile. If the pointer is declared "pointer to volatile" it is
"pointer to volatile".
2)volatile control-variable. If the variable name is listed in the value of the volatile
control-variable at the point of its declaration, it is volatile.
3)ptrvol control-variable. If the variable name is listed in the value of the ptrvol
control-variable at the point of its declaration, it is “pointer to volatile".
4)defvol control-variable. Possible values are:
-Xdefvol=ptrall pointer references are “pointer to volatile”.
-Xdefvol=statall static variables are volatile.
-Xdefvol=globall global variables are volatile.
A list of these values may be used, e.g. defvol=stat+glob.
The volatile and ptrvol control-variables have line scope and accept a list of names. The
first-default-value and the second-default-value for both control-variables is the null list.
The defvol control-variable has line scope and accepts values of ptr, stat, and glob.
The first-default-value is the null list, and the second-default-value is defvol=ptr+glob.
Miscellaneous Controls
Control-Variable lmstat — Status of License Manager
The current status of all of the licenses known to the license daemon are printed to stdout by
using the command line switch -Xlmstat. Also see the lmstat(1) command on page 206.
This control-variable may only be specified on the command line — it has no effect when
specified in a pragma.
Apogee User’s Manual Page 99
Page 100
Apogee Software, Inc.
Control-Variable progress — Status of Compilation
It is possible to request additional information about the status of the compilation as well as
information about which optimizations are being done. These extra messages are affected by
the setting of the progress control-variable.
There are two basic types of these extra messages: the first type involves printing an additional
message as a phase of the compiler begins processing a portion of source code; the second type
involves providing information about optimizations that have been executed on portions of
source code. Specifically:
-Xprogress=filesAnnounce progress at the start of compiling each file.
-Xprogress=functionsAnnounce progress at the start of compiling each function.
-Xprogress=phasesAnnounce progress at the start of each phase of the
compiler.
-Xprogress=subphasesAnnounce progress at the start of each subphase of the
compiler.
-Xprogress=actionsAnnounce progress at each major action (e.g. inlining)
done by the compiler.
-Xprogress=failuresAnnounce the failure of each major action (e.g. failed to
inline a routine) attempted by the compiler.
-Xprogress=templatesAnnounce instantiations of template functions.
-Xprogress=memoryInclude compiler memory-usage information in progress
announcements.
-Xprogress=sizesInclude information on the size of internal compiler data
structures in progress announcements.
-Xprogress=realtimeInclude the realtime used by the compiler in progress
announcements.
-Xprogress=rtimeInclude the realtime used by the compiler in progress
announcements (same as realtime).
-Xprogress=usertimeInclude the usertime used by the compiler in progress
announcements.
-Xprogress=utimeInclude the usertime used by the compiler in progress
announcements (same as usertime).
-Xprogress=%allAnnounce progress at all possible points of compilation.
-Xprogress=%noneDo not announce compiler progress.
As with all controls of "name" type, this control can take a list of more than one value, for
example: -Xprogress=actions+failures+files.
Page 100 Apogee User’s Manual
Loading...
+ hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.