[an error occurred while processing this directive]

HP OpenVMS Systems

C Programming Language
Content starts here HP C

HP C
User's Guide for OpenVMS Systems


Previous Contents Index

Option2 controls whether or not external names greater than 31 characters get truncated or shortened. Table 1-14 lists the option2 values.

Table 1-14 /NAMES Qualifier Option2 Values
Option Usage
/NAMES=TRUNCATED (default) Truncates long external names.
/NAMES=SHORTENED Shortens long external names.

A shortened name consists of the first 23 characters of the name followed by a 7-character Cyclic Redundancy Check (CRC) computed by looking at the full name, and then a "$".

The CRC is generated by calling lib$crc as follows:

long initial_crc = -1;

crc_result = lib$crc(good_crc_table,
&initial_crc,
<descriptor of string to CRC>);
where good_crc_table is:
/*
** Default CRC table:
**
** This table was taken from Ada's
** generalized name generation algorithm.
** It represents a commonly used CRC
** polynomial known as AUTODIN-II.
** For more information see the VAX
** Macro OpenVMS documentation under the
** CRC VAX instruction.
*/
static const unsigned int good_crc_table[16] =
{0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC,
0x76DC4190, 0x6B6B51F4, 0x4DB26158, 0x5005713C,
0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C};

The default is /NAMES=(UPPERCASE,TRUNCATED), which provides the same conversion-to-uppercase behavior as VAX C, and truncates the name to 31 characters.

Notes

On OpenVMS VAX systems, the /NAMES qualifier does not affect the names of the $CODE and $DATA psects.

On OpenVMS Alpha systems, the /NAMES qualifier does not affect the names of the $ABS$, $BSS$, $CODE$, $DATA$, $LINK$, $LITERAL$, and $READONLY$ psects.

Specifying /NAMES=SHORTENED turns on the /REPOSITORY qualifier.

/NESTED_INCLUDE_DIRECTORY[=option]

Controls the first step in the compiler's search algorithm for finding files that are included using the quoted form of the #include preprocessing directive:


#include "file-spec" 

Table 1-15 describes the /NESTED_INCLUDE_DIRECTORY qualifier options.

Table 1-15 /NESTED_INCLUDE_DIRECTORY Qualifier Options
Option Usage
PRIMARY_FILE Directs the compiler to search the default file type for headers using the context of the primary source file (the .C file). This means that just the file type (".h" or ".") is used for the default file-spec, but the chain of "related file-specs" used to maintain the sticky defaults for processing the next top-level source file is also applied when searching for the include file. This most closely matches the behavior of VAX C.
INCLUDE_FILE Directs the compiler to first search the directory of the source file containing the #include directive. If the file to be included is not found, the compiler continues searching by following normal inclusion rules.
NONE Directs the compiler to skip the first step of processing #include " file.h" directives. The compiler starts its search for the include file in the /INCLUDE_DIRECTORY directories. It does not start by looking in the directory containing the including file or in the directory containing the top level source file.

The default is /NESTED_INCLUDE_DIRECTORY=INCLUDE_FILE.

/[NO]OBJECT[=file-spec]

Produces an object module. By default, /OBJECT creates an object module file with the same name as that of the first source file of a compilation unit and with the .OBJ file extension. If you include a file specification with /OBJECT, the compiler uses that specification instead.

The compiler executes faster if it does not have to produce an object module. Use the /NOOBJECT qualifier when you need only a listing of a program or when you want the compiler to check a source file for errors. The default is /OBJECT.

Note that the /OBJECT qualifier has no impact on the output file of the /MMS_DEPENDENCIES qualifier.

/[NO]OPTIMIZE[=(option[,...])]

Determines whether HP C performs code optimizations.

You can specify the options described in Table 1-16.

Table 1-16 /OPTIMIZE Qualifier Options
Option Usage
[NO]DISJOINT (VAX ONLY) Optimizes the generated machine code. For example, the compiler eliminates common subexpressions, removes invariant expressions from loops, collapses arithmetic operations into 3-operand instructions, and places local variables in registers.

