DEC C
User's Guide for OpenVMS Systems


Previous Contents Index

Table 1-10 shows the /MMS_DEPENDENCIES qualifier options.

Table 1-10 /MMS_DEPENDENCIES Qualifier Options
Option Usage
FILE[=filespec] Specifies where to save the dependency file. The default file extension for a dependency file is .mms . Other than using this different default extension, /MMS_DEPENDENCY uses the same procedure that the /OBJECT and /LIST qualifiers do for determining the name of the output file.
[NO]SYSTEM_INCLUDE_FILES Specifies whether or not to include dependency information about system include files (those included with #include < filename> .) If omitted, this option defaults to including dependency information about system include files.

The default is /NOMMS_DEPENDENCY.

/NAMES=(option1,option2)

Option1 converts all definitions and references of external symbols and psects to the case specified. Table 1-11 lists the option1 case values.

Table 1-11 /NAMES Qualifier Option1 Values
Option Usage
UPPERCASE Converts to uppercase.
LOWERCASE Converts to lowercase.
AS_IS Leaves the case as specified in the source.

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

Table 1-12 /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 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-13 describes the /NESTED_INCLUDE_DIRECTORY qualifier options.

Table 1-13 /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.

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

Determines whether DEC C performs code optimizations.

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

Table 1-14 /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 DEC 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 (VAX ONLY) Provides automatic inline expansion of functions that yield optimized code when they are expanded. Whether or not a function is a candidate for inline expansion is based on its size, the number of times it is called, and whether it conforms to the rules specified in Section 5.4.7.
[NO]INLINE[= keyword] (ALPHA ONLY) Provides inline expansion of functions that yield optimized code when they are expanded. Whether or not a function is a candidate for inline expansion is based on its size, the number of times it is called, and whether it conforms to the rules specified in Section 5.4.7. On OpenVMS Alpha systems, you can specify one of the following keywords to control inlining:
NONE No inlining is done, even if requested by a #pragma inline preprocessor directive. /OPTIMIZE=INLINE=NONE is equivalent to /OPTIMIZE=NOINLINE.
MANUAL Inlines only those function calls explicitly requested for inlining by a #pragma inline directive.
||
AUTOMATIC Inlines all of the function calls in the MANUAL category, plus any additional calls that the compiler determines would improve run-time performance. This is the default.
||
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.
||
SIZE Provides behavior similar to that of the keyword AUTOMATIC in versions of DEC C before 5.0, although it is somewhat more conservative in most cases. For DEC C Version 5.0 and higher, AUTOMATIC is treated as a synonym for SIZE. SIZE inlines functions when the compiler determines that it can 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.

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 (ALPHA ONLY) 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.8 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, non-ANSI-Standard functions are not automatically intrinsic and do not even have their prototypes checked. They are only checked if the non-ANSI-Standard 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 (ALPHA ONLY) 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.

For this version of DEC C, 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 (ALPHA ONLY) 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 (ALPHA ONLY) 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 (ALPHA ONLY) 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 architecture. This option is the default.
HOST Selects instruction tuning that is appropriate for the machine on which the code is being compiled.
EV4 Selects instruction tuning for the 21064, 21064A, 21066, and 21068 implementations of the Alpha architecture.
EV5 Selects instruction tuning for the 21164 implementation of the Alpha architecture.

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 (ALPHA ONLY) 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 (ALPHA ONLY)

At optimization level 3 or above, DEC 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 (ALPHA ONLY)

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.

For this version of DEC C, loops chosen for software pipelining:

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 (ALPHA ONLY)

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-15, 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-15 /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:

/[NO]PLUS_LIST_OPTIMIZE (ALPHA ONLY)

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] (ALPHA ONLY)

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 DEC C.

Table 1-16 shows the /POINTER_SIZE qualifier options.

Table 1-16 /POINTER_SIZE Qualifier Options
Option Usage
{SHORT|32} The compiler assumes 32-bit pointers.
{LONG|64} The compiler assumes 64-bit pointers.

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 /POINTER_SIZE either alone or with a keyword value (32, 64, SHORT, or LONG) has the following effects:


Previous Next Contents Index