|
|
HP C/HP-UX Programmer's Guide: HP 9000 Computers > Chapter 4 Optimizing HP C Programs Optimizer Pragmas |
|
Pragmas give you the ability to:
Pragmas cannot cross line boundaries and the word pragma must be in lowercase letters. Optimizer pragmas may not appear inside a function. The OPTIMIZE and OPT_LEVEL pragmas control which functions are optimized, and which set of optimizations are performed. You can place these pragmas before any function definitions and they override any previous pragma. These pragmas cannot raise the optimization level above the level specified in the command line. OPT_LEVEL 0, 1, and 2 provide more control over optimization than the +O1 and +O2 compiler options. You use these pragmas to raise or lower optimization at a function level inside the source file. Whereas, the compiler options can only be used for an entire source file. (OPT_LEVEL 3 and 4 can only be used at the beginning of the source file.) Table 4-5 “Optimization Level Precedence ” shows the possible combinations of options and pragmas and the resulting optimization levels. The level at which a function will be optimized is the lower of the two values specified by the command line optimization level and the optimization pragma in force. Table 4-5 Optimization Level Precedence
The values of OPTIMIZE and OPT_LEVEL are summarized in Table 4-6 “Optimizer Control Pragmas ” Table 4-6 Optimizer Control Pragmas
When INLINE is specified without a functionname, any function can be inlined. When specified with functionname(s), these functions are candidates for inlining. The NOINLINE pragma disables inlining for all functions or specified functionname(s). The syntax for performing inlining is:
For example, to specify inlining of the two subprograms checkstat and getinput, use:
To specify that an infrequently called routine should not be inlined when compiling at optimization level 3 or 4, use:
See also the related +O[no]inline optimization option. The compiler gathers information about each function (such as information about function calls, variables, parameters, and return values) and passes this information to the optimizer. The NO_SIDE_EFFECTS and ALLOCS_NEW_MEMORY pragma tell the optimizer to make assumptions it can not normally make, resulting in improved compile-time and run-time speed. They change the default information the compiler collects. If used, the NO_SIDE_EFFECTS and ALLOCS_NEW_MEMORY pragmas should appear before the first function defined in a file and are in effect for the entire file. When used appropriately, these optional pragmas provide better optimization. By default, the optimizer assumes that all functions might modify global variables. To some degree, this assumption limits the extent of optimizations it can perform on global variables. The NO_SIDE_EFFECTS pragma provides a way to override this assumption. If you know for certain that some functions do not modify global variables, you can gain further optimization of code containing calls to these functions by specifying the function names in this pragma. NO_SIDE_EFFECTS has the following form:
All functions in functionname are the names of functions that do not modify the values of global variables. Global variable references can be optimized to a greater extent in the presence of calls to the listed functions. Note that you need the NO_SIDE_EFFECTS pragma in the files where the calls are made, not where the function is defined. This pragma takes effect from the line it first occurs on to the end of the file. The ALLOCS_NEW_MEMORY pragma states that the function functionname returns a pointer to new memory that it either allocates or a routine that it calls allocates. ALLOCS_NEW_MEMORY has the following form:
The new memory must be memory that was either newly allocated or was previously freed and is now reallocated. For example, the standard routines malloc() and calloc() satisfy this requirement. Large applications might have routines that are layered above malloc() and calloc(). These interface routines make the calls to malloc() and calloc(), initialize the memory, and return the pointer that malloc() or calloc() returns. For example, in the program below:
the routine get_new_record falls under this category, and can be included in the ALLOCS_NEW_MEMORY pragma. Informs the compiler that the function(s) may enable floating-point trap handling. When the compiler is so informed, it will not perform loop invariant code motion (LICM) on floating-point operations in the function(s) named in the pragma. This pragma is required for proper code generation when floating-point traps are enabled. #pragma FLOAT_TRAPS_ON {
functionname,...functionname
} For example:
informs the compiler and optimizer that xyz and abc have floating-point traps turned on and therefore LICM optimization should not be performed. The PTRS_STRONGLY_TYPED pragma allows you to specify when a subset of types are type-safe. This provides a finer lever of control than +O[no]ptrs_strongly_typed.
Any types that are defined between the begin-end pair are taken to apply type-safe assumptions. These pragmas are not allowed to nest. For each BEGIN an associated END must be defined in the compilation unit. The pragma will take precedence over the command-line option. Although, sometimes both are required (see example 2). Example 1
In this example only two types, pointer-to-int and pointer-to-float will be assumed to be type-safe. Example 2
In this example all types are assumed to be type-safe except the types bracketed by pragma NOPTRS_STRONGLY_TYPED. The command-line option is required because the default option is +Onoptrs_strongly_typed. |
|