When debugging HP C programs, use the /OPTIMIZE=NODISJOINT option if you need minimal optimization; if optimization during debugging is not important, use the /NOOPTIMIZE qualifier.

[NO]INLINE[= keyword] Provides inline expansion of functions that yield optimized code when they are expanded. You can specify one of the following keywords to control inlining:
NONE No inlining is done, even if requested by the language syntax.
MANUAL Inlines only those function calls for which the program explicitly requests inlining.
AUTOMATIC Inlines all of the function calls in the MANUAL category, plus additional calls that the compiler determines are appropriate on this platform. On Alpha systems, this is the same as SIZE; on I64 systems, this is the same as SPEED. AUTOMATIC is the default.
SIZE Inlines all of the function calls in the MANUAL category plus any additional calls that the compiler determines would improve run-time performance without significantly increasing the size of the program.
SPEED Performs more aggressive inlining for run-time performance, even when it might significantly increase the size of the program.
ALL Inlines every call that can be inlined while still generating correct code. Recursive routines, however, will not cause an infinite loop at compile time.

Note that /OPT=INLINE=ALL is not recommended for general use, because it performs very aggressive inlining and can cause the compiler to exhaust virtual memory or take an unacceptably long time to compile.

The #pragma noinline preprocessor directive can be used to prevent inlining of any particular functions under the compiler-selected forms of inlining (SPEED, SIZE, or AUTOMATIC).

The #pragma inline preprocessor directive (or the __inline storage-class modifier for OpenVMS Alpha systems) can be used to request inlining of specific functions under the AUTOMATIC or MANUAL forms of inlining.

[NO]INTRINSICS Controls whether or not certain functions are handled as intrinsic functions without explicitly enabling each of them as an intrinsic through the #pragma intrinsic preprocessor directive. An intrinsic function is an apparent function call that could be handled as an actual call to the specified function, or could be handled by the compiler in a different manner. By treating the function as an intrinsic, the compiler can often generate faster code. (Contrast with a built-in function, which is an apparent function call that is never handled as an actual function call. There is never a function with the specified name.)

See Section 5.4.10 for a list of functions that can be handled as intrinsics.

The /OPTIMZE=INTRINSICS qualifier works together with /OPTIMIZE=LEVEL=n and some other qualifiers to determine how intrinsics are handled:

  • If the optimization level specified is less than 4, the intrinsic-function prototypes and call formats are checked, but normal run-time calls are still made.
  • If the optimization level is 4 or higher, intrinsic code is generated.
  • If /STANDARD=ANSI89 is specified, nonstandard functions are not automatically intrinsic and do not even have their prototypes checked. They are only checked if the nonstandard functions are made intrinsic through #pragma intrinsic.
  • Intrinsic code is not generated for math functions that set the errno variable unless /ASSUME=NOMATH_ERRNO is specified. Such math functions, however, do have their prototypes and call formats checked.

The default is /OPTIMIZE=INTRINSICS, which turns on this handling.

To turn it off, specify /NOOPTIMIZE or /OPTIMIZE=NOINTRINSICS, or specify an optimization level less than 4.

LEVEL= n Selects the level of optimization. Specify an integer from 0 (no optimization) to 4 (full optimization):
0 Disables all optimizations. Does not check for unassigned variables.
1 Enables local optimizations and recognition of some common subexpressions. The call graph determines the order of compilation of procedures.
2 Includes level 1 optimizations. Enables global optimization. This includes data-flow analysis, code motion, strength reduction and test replacement, split lifetime analysis, and code scheduling.
3 Includes level 2 optimizations. Enables additional global optimizations that improve speed (at the cost of extra code size), for example: integer multiplication and division expansion (using shifts), loop unrolling, and code replication to eliminate branches.
4 Includes level 3 optimizations. Enables interprocedural analysis and automatic inlining of small procedures (with heuristics limiting the amount of extra code). This is the default.
5 Includes level 4 optimizations. Activates software pipelining, which is a specialized form of loop unrolling that in certain cases improves run-time performance. Software pipelining uses instruction scheduling to eliminate instruction stalls within loops, rearranging instructions between different unrolled loop iterations to improve performance.

