Apogee Software APOGEE COMPILERS, APOGEE-C++, FORTRAN 77, FORTRAN 90 User Manual

Page 1
USER’S MANUAL
FOR
Version
APOGEE-C APOGEE-C++
APOGEE COMPILERS
™
HIGHLY OPTIMIZING COMPILERS
WITH INTRODUCTION TO KAP™& VAST™PREPROCESSORS
& FLEXLM™LICENSE MANAGER
APOGEE-FORTRAN 77
™
APOGEE-FORTRAN 90
4.0
™ ™
Page 2
© 1990-1996 — Apogee Software, Inc.
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
Preface ..................................................................................................................9
Contents of this Manual ...........................................................................................9
Typographic Conventions......................................................................................11
Terminology .............................................................................................................12
A 3-minute Guide to Using the Apogee Compilers...........................................13
Chapter 1 Introduction to the Apogee Compilers........................................................... 15
The Compilation System........................................................................................15
Optimization............................................................................................................19
Control of Compiler Behavior...............................................................................21
Chapter 2 Invoking the Compilers.....................................................................................23
Compiler Invocation Command ...........................................................................23
Files............................................................................................................................23
Fortran 90 File Names.............................................................................................25
Options......................................................................................................................25
Chapter 3 Control-Variables and Control-Programs...................................................... 33
Control-Variables.....................................................................................................33
Control-Groups........................................................................................................35
Control-Expressions................................................................................................36
Control-Assignments..............................................................................................37
Control-Programs....................................................................................................38
Writing Pragma Directives.....................................................................................39
Apogee User’s Manual Page 3
Page 4
Apogee Software, Inc.
Chapter 4 Control-Variable Definitions...........................................................................41
Optimization Control-Variables............................................................................ 41
Introduction to Optimization......................................................................... 41
Control-Variable alias — Alias Analysis ...................................................... 43
Control-Variable callmod — Call Modification Analysis .......................... 44
Control-Variable cih — Cross-Iteration Hoisting........................................ 45
Control-Variable constp — Constant Propagation......................................45
Control-Variable copyp — Copy Propagation.............................................46
Control-Variable domain — Optimization Domain................................... 46
Control-Variable fcm — Forward Code Motion.......................................... 46
Control-Variable flex — Optimization Flexibility....................................... 47
Control-Variable flow — Control Flow Optimization................................ 47
Control-Variable fltacc — Floating Point Expression Rearrangement &
Numerical Accuracy................................................................................. 48
Control-Variable fltedge — Floating Point Limits ...................................... 49
Control-Variable fltfold — Floating Point Constant Folding .................... 50
Control-Variable intedge — Integer Limits.................................................. 50
Control-Variable ivrep — Induction Variable Replacement...................... 50
Control-Variable memlimit — Scope of Main Optimizations................... 51
Control-Variable mopt — Main Optimizations........................................... 51
Control-Variable reg — Register Allocation ................................................ 52
Control-Variable safeintr — Intrinsic Error Checking................................ 53
Control-Variable sched — Scheduling.......................................................... 53
Control-Variable unroll — Loop Unrolling.................................................. 54
Control-Variable unrollexact — Loop Unrolling Exactness ...................... 54
Control-Variable whole — Whole Program Compilation.......................... 55
Control-Variable xopt — Extra Optimizations............................................ 55
Control-Variable zone — Expansion of Zones............................................. 56
Control-Variables inline, noinline, deflib, inllev and sinllev — Routine
Inlining.......................................................................................................56
Control-Variables profile and pstat — Profiling Feedback to Inlining .... 58
Control-Group O — Optimization................................................................ 59
Target Computer Control-Variables..................................................................... 59
Control-Variable cg — Target Computer Instruction Set........................... 60
Control-Variable pipe — Target Computer Instruction Pipeline.............. 61
Control-Group T — Target Computer.......................................................... 62
Diagnostic Control-Variables ................................................................................ 62
Control-Variable diag — Diagnostic Output Level .................................... 63
Control-Variable quit — Diagnostic Quit Level.......................................... 64
Control-Variable stddiag — Standard Diagnostics (FORTRAN only)..... 64
FORTRAN Source File Format.............................................................................. 64
FORTRAN 77 Statement Format................................................................... 64
Control-Variable fblank — FORTRAN Statement Blanks..........................66
Control-Variable fcols — FORTRAN Statement Columns........................ 66
Page 4 Apogee User’s Manual
Page 5
Table of Contents
Control-Variable ftab — FORTRAN Tab Statements.................................. 66
Control-Group F — FORTRAN Statement Format..................................... 67
Control-Variable fcont — FORTRAN Continuation Lines........................ 68
Control-Variable fstmt — FORTRAN Statement Buffer............................. 68
Control-Variable case — FORTRAN Case Sensitivity................................ 69
Control-Variable dline — FORTRAN Debug Lines.................................... 69
Fortran 90 Statement Format.......................................................................... 69
Control-Variable sform — FORTRAN 90 Statement Format.....................70
FORTRAN 77 Compilation.................................................................................... 70
Control-Variable alnstd — FORTRAN Standard Common/Equivalent
Layout ........................................................................................................ 70
Control-Variable cmul — Complex multiply............................................... 72
Control-Variable comname — COMMON Block Name Format.............. 72
Control-Variable ftype — FORTRAN Types................................................ 73
Control-Variable implicit — Assumed Implicit None Statement............. 76
Control-Variable onetrip — One-Trip DO Loops in FORTRAN............... 76
Control-Variable save — SAVE Variables in FORTRAN............................ 77
Control-Variable vms — VAX/VMS Compatibility................................... 80
C/C++ Compilation ............................................................................................... 81
Control-Variable c — C/C++ Language Modes.......................................... 81
Control-Variable char — Signedness of plain char in C/C++................... 83
Control-Variables sizet and wchart — Definitions of types size_t and
wchar_t in C/C++ .................................................................................... 84
Control-Variable fltdbl — Single vs. Double Arithmetic........................... 85
Control-Variable inclpath — Include File Searching.................................. 85
Control-Variable join — Combining Programs........................................... 86
C++ Compilation..................................................................................................... 87
C++ Dialect....................................................................................................... 87
Control-Variable tmpl — Template Instantiation Mode in C++............... 87
General Code Control............................................................................................. 90
Control-Variable addr — Data Addressing Mode...................................... 90
Control-Variable alnref — Alignment of Indirect References ................... 90
Control-Variable bss — Use of .bss section.................................................. 92
Control-Variable flat — Flat Register Model ............................................... 92
Control-Variable fltconst — Single Precision Floating Point Constants.. 93
Control-Variable g — Symbolic Debugging ................................................ 95
Control-Variable glbreg — Use of Global Registers in Compiled Code.. 95
Control-Variable kap — Use of the KAP Preprocessor.............................. 96
Control-Variable prof — Profiling................................................................. 97
Control-Variable relfunc — Routine Handling in Assembly Files........... 97
Control-Variable vast — Use of the VAST Preprocessor............................ 98
Properties of Variables............................................................................................ 98
Control-Variables volatile, defvol, ptrvol — Volatile Variables................ 98
Miscellaneous Controls.......................................................................................... 99
Apogee User’s Manual Page 5
Page 6
Apogee Software, Inc.
Control-Variable lmstat — Status of License Manager...............................99
Control-Variable progress — Status of Compilation................................ 100
Control-Variable show — Output Values of Control-Variables.............. 101
Control-Variable xref — Output a Cross-Reference Table ....................... 101
Chapter 5 Reference Tables...............................................................................................105
Control-Variable Reference Table ....................................................................... 105
Control-Group Reference Tables......................................................................... 129
Optimization Group (O)............................................................................... 129
Fortran Input Format Group (F).................................................................. 130
Target Machine Group (T)............................................................................ 131
Chapter 6 Programming Restrictions...............................................................................133
Introduction to Programming Restrictions and Optimization....................... 133
Required Restrictions ........................................................................................... 135
Uninitialized Variables.................................................................................. 135
Overlapping String Moves........................................................................... 136
Side-effects Within a Zone............................................................................136
Assignable Actual Parameters (FORTRAN).............................................. 137
EQUIVALENCE/COMMON Cross-Typing (FORTRAN)....................... 137
Default Restrictions .............................................................................................. 138
Out of Bound References/Wildness............................................................ 138
Asynchronous Modifications/Volatility.....................................................138
SETJMP and LONGJMP (C)......................................................................... 141
Assigned GOTO Bounds (FORTRAN)....................................................... 141
Dummy Argument Aliasing (FORTRAN)................................................. 142
Recursion (FORTRAN) ................................................................................. 142
Compilation Restrictions ..................................................................................... 143
Interprocedural Optimizations and Compilation..................................... 143
Mixing C and Fortran, or FORTRAN-77 and Fortran 90......................... 143
Using Fortran 90 MODULEs........................................................................ 144
Using the KAP Preprocessor........................................................................ 144
Using the VAST Preprocessor...................................................................... 144
Using the VAST -mi Option.......................................................................... 144
Using control-variable whole....................................................................... 144
Chapter 7 The Apogee-FORTRAN 77/90 Languages....................................................145
Overview of Apogee-FORTRAN........................................................................ 145
ANSI FORTRAN-77 Features.............................................................................. 146
ANSI FORTRAN-66 Features.............................................................................. 146
MIL-STD 1753 Extensions.................................................................................... 146
VAX FORTRAN Extensions................................................................................. 147
Cray FORTRAN Extensions................................................................................ 149
SUN FORTRAN Extensions ................................................................................ 149
Additional Extensions..........................................................................................150
Page 6 Apogee User’s Manual
Page 7
Table of Contents
Transformation of Symbol Names...................................................................... 150
Intermixing C Modules with FORTRAN Modules.......................................... 151
Control-Variables That Affect the FORTRAN Language................................ 154
Fortran 90 Compilation Restrictions.................................................................. 155
Chapter 8 The Apogee-C & Apogee-C++ Languages....................................................157
C Language Definition......................................................................................... 157
C++ Language Definition .................................................................................... 158
Dialect.............................................................................................................. 158
Boolean Type (bool)....................................................................................... 158
Wide Characters (wchar_t)........................................................................... 159
Special Pragmas ............................................................................................. 160
Exception Handling....................................................................................... 161
On-going Standardization Issues................................................................ 162
Significant Comments .......................................................................................... 165
Predefined Symbols.............................................................................................. 166
Appendix A A 5-Minute VAST Guide ..............................................................................167
Introduction........................................................................................................... 167
Optimizing Small Programs with VAST............................................................ 168
Optimizing Large Programs with VAST............................................................168
Improving and Customizing VAST Performance............................................ 169
Additional Performance Improvement Techniques......................................... 170
Problems................................................................................................................. 171
Appendix B A 5-Minute KAP Guide.................................................................................173
Introduction........................................................................................................... 173
Optimizing Small Programs with KAP ............................................................. 173
Optimizing Large Programs with KAP............................................................. 174
Improving and Customizing KAP Performance.............................................. 175
Additional Performance Improvement Techniques......................................... 177
Problems................................................................................................................. 177
Appendix C Apogee Compilers on SPARC Systems......................................................179
Introduction........................................................................................................... 179
Operating System Issues...................................................................................... 180
SPARC-specific control variables........................................................................ 180
SPARC-specific predefines................................................................................... 181
SPARC-specific command-line options ............................................................. 182
Compatibility......................................................................................................... 183
Appendix D Apogee Compilers on PowerPC Systems...................................................185
Appendix E Installation and License Management........................................................187
Overview................................................................................................................ 187
Installation Features...................................................................................... 189
Mounting the Apogee CD-ROM......................................................................... 191
Apogee User’s Manual Page 7
Page 8
Apogee Software, Inc.
Index..................................................................................................................211
Introduction.................................................................................................... 191
Procedure for Use .......................................................................................... 191
The Installation Process ................................................................................ 191
Installing From a Local CD Drive................................................................ 192
Installing From a Remote CD Drive............................................................ 193
The Installation Directory.................................................................................... 194
The FLEXlm License Manager ............................................................................ 198
How the FLEXlm License Manager Works................................................ 198
The FLEXlm Log File..................................................................................... 199
The FLEXlm License-file...............................................................................200
SERVER Lines..........................................................................................200
DAEMON Lines...................................................................................... 201
FEATURE Lines ...................................................................................... 201
License File Example.....................................................................................202
Managing/Merging License-Files............................................................... 202
The FLEXlm Options File ............................................................................. 204
RESERVE Line......................................................................................... 205
NOLOG Line........................................................................................... 205
INCLUDE Line........................................................................................ 205
EXCLUDE Line....................................................................................... 206
GROUP Line............................................................................................ 206
FLEXlm Utilities............................................................................................. 206
Troubleshooting Guide ................................................................................. 207
General Debugging Hints...................................................................... 207
Problem Description Format................................................................. 207
Problems .................................................................................................. 208
Page 8 Apogee User’s Manual
Page 9
Preface
Preface
Contents of this Manual
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++, Apogee­FORTRAN 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++, Apogee­FORTRAN 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 Apogee­Fortran 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:
Purpose Convention
English prose The Palatino typeface is used for ordinary English prose in this
manual. The bold variant of Palatino is used to emphasize words.
definitions For 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 text For literal samples of text from some language given as input to or
output from the computer, this typeface, the bold variant of 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 fields For 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:
Term Definition
routine A 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-routine A 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-routine A 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.
program A 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 failure Any 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-variable A 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 "control­variable". This distinguishes it from more casual use of the term, e.g., "The loop control variable ...".
target computer The particular kind and model of computer for which the compiler is
to produce compiled code and the operating environment on it.
host computer The 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 instantiation­information (.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 intrinsic­routines 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 control­variable 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:
Suffix Meaning
.c A C or C++ (for apCC) source program. .C A C++ source program.
Apogee User’s Manual Page 23
Page 24
Apogee Software, Inc.
.CC A C++ source program. .cc A C++ source program. .C++ A C++ source program. .c++ A C++ source program. .CXX A C++ source program. .cxx A C++ source program. .cpp A C++ source program. .i A C or C++ source program that has already been preprocessed. .f For apf77, a FORTRAN-77 source program. For apf90, a Fortran 90
source program in fixed format.
.for Same as .f. .F For apf77, a FORTRAN-77 source program that should be
preprocessed by the C preprocessor before compilation. Not supported by apf90 in this release.
.f90 A FORTRAN 90 source program in free format. .F90 Not supported in this release. .inc A Fortran 90 include file. If the first letter is an upper-case ’V’ the file
may have been created by apf90.
.inf A Fortran 90 interface file. .s An assembly source program. .o A relocatable object file. .vo A Fortran 90 intermediate binary 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.
-c Stop the compilation before invoking the link editor, leaving the .o
files in the current directory.
-C Retain comments in the C preprocessor output.
-cg87 Compile 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.
-cg89 Compile instructions for the old SPARC cpu’s with square root but
-cg92 Compile instructions for SPARC cpu’s meeting the version 8
-cg94 Compile instructions for SPARC cpu’s meeting the version "v8plus"
-Dstring (There must not be whitespace between -D and string.) Define names.
-dalign Assume that double word objects referred to indirectly will always be
-dryrun Write, to stderr, the name and arguments for each process that
-E Write preprocessor output to stdout and stop the compilation. When
-fast This is an abbreviation for -O -dalign -native. It provides a
-g Include 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 FORTRAN­77 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.
-H Write 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.
-K Accept the Kernighan&Ritchie (K&R) dialect of C. This is an
-keeptemp Do 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
-M Write make dependencies to stdout and stop the compilation. Any
-M1 ("1" = one.) Like -M but do not emit dependencies for include files
-native This is an abbreviation for -Xcg=native.
-noex This is an abbreviation for -Xc-=exceptions.
-nolib Suppress 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. 1 Local (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.
-P This 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.
-p Set 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
-PIC Generate Position Independent Code. This is an abbreviation for
-pic Generate Position Independent Code, assuming that the Global Offset
-S Stop the compilation before invoking the assembler and leave all of the
-target word Ignored. Included for compatibility reasons.
-u In FORTRAN 77/90, process declarations as if there were an
-Uname (There must not be whitespace between -U and name.) This option
-v Write to stderr, the name and arguments for each process that is
-V Write the version numbers of each process invoked to stdout.
-verbose Write to stderr, the name and arguments for each process that is
-w Suppress 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".
p C/C++ preprocessor k Kuck & Associates preprocessor (KAP) v Pacific-Sierra Research preprocessors (VAST), including
VAST/f90
Page 30 Apogee User’s Manual
Page 31
Chapter 2: Invoking the Compilers
Options
f front-end i interprocedural analyzer b back-end (optimizer/code generator) a assembler l link editor
-where Write to stderr, a trace of the process of locating the license file and
the other processes of the compiler.
-xF Put 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 control­program 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,dir Specify 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:
p C/C++ preprocessor k Kuck & Associates preprocessors (KAP) v Pacific-Sierra Research preprocessors (VAST), including
VAST/f90
f front-end i interprocedural analyzer b back-end (optimizer/code generator) a assembler l link editor S directory containing the startup routines. I default include directory L first default library directory searched by ld(1). U second 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 pre­processor. 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 scope­point, 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 control­expressions. 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-to­right. 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=2 mopt2
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=4 O4
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 second­default-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 "∆"):
mopt=3,inline=joe+pete inline=joe+pete,mopt=3 mopt=3∆inline=joe+pete inline=joe+pete∆mopt=3
mopt=3inline=joe+pete inline=joe+pete∆mopt3
mopt3inline=joe+pete inline=joe+pete,mopt3
etc. etc.
To extend this example, if an assignment of 3 to control-group O was also needed, any of the following forms are permissible:
O=3,mopt=3,inline=joe+pete inline=joe+pete,mopt=3,O=3
O3mopt=3∆inline=joe+pete inline=joe+pete,mopt=3O=3 mopt=3O=3inline=joe+pete inline=joe+pete,O=3mopt=3
O3mopt3inline=joe+pete inline=joe+pete,mopt3O3
etc. etc.
Page 38 Apogee User’s Manual
Page 39
Chapter 3: Control-Variables and Control-Programs
Writing Pragma Directives
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
the following grammar:
control-program: := control-assign-list
control-assign-list: := control-assignment | control-assign-list [ separator ] control-assignment
{Constraint: the separator is optional only when the control-assignment-list ends with an integer-value.}
separator: := "," | "∆"{Note: ∆ denotes the blank character.}
control-assignment: := control-variable-name [ [ "=" ] control-expression ] |
control-group-name [ [ "=" ] control-expression ] {Constraint: when the control-expression is present, the "=" is optional
only when the control-expression begins with an integer-value.}
control-variable-name: := {One of the control-variable names listed in Chapters 4 and 5.}
control-group-name: := {One of the control-group names listed in Chapters 4 and 5.}
control-expression: := term |control-expression plus-op term
term: := integer-value | name | pair
integer-value: := digit | integer-value digit
digit: := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
name: := name-value | "%all" | "%none" |"%"control-variable-name
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 control­groups.
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) 1 A = 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 + B int i,j; Y = C - D . . . . . . x = a + b; U(6) = E*F y = c - d; V(J) = G*H . . . . . . p.u[5] = e*f; U(I) = G/H p.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=0 Alias 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=1 Alias 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=2 Alias 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 numerically­based programs, particularly those that use multidimensional arrays in inner loops; it is less important or not useful for other programs.
-Xalias=3 or 4 Alias 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.
Control-Variable callmod — Call Modification Analysis
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=0 No call modification analysis; assume each call references/modifies everything.
-Xcallmod=1 Intraprocedural 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=2 Interprocedural 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-default­value 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=0 Do not do cross-iteration hoisting.
-Xcih=1 Do cross-iteration hoisting.
The cih control-variable has routine scope and accepts values of 0 or 1. The first-default­value 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=0 Do not do constant propagation.
-Xconstp=1 Do local constant propagation.
-Xconstp=2 Do 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=0 Do not do copy propagation.
-Xcopyp=1 Do local copy propagation.
-Xcopyp=2 Do 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=0 Apply the main optimizations to each outermost loop separately.
-Xdomain=1 Apply the main optimizations to the whole routine.
The domain control-variable has routine scope, accepts values of 0 and 1. The first-default­value 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=0 Do not do forward code motion.
-Xfcm=1 Do forward code motion for loops without conditional control flow.
-Xfcm=2 Do 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=0 Assume that none of the control-variables in control-group O will increase past the values given to them on the command line, so time­saving 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=1 Assume 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 first­default-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=0 Do not do control flow optimization.
-Xflow=1 Do 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*Z X*(Y+Z)
X/Y/Z X/(Y*Z)
X/2.0 0.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=0 Do no rearrangement of floating point expressions that may change the result of the expression. This applies to all languages.
-Xfltacc=1 In 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=2 Permit 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 first­default-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 non­numeric value.
Some control of this situation is offered by the fltedge control-variable. Specifically:
-Xfltedge=1 Do no optimization that changes the behavior of the program if non­numeric 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=2 Do optimizations that may change the behavior of the program if non­numeric values occur and are used in quiet computations, but do not optimize the special case of testing a variable for equality or non­equality to itself. (This mode is provided to permit normal optimization, but also to provide the ability to program a test for non­numeric values).
-Xfltedge=3 Do optimizations that may change the behavior of the program if non­numeric values occur and are used in quiet computations.
The fltedge control-variable has routine scope and accepts values of 1 through 3. The first­default-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 floating­point constants by the fltfold control-variable, as follows:
-Xfltfold=0 During compilation, do not evaluate expressions involving floating­point constants.
-Xfltfold=1 During compilation, evaluate expressions involving floating-point constants and arithmetic operators, but do not evaluate expressions involving intrinsic functions applied to floating point constants.
-Xfltfold=2 During compilation, evaluate expressions involving floating-point constants.
The fltfold control-variable has routine scope and accepts values of 0 through 2. The first­default-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=0 Assume that integer overflow can occur during integer operations. Do no optimization that would change the program behavior if it does occur.
-Xintedge=1 Assume 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 first­default-value is intedge=0 and the second-default-value is intedge=1.
Control-Variable ivrep — Induction Variable Replacement
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=0 Do not attempt induction variable replacement optimizations.
-Xivrep=1 Attempt to perform induction variable replacement optimizations.
The ivrep control-variable has routine scope and accepts values of 0 and 1. The first-default­value 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-default­value and second-default-values are both 0.
n If 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=0 Do not do any of the main optimizations.
-Xmopt=1 Do the main optimizations locally.
-Xmopt=2 Do the main optimizations locally and globally on a flow-free basis.
-Xmopt=3 Do the main optimizations globally.
-Xmopt=4 Do 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=0 Do not allocate register-candidate variables to registers.
-Xreg=1 Allocate 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=2 Allocate register-candidate variables to registers, and do interprocedural and global and local register allocation, but without reordering routines for interprocedural allocation.
-Xreg=3 Allocate 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.
Control-Variable safeintr — Intrinsic Error Checking
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 intrinsic­routines 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=0 Assume that the normal error checking must be done in intrinsic routines.
-Xsafeintr=1 Assume 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 first­default-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=0 Do not schedule instructions.
-Xsched=1 Schedule instructions using pass 1 only.
-Xsched=2 Schedule 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=0 Do not unroll loops.
-Xunroll=1 Unroll loops under automatic control.
-Xunroll=n where 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.
Control-Variable unrollexact — Loop Unrolling Exactness
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 "fix­up" 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 first­default-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=0 Do not assume the whole source program is present in this compilation.
-Xwhole=1 Assume 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 non­standard 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 first­default-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 control­variable. Specifically:
-Xxopt=0 Do not do any extra optimizations.
-Xxopt=n where 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=0 Do not do the zone expansion optimization.
-Xzone=1 Attempt 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=0 By default, do not inline intrinsic-routines.
-Xdeflib=1 By default, inline intrinsic-routines under automatic
control.
-Xdeflib=2 By default, inline intrinsic-routines whenever possible.
6) For user routines, the call site value of the inllev control-variable. This control­variable accepts the following values:
-Xinllev=0 Do not do inlining of user routines.
-Xinllev=n where 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 first­default-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-default­value 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:
% apcc -O -p foo.c % ./a.out % prof -a -n a.out > PROF.OUT % apcc -O5 -Xinline=%profile30,pstat=PROF.OUT foo.c
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 first­default-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=0 No optimization.
-XO=1 Local optimization only.
-XO=2 O=1, plus variables may reside in registers, intraprocedural global
optimization, and scheduling.
-XO=3 O=2, plus more extensive global optimizations.
-XO=4 O=3, plus interprocedural global optimization and inlining.
-XO=5 O=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=87 Limit 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=89 Limit 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=92 Limit 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=94 Limit 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.
Control-Variable pipe — Target Computer Instruction Pipeline
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=iu3 Assume the target pipeline is the FJ MB86903 chip.
-Xpipe=super Assume the target pipeline is the TI TMS390Z50 (SuperSPARC) chip.
-Xpipe=super2 Assume the target pipeline is the SuperSPARC II chip.
-Xpipe=hyper Assume the target pipeline is the CY 7C620 (hyperSPARC) chip.
-Xpipe=micro Assume the target pipeline is the TI TMS390S10 (MicroSPARC) chip.
-Xpipe=micro2 Assume the target pipeline is the MicroSPARC II chip.
-Xpipe=ultra Assume 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 second­default-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:
-Xcg=89,pipe=iu2fpu5 -XKchs=64,0 -XKchl=32,0 -XKsasc=1
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.
Remark A remark message diagnoses some language usage that the compiler
will accept, but that the compiler regards as unconventional usage.
Warning A 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
Error An 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 Error A 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 Error An 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=0 Output only error and fatal error messages. Do not output remark or
warning messages.
-Xdiag=1 Output only warning, error, and fatal error messages. Do not output
remark messages.
-Xdiag=2 Output 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-default­value 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=0 Exit abnormally (exit status=1) if error or fatal error message situations
were encountered, exit normally otherwise.
-Xquit=1 Exit abnormally (exit status=1) if warning or error or fatal error message situations were encountered, exit normally otherwise.
-Xquit=2 Exit 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 first­default-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=0 Do not output standard messages, i.e., accept the normal extensions to the ANSI language without comment.
-Xstddiag=1 Output standard messages for (nearly all of) the language situations encountered that are extensions to the ANSI standard.
-Xstddiag=2 Output 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 first­default-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:
Column Meaning
1 Comment indicator if C or *.
1..5 Statement label (numeric). 6 Continuation indicator (indicates initial line if blank, or continuation
line if non-blank).
7..72 Statement.
73..80 Ignored (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.
Apogee User’s Manual Page 65
Page 66
Apogee Software, Inc.
Control-Variable fblank — FORTRAN Statement Blanks
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=0 Do not pad short lines with blanks.
-Xfblank=1 Pad 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 fblank control-variable. VAST input uses the behavior of fblank=1, unless -ef is given to allow free format input..
Control-Variable fcols — FORTRAN Statement Columns
The fcols control-variable is used to indicate the number of columns scanned for statement information. Specifically:
-Xfcols=0 The whole line is scanned for statement information — no characters in the line are ignored, regardless of the line length.
-Xfcols=n where 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 second­default-value is fcols=0. If you are using KAP, you should not use the fcols control­variable. 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 132­column 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=0 Tab-format lines are not accepted. They generate an error message.
-Xftab=1 Tab-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-tab­format 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=2 Tab-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 are using 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=classic Which 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=sun72 Which means fcols=72, ftab=2, fblank=1. This mode provides the SunSoft FORTRAN default mode. This mode is the first-default­value for each of these control-variables and is thus the default mode of the compiler.
-XF=sun132 Which means fcols=132, ftab=2, fblank=1. This mode provides the SunSoft FORTRAN "-e" mode.
-XF=svs72 Which means fcols=72, ftab=0, fblank=0. This mode provides the SVS FORTRAN 72-column mode, and the MIPS FORTRAN "-col72" mode.
-XF=svs120 Which means fcols=120, ftab=0, fblank=0. This mode provides the SVS FORTRAN default mode and the MIPS FORTRAN "-col120" mode.
-XF=normal Which 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=vax72 Which means fcols=72, ftab=1, fblank=1. This mode provides the VAX FORTRAN default mode and the MIPS FORTRAN "-noextend_source" mode.
-XF=vax132 Which means fcols=132, ftab=1, fblank=1. This mode provides the VAX FORTRAN "/EXTEND_SOURCE" mode and the MIPS FORTRAN "-extend_source" mode.
-XF=mips72 Which means fcols=72, ftab=2, fblank=0. This mode provides the MIPS FORTRAN default mode.
-XF=unix72 Which 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=unix Which 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 second­default-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.
Control-Variable fcont — FORTRAN Continuation Lines
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=0 Compile with case-insensitive treatment of identifiers.
-Xcase=1 Compile 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=0 Treat lines with D or d or X or x in column 1 as comments.
-Xdline=1 Treat 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-default­value 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 backward­compatible fixed-form style. This behavior can be explicitly overridden by the sform control­variable 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=0 Use 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=1 Assume fixed-form source lines, regardless of file suffix.
-Xsform=2 Assume 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=0 Deviate 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=1 Do 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 first­default-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=4 Do single precision complex multiplies in single precision, in spite of the potential for loss of significant bits.
-Xcmul=8 Do 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=0 Apply the name transformation for C global data symbols to common block names.
-Xcomname=1 Apply 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=2 Apply 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-precision­sensitive 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 DOUBLE PRECISION, 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:
n Compile variables declared as real using length n, n=4|8|16, 1st
r:
default 4, 2nd default 8.
r4:
n Compile variables declared as real*4 using length n, n=4|8|16, 1st
default 4, 2nd default 4.
d:n Compile variables declared as double precision using length n,
n=4|8|16, 1st default 8, 2nd default 16.
r8:n Compile variables declared as real*8 using length n, n=4|8|16, 1st
default 8, 2nd default 8.
r16:n Compile variables declared as real*16 using length n, n=4|8|16,
1st default 16, 2nd default 16.
i:n Compile 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:n Compile 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:n Compile 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:n Compile 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:n Compile 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:n Compile 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:n Compile 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:n Compile 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 option Apogee 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.
Control-Variable implicit — Assumed Implicit None Statement
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=0 The program is processed as if an IMPLICIT NONE statement were
present, whether or not there is actually one present.
-Ximplicit=1 The program is processed normally.
The implicit control-variable has routine scope and permits values of 0 and 1. The first­default-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=0 The loop will execute zero times when the trip count is zero (the
FORTRAN-77 language).
-Xonetrip=1 The 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-default­value 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 save­usage 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=0 Do not provide an implicit global SAVE statement.
-Xsave=1 Provide 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 register­based 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-default­value 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=recl In 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=quote In 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=bslash In 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=param In 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=ansi In 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=knr In 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=mixed In 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=arm In this mode the compiler accepts the C++ language as defined in The
Annotated Reference Manual
and will track the ANSI standard being developed.
-Xc=cp Similar 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=cfront In 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
#ifndef _BOOL_DEFINED typedef unsigned char bool; #define _BOOL_DEFINED 1 #endif
Page 82 Apogee User’s Manual
Page 83
Chapter 4: Control-Variable Definitions
C/C++ Compilation
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=signed The representation for char is the same as signed char.
-Xchar=unsigned The representation for char is the same as unsigned char.
Bit fields of type int are similarly left "implementation-defined" in ANSI C/C++. Apogee­C/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=uint The definition for size_t is unsigned int.
-Xsizet=ulong The definition for size_t is unsigned long.
-Xsizet=ushort The definition for size_t is unsigned short.
-Xwchart=uint The 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=int The definition for wchar_t is int.
-Xwchart=long The definition for wchar_t is long.
-Xwchart=short The definition for wchar_t is short.
-Xwchart=char The 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 single­precision arithmetic cannot be utilized in K&R programs unless the fltdbl control-variable is used, as follows:
-Xfltdbl=0 For C in c=knr mode, perform arithmetic on float objects in single­precision, 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=1 For C in c=knr mode, perform arithmetic on float objects in single­precision, 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=2 For 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 first­default-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=0 Do not join together the C source files passed to the compiler.
-Xjoin=1 Join 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 first­default-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=none In 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=used In 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=all In 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. Non­member template functions will be instantiated even if the only occurrence was a declaration.
-Xtmpl=local This 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=retry This 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+noautoincl The 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=DATA Generate absolute reference to items in data space.
-Xaddr=PIC Generate position-independent code.
-Xaddr=pic Generate 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=0 Assume that double-word objects referred to indirectly will always be
properly aligned, so double-word load and store instructions can be used.
-Xalnref=1 Assume 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 first­default-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=0 All data will be placed in the .data section.
-Xbss=1 Static 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=2 Static 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 first­default-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).
Apogee User’s Manual Page 93
Page 94
Apogee Software, Inc.
Consider the following program fragment:
DOUBLE PRECISION D1, D2, D3 D1 = 1.231 D2 = 1.232E0 D3 = 1.233D0
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=0 For 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=4 Implement single precision floating point constants with single precision accuracy.
-Xfltconst=8 Implement 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 first­default-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=0 Do not include symbolic debugging information in the assembly files.
-Xg=1 Include 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=2 Include 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 first­default-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=g2 Use global-register g2 in compiled code.
-Xglbreg=g3 Use global-register g3 in compiled code.
-Xglbreg=g4 Use global-register g4 in compiled code.
-Xglbreg=g5 Use global-register g5 in compiled code.
-Xglbreg=g6 Use global-register g6 in compiled code.
-Xglbreg=g7 Use global-register g7 in compiled code.
-Xglbreg=appl Use the global-registers which the SPARC ABI reserves for the
application, i.e., g2, g3, and g4.
-Xglbreg=syst Use 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.
combination The 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=no Do not run the KAP preprocessor on this file.
-Xkap=sp Run the KAP preprocessor on this file.
-Xkap=mp Run 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 first­default 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=0 Do not set up for profiling.
-Xprof=1 Set 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=2 Set 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 first­default-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=0 Put all routines in the same text section.
-Xrelfunc=1 Put each routine in a separately relocatable text section.
The relfunc control-variable has routine scope and accepts values of 0 and 1. The first­default-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=no Do not run the VAST preprocessor on this file.
-Xvast=sp Run the VAST preprocessor on this file.
-Xvast=mp Run 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 first­default value is vast=no and the second-default value is vast=sp.
Properties of Variables
Control-Variables volatile, defvol, ptrvol — Volatile Variables
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 control­variables 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=ptr all pointer references are “pointer to volatile”.
-Xdefvol=stat all static variables are volatile.
-Xdefvol=glob all 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=files Announce progress at the start of compiling each file.
-Xprogress=functions Announce progress at the start of compiling each function.
-Xprogress=phases Announce progress at the start of each phase of the
compiler.
-Xprogress=subphases Announce progress at the start of each subphase of the compiler.
-Xprogress=actions Announce progress at each major action (e.g. inlining) done by the compiler.
-Xprogress=failures Announce the failure of each major action (e.g. failed to inline a routine) attempted by the compiler.
-Xprogress=templates Announce instantiations of template functions.
-Xprogress=memory Include compiler memory-usage information in progress
announcements.
-Xprogress=sizes Include information on the size of internal compiler data structures in progress announcements.
-Xprogress=realtime Include the realtime used by the compiler in progress announcements.
-Xprogress=rtime Include the realtime used by the compiler in progress announcements (same as realtime).
-Xprogress=usertime Include the usertime used by the compiler in progress announcements.
-Xprogress=utime Include the usertime used by the compiler in progress announcements (same as usertime).
-Xprogress=%all Announce progress at all possible points of compilation.
-Xprogress=%none Do 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...