C Language Software Release Document
Software Release 9.6
Part No. 05500
Revision 06
This document describes the C compiler
for DOMAIN software release 9.6.
APOLLO COMPUTER INC.
330 Billerica Road
Chelmsford, Massachusetts 01824
Copyright c 1987 Apollo Computer Inc.
All rights reserved. Printed in U.S.A.
First Printing: May, 1987
Latest Printing: May, 1987
This document was formatted using the FMT tool distributed with the DOMAIN
computer system.
APOLLO and DOMAIN are registered trademarks of Apollo Computer Inc.
AEGIS, DGR, DOMAIN/BRIDGE, DOMAIN/DFL-100, DOMAIN/DQC-100, DOMAIN/Dialogue,
DOMAIN/IX, DOMAIN/Laser-26, DOMAIN/PCI, DOMAIN/SNA, D3M, DPSS, DSEE, GMR, and
GPR are trademarks of Apollo Computer Inc.
Apollo Computer Inc. reserves the right to make changes in specifications and
other information contained in this publication without prior notice, and the
reader should in all cases consult Apollo Computer Inc. to determine whether
any such changes have been made.
THE TERMS AND CONDITIONS GOVERNING THE SALE OF APOLLO COMPUTER INC. HARDWARE
PRODUCTS AND THE LICENSING OF APOLLO COMPUTER INC. SOFTWARE CONSIST SOLELY OF
THOSE SET FORTH IN THE WRITTEN CONTRACTS BETWEEN APOLLO COMPUTER INC. AND ITS
CUSTOMERS. NO REPRESENTATION OR OTHER AFFIRMATION OF FACT CONTAINED IN THIS
PUBLICATION, INCLUDING BUT NOT LIMITED TO STATEMENTS REGARDING CAPACITY,
RESPONSE-TIME PERFORMANCE, SUITABILITY FOR USE OR PERFORMANCE OF PRODUCTS
DESCRIBED HEREIN SHALL BE DEEMED TO BE A WARRANTY BY APOLLO COMPUTER INC. FOR
ANY PURPOSE, OR GIVE RISE TO ANY LIABILITY BY APOLLO COMPUTER INC.
WHATSOEVER.
IN NO EVENT SHALL APOLLO COMPUTER INC. BE LIABLE FOR ANY INCIDENTAL,
INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING BUT NOT
LIMITED TO LOST PROFITS) ARISING OUT OF OR RELATING TO THIS PUBLICATION OR
THE INFORMATION CONTAINED IN IT, EVEN IF APOLLO COMPUTER INC. HAS BEEN
ADVISED, KNEW OR SHOULD HAVE KNOWN OF THE POSSIBILITY OF SUCH DAMAGES.
THE SOFTWARE PROGRAMS DESCRIBED IN THIS DOCUMENT ARE CONFIDENTIAL INFORMATION
AND PROPRIETARY PRODUCTS OF APOLLO COMPUTER INC. OR ITS LICENSORS.
Reader_Notice
This document resides on line in the /doc directory. To print a copy of this
document, use the PRF command with the -npag and -pr options.
PRF <file_pathname> -PR <printer_name> -NPAG
iii
Contents
Section Page
CHAPTER 1 OVERVIEW OF DOMAIN C Language SR 9.6 . . . . . . . . . . 1-1
1.1 Choosing a Version . . . . . . . . . . . . . . . . . . . 1-1
1.2 New Features . . . . . . . . . . . . . . . . . . . . . . 1-1
1.2.1 -CPU FPX Compile Option . . . . . . . . . . . . . . 1-1
1.2.2 C Help File . . . . . . . . . . . . . . . . . . . . 1-2
CHAPTER 2 SOFTWARE INSTALLATION PROCEDURES . . . . . . . . . . . . 2-1
CHAPTER 3 DOCUMENTATION . . . . . . . . . . . . . . . . . . . . . 3-1
3.1 New Error Messages . . . . . . . . . . . . . . . . . . . 3-7
CHAPTER 4 BUGS AND BUG FIXES . . . . . . . . . . . . . . . . . . . 4-1
4.1 Bugs Fixed Since SR9.5 . . . . . . . . . . . . . . . . . 4-1
Contents iv
CHAPTER 1
OVERVIEW OF C at SR9.6
This document describes changes to the C compiler made between the last
release (SR9.5.1) and this release (9.6). In some instances, you may need to
know about changes made between SR9.2 and SR9.5.1. For information about
these changes, read the SR9.5 C Release Notes (05500, rev. 05), which are
also supplied with this release.
1.1 Choosing a Compiler Version
If you are developing programs to run on systems that are running the SR9.2
version of the operating, you will want to compile your programs with the
SR9.2 version of the C compiler. When you install the SR9.6 C compiler, you
will also get the SR9.2 compiler. If you need to use the older version,
compile your file(s) with the following command:
$ ccsr9.2 filename [-options]
To compile with the SR9.6 version, use the usual command; that is:
$ cc filename [-options]
1-1 C Release at SR9.6
1.2 New Features
The SR9.6 version of the C compiler supports several new features added since
SR9.5:
o The DOMAIN C compiler supports a new compile option, -CPU FPX, that
takes advantage of the floating-point accelerator (FPX) unit on
DN570-T and DN580-T machines.
o The help file for the C compiler now reports the software release
number rather than the compiler version number.
1.2.1 -CPU FPX Compile Option
At SR9.6, the DOMAIN C Compiler supports a new compile option, -CPU FPX, for
programs that will run on DN570-T(urbo) and DN580-T(urbo) machines. The
format of the new switch conforms to other -CPU options. For example:
cc test.c -CPU FPX
The -CPU FPX option causes the compiler to produce object code that takes
advantage of the floating-point accelerator (FPX) unit n DN5xx-T computers.
You may run programs on DN5xx-Ts without using the -CPU FPX compile option,
but these programs will not enjoy the full performance benefits of the FPX
unit. If you attempt to run a program compiled with the -CPU FPX switch on a
machine that does not have an FPX unit, you will receive a runtime error.
One caveat concerning programs compiled with the -CPU FPX switch is that the
the address of an instruction for a floating-point fault is not stored in the
Instruction Address register (IADDR) as it is for programs compiled with the
-CPU 330 and -CPU 3000 switches. Consequently, fault handlers should not
rely on this address when code is compiled with -CPU FPX. This warning
applies only to assembly language fault handlers.
1.2.2 C Help File
At SR9.6, the help file for this compiler contains a release number (SR9.6)
in its header. At previous releases, the compiler help file contained a
compiler version number, such as 7.09, in its header. We have incorporated
the release number so that you can easily see the software release to which
the help file applies.
C Release at SR9.6 1-2
You can determine the individual compiler version number, such as 7.09, by
using the compiler's -version option. Please use the compiler version number
if you submit a User Change Request (UCR) or call our Customer Support
Center.
1-3 C Release at SR9.6
CHAPTER 2
INSTALLATION INFORMATION
You can add DOMAIN cc to a user node (one equipped with monitor and keyboard)
or a DOMAIN server processor (DSP) that is running SR9.6 or a more recent
version of the AEGIS or DOMAIN/IX operating system. If the user node or DSP
is not running SR9.6 or a more recent version, follow the appropriate
software update procedures as described in Installing_DOMAIN_Software (Order
No. 008860) or in the appropriate release notes.
For directions about how to install this product, see the manual Installing
DOMAIN_Software, (Order No. 008860).
NOTE: The user node or DSP must have a minimum of 1700 blocks of
available disk space for a successful installation of this
software.
2-1 C Release Notes
CHAPTER 3
DOCUMENTATION
The current DOMAIN__C__Language_Reference manual (Order No. 002093, Rev. 03)
reflects the compiler released at SR9.2. Changes in the compiler between
SR9.2 and SR9.5 are documented in the C_Language_Software_Release_Document
for SR9.5 (Order No. 05500, Rev. 04). New features at SR9.6 are documented
in Chapter 1 of these release notes. In addition, you should replace
Section 6.2.17 of the manual with the following text. Note that this new
section does not reflect new functionality -- it is merely an improved
description of old functionality.
6.2.17 -Opt : Optimized Code
The -opt 3 option is the default.
The -opt option allows you to specify the kinds of optimization performed on
your source program, by means of an "optimization level." The syntax for the
-opt option is:
-opt n
where n is an integer between 0 and 4 that represents the optimization
level. At -opt 0, very few optimizations are performed. For each higher
optimization level, more optimizations are performed. If you specify -opt
and omit the optimization level, the level defaults to -opt 3. If you omit
the -opt option completely, the default option, -opt 3, is assumed. The
obsolete option -nopt is equivalent to -opt 0.
Each higher level of optimization includes all optimizations performed at
the lower levels of optimization. Because the compiler does more work at
each higher level of optimization, it often takes progressively longer to
compile your program at each successive optimization level. If you are just
beginning to develop your program, and are compiling mainly to find syntax
errors, you may want to compile using a low optimization level to reduce the
time required to compile your program. When you are ready to test the
execution of your program, you can compile with a higher optimization level
to get the maximum advantage of all the optimizations.
3-1 C Release at SR9.6
It is important to note that the -dba option overrides anything you specify
for the -opt option. If you want your code to be optimized, and want to use
the debugger on your program, you should use the -dbs option rather than
-dba. When you specify -dba, the -opt option is set to -opt 0, regardless
of what you specified for -opt on the command line for the compilation. In
addition, -dba represents an even lower level of optimization than -opt 0.
NOTE:If you wish to use the Debugger (described in the "Debug" section of
this chapter) to debug a program compiled at -opt 3 or -opt 4, you may find
that you are unable to examine the values of some local variables at points
in the source code where those variables are not actively in use. This
happens because the value of the variable is assigned to a machine register,
rather than being kept in the computer's main memory. The optimizer may
decide that the main memory location for this variable does not need to be
updated, because all uses of the variable in the source program can legally
use the value of the variable that is retained in the machine register. In
addition, the optimizer may merge some source statements together, or
eliminate source statements entirely, when legal to do so. When you are
debugging with these optimizations, you may see what appear to be strange
jumps in the control flow of the program. In addition, you may be unable to
set a breakpoint at a particular source line because the generated code for
that source line has been optimized away or merged with the code from
another source line. It can be slightly more difficult to use the debugger
with optimized code, but there is no reason to avoid using debug with the
optimization levels discussed here. See the DOMAIN_Language__Level_Debugger
Reference for more details concerning the use of the debugger.
The following is a brief description of the optimizations performed at each
optimization level. For a detailed discussion of compiler optimization
techniques, consult a general compiler textbook.
-dba represents the lowest possible optimization level. It forces the
-opt option to be -opt 0, and additionally suppresses some
optimizations that are normally performed at -opt. In particular,
the -dba option forces the compiler to store machine registers in
main memory after every statement. Even with the -dba option,
however, some optimizations are still performed. For example, the
compiler may:
o rearrange expressions to minimize the number of registers
needed to compute the expression.
o generate faster short range branch instructions in place of
long branches where possible.
o compute constant expressions that appear in the source code,
such as 2*3, rather than generating code to compute them.
o compute multiple occurrences of the same expression only
once.
C Release at SR9.6 3-2
Another example of simple constant folding performed at this level
is shown by the following example:
unsigned char small_range;
.
.
if (small_range < 0)
.
.
In this example, smallrange can never be less than zero, because of
its type. The compiler will therefore substitute the value FALSE for
the expression "small_range < 0". The expression,
if FALSE
means that the statements following if cannot be executed, so the
compiler will not generate code for them.
-opt 0 performs the optimizations described above. If -dba is not also
set, the compiler will permit values to remain in registers across
statements where it is legal to do so. Additionally, a sequence of
generated code that is identical to another sequence may have all
its instructions replaced by a branch to the other identical
sequence of instructions.
-opt 1 performs the following optimizations:
o Eliminates limited global "common subexpression."
o Eliminates "dead code."
o Transforms integer multiplication by a constant into shift
and add instructions rather than using direct multiply,
where appropriate.
o Performs simple transformations for speed.
p Merges assignment statements where possible.
A "common subexpression" is an expression that appears two or more
times in the program, with no intervening assignments to any
component of the expression. In such cases, the expression need only
be computed once, and the other occurrences of the expression can be
replaced with the resulting value. "Dead code" is code that cannot
be executed because there is no execution path of the program that
3-3 C Release at SR9.6
leads to the code.
-opt 2 performs the following optimizations:
o Substitutes constants for "reaching" definitions.
o Folds global constants.
Assigning to a variable, or using the variable as parameter in a
function call, produces a "definition" of the variable. A particular
definition of a variable is said to "reach" later uses of the
variable if there are no other definitions between the original
definition and the use of the variable. If the definition is an
assignment of a constant to the variable, uses of the variable that
are "reached" by the definition can be replaced with the constant
value. As constants are substituted for variable uses, the
expressions in which the variable uses occurred are sometimes
transformed into constant expressions that can be evaluated during
compilation. This eliminates the need to generate code to compute
the value of the expression. For example, in the statements,
a = 3;
c = 2 * a;
there are no other definitions of the variable a between the
original assignment and the use of a in the expression 2*a. So the
compiler can substitute the value 3 in the expression 2*a. The
expression then becomes 2*3, which is computed during compilation.
As a result, the program does not perform a multiply when it
executes. Instead, it merely assigns the already computed value 6 to
c.
-opt 3 is the default optimization level. At this level, the compiler
performs the following optimizations:
o live analysis on local variables.
o redundant assignment statement elimination.
o global register allocation.
o instruction reordering.
o removal of invariant expressions from loops.
o exhaustive searches through each routine for global common
subexpressions to eliminate.
The -opt 1 and -opt 2 levels make only limited searches through the
C Release at SR9.6 3-4
code for global common subexpressions.
Performing "live analysis" of local variables involves determining
the areas of a routine where a variable is actively used. For
example,
.
.
j = k;
if (i = 0)
{
i = 2;
j = 3 * j;
}
else
{
k = i * 4;
printf("%d", k);
}
.
.
In the else clause of the example, there are no uses of j. If there
are no further uses of the variable j on any execution path from the
else clause to the end of the program, j is not actively used in the
else clause and on execution paths from the else to other parts of
the routine. j is therefore considered "dead" from the statement
following the else to the end of the routine. Within the then
clause, there is a use of j. Therefore, j is actively used within
the then clause, and is considered "live" within the then clause. If
there are other uses of j that can be reached from the then clause,
j is considered "live" along the paths that lead to those uses. Live
analysis is important because it allows the compiler to allocate
local variables to machine registers for exactly as long as the
variable's value is needed. When the variable becomes "dead", the
register can be used for other variables or expression values. In
general, referencing a value in a register is faster than
referencing a value in the computer's main memory. Efficient use of
registers increases the execution speed of your program.
"Redundant assignment elimination" performed at this optimization
level may result in warning messages such as the following:
******** Line 14: [Warning 279] Value assigned to SMALL_RANGE is
never used; assignment is eliminated by optimizer.
3-5 C Release at SR9.6
Consider the following example:
main()
{
int i, j;
fscanf("%d%d", &i, &j);
if (i == 0)
j = 3;
printf("%d", i);
}
There are no uses of the variable j after the assignment j=3. Since
the value assigned to j is not used, the compiler can eliminate the
assignment completely without changing the result computed in the
program. In fact, once the assignment is eliminated, the if portion
of the statement isn't needed either, and can be eliminated. If we
change the example so that j is used after the assignment,
main()
{
int i, j;
fscanf("%d%d", &i, &j);
if (i == 0)
j = 3;
printf("%d\t%d", i, j);
}
the assignment is no longer eliminated.
"Global register allocation" allows variables that are local to a
routine to have their values placed in machine registers for faster
access. In many cases, all definitions and uses of a local variable
may occur in a register, and the copy of the variable in the
computer's main memory is never used or updated. Keeping variables
in registers makes your program execute faster. The global register
allocator treats the register variable declaration as advice, not as
a directive. Variables declared as register receive special
consideration for allocation to registers. However, if a variable is
declared as register, but is not used, it will not be allocated to a
register.
"Instruction reordering" changes the order in which some
instructions are executed to take advantage of overlaps that are
possible in some instruction sequences. Some integer instructions
can execute at the same time as some floating point instructions,
as long as the integer instructions do not depend upon the result
computed by the floating point instruction.
C Release at SR9.6 3-6
A "loop invariant expression" is an expression whose value does not
change during the execution of a loop. When invariant expressions
are computed outside a loop, they are only computed once, instead of
needlessly being computed on each pass through the loop. This makes
the loop execute faster, and generally increases program execution
speed. For example:
.
.
for (i=1; i <= 10; i++)
{
j = k * m;
j = i + j;
}
.
.
The expression k * m is invariant in the above example. The
compiler can safely transform this loop as follows:
.
.
temp = k * m;
for (i=1; i <= 10; i++)
{
j = temp;
j = i + j;
}
.
.
After the invariant expression is removed from the loop, the example
does only one multiply instead of 10 to make the assignment to j.
-opt 4 is identical to -opt 3 in the present compiler. Future releases
may use this level to perform other optimizations.
3.1 New Error Messages
In addition to the new features described in Chapter 1, the DOMAIN C compiler
supports some new error messages:
202 Value assigned to "VARIABLE" is never used; assignment eliminated by
optimizer.
3-7 C Release at SR9.6
203 Illegal declaration of "VARIABLE"; cannot have an array of functions.
204 Wrong size for enum "VARIABLE"; original size "SIZE" assumed.
205 Enumeration type clash ["VARIABLE", "VARIABLE"] to the "OPERATOR"
operator.
206 Address of array or function in this context is redundant and
ignored.
207 Illegal type "void" for argument arg1.
210 Exceeded maximum number of allowable parameters ( > 64).
C Release at SR9.6 3-8
CHAPTER 4
BUGS AND BUG FIXES
This chapter describes bugs fixed since SR9.5. There are no known bugs or
limitations in this release of the C compiler.
4.1 Bugs Fixed Since SR9.5
The following bugs that existed at SR9.5 have been fixed:
o Prior to this release, the C compiler could generate bad code in two
instances when you compiled with the -cpu 3000, -cpu 580, -cpu 570,
-cpu 560, -cpu 330, or -cpu 90 options. The first problem concerned
a structure in which a field was odd-aligned. For example, in the
following struct, the xx field is odd-aligned:
struct a { char dum1;
char xx;
int yy;
} *x;
If you assigned constant values to two fields in such a struct, the
optimizer might have incorrectly merged the assigments. This
problem has been fixed.
The second problem was that the compiler did not correctly generate
array references to multidimensional arrays if part of the
expression was parenthesized. For example:
(X[y])[z]
This problem has also been fixed.
o Prior to this release, the compiler sent error and warning messages
to stdout rather than stderr. This big has been fixed. Note,
however, that the final banner that reports the total number of
compile-time errors and warnings is still sent to stdout.
4-1 C Release at SR9.6
C Release at SR9.6 4-2