Loops chosen for software pipelining are always innermost loops and do not contain branches or procedure calls. To determine whether using level 5 benefits your particular program, you should time program execution for the same program compiled at levels 4 and 5. For programs that contain loops that exhaust available registers, longer execution times may result with level 5.

[NO]PIPELINE Controls Activation of the software pipelining optimization.

The software pipelining optimization applies instruction scheduling to certain innermost loops, allowing instructions within a loop to "wrap around" and execute in a different iteration of the loop. This can reduce the impact of long-latency operations, resulting in faster loop execution.

Software pipelining can be more effective when you combine /OPTIMIZE=PIPELINE with the appropriate /OPTIMIZE=TUNE keyword for the target Alpha processor generation.

Software pipelining also enables the prefetching of data to reduce the impact of cache misses.

Software pipelining is a subset of the optimizations activated by optimization level 5.

To determine whether using /OPTIMIZE=PIPELINE benefits your particular program, you should time program execution for the same program (or subprogram) compiled with and without software pipelining.

For programs containing loops that exhaust available registers, longer execution times can result with optimization level 5, requiring use of /OPTIMIZE=UNROLL= n to limit loop unrolling.

UNROLL= n Controls loop unrolling done by the optimizer. UNROLL= n means to unroll loop bodies n times, where n is between 0 and 16. UNROLL=0 means the optimizer will use its own default unroll amount. Specify UNROLL only at level 3 or higher.
TUNE= keyword Selects processor-specific instruction tuning for implementations of the Alpha architecture. Regardless of the setting of the /OPTIMIZE=TUNE flag, the generated code will run correctly on all implementations of the Alpha architecture. Tuning for a specific implementation can provide improvements in run-time performance. Code tuned for a specific target might run slower on another target.

You can specify one of the following keywords:

GENERIC Selects instruction tuning that is appropriate for all implementations of the Alpha and Itanium architecture. This option is the default.
HOST Selects instruction tuning that is appropriate for the machine on which the code is being compiled.
EV4 (ALPHA ONLY) Selects instruction tuning for the 21064, 21064A, 21066, and 21068 implementations of the Alpha architecture.
EV5 (ALPHA ONLY) Selects instruction tuning for the 21164 implementation of the Alpha architecture.
EV56 (ALPHA ONLY) Selects instruction tuning for the 21164 chip implementations that use the byte- and word-manipulation instruction extensions of the Alpha architecture.

Running programs compiled with the EV56 keyword might incur emulation overhead on EV4 and EV5 processors, but will still run correctly on OpenVMS Version 7.1 (or higher).

PCA56 (ALPHA ONLY) Selects instruction tuning for the 21164PC implementation that uses the byte- and word-manipulation instruction extensions and multimedia instruction extensions of the Alpha architecture.

Running programs compiled with the PCA56 keyword might incur emulation overhead on EV4, EV5, and EV56 processors, but will still run correctly on OpenVMS Version 7.1 (or higher).

EV6 (ALPHA ONLY) Selects instruction tuning for the first-generation 21264 implementation of the Alpha architecture.
EV67 (ALPHA ONLY) Selects instruction tuning for the second-generation 21264 implementation of the Alpha architecture.
ITANIUM2 (I64 ONLY) Selects instruction tuning for the Intel Itanium 2 processor.

For OpenVMS VAX systems the default, /OPTIMIZE, is equivalent to /OPTIMIZE=(DISJOINT,INLINE).

For OpenVMS Alpha systems the default, /OPTIMIZE, is equivalent to /OPTIMIZE=(INLINE=AUTOMATIC,LEVEL=4,UNROLL=0,TUNE=GENERIC).

Use /NOOPTIMIZE or /OPTIMIZE=LEVEL=0 for a debugging session to ensure that the debugger has sufficient information to locate errors in the source program.

In most cases, using /OPTIMIZE will make the program execute faster. As a side effect of getting the fastest execution speeds, using /OPTIMIZE can produce larger object modules and longer compile times than /NOOPTIMIZE.

Loop Unrolling

At optimization level 3 or above, HP C attempts to unroll certain loops to minimize the number of branches and group more instructions together to allow efficient overlapped instruction execution (instruction pipelining). The best candidates for loop unrolling are innermost loops with limited control flow.

As more loops are unrolled, the average size of basic blocks increases. Loop unrolling generates multiple loop code iterations in a manner that allows efficient instruction pipelining.

The loop body is replicated a certain number of times, substituting index expressions. An initialization loop may be created to align the first reference with the main series of loops. A remainder loop may be created for leftover work.

The number of times a loop is unrolled can be determined by the optimizer or the user can specify the limit for loop unrolling using the /OPTIMIZE=UNROLL qualifier. Unless the user specifies a value, the optimizer unrolls a loop 4 times for most loops or 2 times for certain loops (large estimated code size or branches out the loop).

Software Pipelining

Software pipelining and additional software dependence analysis are enabled by using /OPTIMIZE=LEVEL=5, which in certain cases improves run-time performance.

Loop unrolling (enabled at /OPTIMIZE=LEVEL=3 or higher) is constrained in that it cannot schedule across iterations of a loop. Because software pipelining can schedule across loop iterations, it can perform more efficient scheduling that eliminates instruction stalls within loops, by rearranging instructions between different unrolled loop iterations to improve performance.

For example, if software dependence analysis of data flow reveals that certain calculations can be done before or after that iteration of the unrolled loop, software pipelining reschedules those instructions ahead of or behind that loop iteration, at places where their execution can prevent instruction stalls or otherwise improve performance.

Loops chosen for software pipelining:

  • Are always innermost loops (those executed the most)
  • Do not contain branches or procedure calls

By modifying the unrolled loop and inserting instructions as needed before and/or after the unrolled loop, software pipelining generally improves run-time performance, except for cases where the loops contain a large number of instructions with many existing overlapped operations. In this case, software pipelining may not have enough registers available to effectively improve execution performance, and run-time performance using level 5 may not improve as compared to using level 4.

To determine whether using level 5 benefits your particular program, time program execution for the same program compiled at levels 4 and 5. For programs that contain loops that exhaust available registers, longer execution times may result with level 5.

In cases where performance does not improve, consider compiling using /OPTIMIZE=(UNROLL=1, LEVEL=5) to possibly improve the effects of software pipelining.

/PDSC_MASK=option

Forces the compiler to set the PDSC$V_EXCEPTION_MODE field of the procedure descriptor for each function in the compilation unit to the specified value, regardless of the setting of any other qualifiers.

Ordinarily the PDSC$V_EXCEPTION_MODE field gets set automatically by the compiler, depending on the /IEEE_MODE qualifier setting. The /PDSC_MASK qualifier overrides the /IEEE_MODE qualifier setting of this field.

Note

This qualifier is a low-level systems-programming feature that is seldom necessary. Its usage can produce object modules that do not conform to the VMS common language environment and, within C, it can produce nonstandard and seemingly incorrect floating-point behaviors at runtime.

As shown in Table 1-17, the qualifier option keywords are exactly the allowed values defined in the OpenVMS Calling Standard for this field, stripped of the PDSC$V_EXCEPTION_MODE prefix (for example, /PDSC_MASK=SIGNAL sets the field to PDSC$V_EXCEPTION_MODE_SIGNAL).

Table 1-17 /PDSC_MASK Qualifier Options
Option Maps to Meaning
SIGNAL PDSC$K_EXCEPTION_MODE_SIGNAL Raise exceptions for all except underflow (which is flushed to 0).
SIGNAL_ALL PDSC$K_EXCEPTION_MODE_SIGNAL_ALL Raise exceptions for all.
SILENT PDSC$K_EXCEPTION_MODE_SILENT Raise no exceptions. Create only finite values: no infinities, no denorms, no NaNs.
FULL_IEEE PDSC$K_EXCEPTION_MODE_FULL_IEEE Raise no exceptions except as controlled by separate IEEE exception-enabling bits. Create exceptional values according to the IEEE standard.
CALLER PDSC$K_EXCEPTION_MODE_CALLER Emulate the same mode as the caller. This is useful primarily for writing libraries that can be called from languages other than C.

In the absence of the /PDSC_MASK qualifier, the compiler sets the PDSC$V_EXCEPTION_MODE field automatically, depending on the /IEEE_MODE qualifier setting:

  • If /IEEE_MODE is specified with UNDERFLOW_TO_ZERO, DENORM_RESULTS, or INEXACT, then /PDSC_MASK is set to FULL_IEEE.
  • In all other cases, /PDSC_MASK is set to SILENT. This setting differs from the calling-standard-specified default of SIGNAL used by FORTRAN, and is largly responsible for the standard-conforming behavior of the math library when called from C or C++ programs.

/[NO]PLUS_LIST_OPTIMIZE

Provides improved optimization and code generation across file boundaries that would not be available if the files were compiled separately.

When you specify /PLUS_LIST_OPTIMIZE on the command line in conjunction with a series of file specifications separated by plus signs, the compiler does not concatenate each of the specified source files together; such concatenation is generally not correct for C code because a C source file defines a scope.

Instead, each file is treated separately for purposes of parsing, except that the compiler issues diagnostics about conflicting external declarations and function definitions that occur in different files. For purposes of code generation, the compiler treats the files as one application and can perform optimizations across the source files.

The default is /NOPLUS_LIST_OPTIMIZE.

/[NO]POINTER_SIZE=option

Controls whether or not pointer-size features are enabled and whether pointers are 32-bits or 64 bits.

The default is /NOPOINTER_SIZE, which disables pointer-size features, such as the ability to use #pragma pointer_size , and directs the compiler to assume that all pointers are 32-bit pointers. This default represents no change over previous versions of HP C.

Table 1-18 shows the /POINTER_SIZE qualifier options.

Table 1-18 /POINTER_SIZE Qualifier Options
Option Usage
{SHORT|32} The compiler assumes 32-bit pointers.
{LONG[=ARGV]} The compiler assumes 64-bit pointers. If the ARGV option to LONG or 64 is present, the main argument argv will be an array of long pointers instead of an array of short pointers.
{64[=ARGV]} Same as LONG.

Specifying /POINTER_SIZE=32 enables pointer-size features and directs the compiler to assume that all pointers are 32-bit pointers.

Specifying /POINTER_SIZE=64 enables pointer-size features and directs the compiler to assume that all pointers are 64-bit pointers.

Specifying the /POINTER_SIZE qualifier enables the following pointer-size features:

  • Enables processing of #pragma pointer_size .
  • Sets the initial default pointer size.
  • Predefines the preprocessor macro __INITIAL_POINTER_SIZE to 32 or 64. If /POINTER_SIZE is omitted from the command line, __INITIAL_POINTER_SIZE is 0, which allows you to use #ifdef __INITIAL_POINTER_SIZE to test whether or not the compiler supports 64-bit pointers.
  • For /POINTER_SIZE=64, the HP C RTL name mapping table is changed to select the 64-bit versions of malloc , calloc , and other RTL routines by default.

For information about other compiler features that affect pointer size or warn about potential pointer size conflicts, see the following:

  • /CHECK=POINTER_SIZE
  • #pragma pointer_size
  • #pragma required_pointer_size
  • __INITIAL_POINTER_SIZE predefined macro

The /POINTER_SIZE qualifier must be specified for any program that uses 64-bit pointers.

/PRECISION[=option]

Controls whether floating-point operations on float variables are performed in single or double precision. Table 1-19 shows the /PRECISION qualifier options.

Table 1-19 /PRECISION Qualifier Options
Option Usage
SINGLE Performs floating-point operations in single precision.
DOUBLE Performs floating-point operations in double precision.


Previous Next Contents Index