HCS08 Compiler > Optimization

Use this panel to control compiler optimizations. The compiler's optimizer can apply any of its optimizations in either global or non-global optimization mode. You can apply global optimization at the end of the development cycle, after compiling and optimizing all source files individually or in groups.

The table below lists and describes the Optimization options for HC(S)08 compiler.

Table 1. Tool Settings - HCS08 Compiler > Optimization Options
Option Description
Disable optimization (-O0) Disables all optimizations.
No integral promotion on characters (-Cni) Enhances character operation code density by omitting integral promotion. This option enables behavior that is not ANSI-C compliant. Code generated with this option set does not conform to ANSI standards.

Code compiled with this option is not portable. Using this option is not recommended in most cases.

Loop unrolling (i[number]) (-Cu) Enables loop unrolling with the following restrictions:
  • Only simple for statements are unrolled, for example, for (i=0; i<10; i++)
  • Initialization and test of the loop counter must be done with a constant.
  • Only <, >, <=, >= are permitted in a condition.
  • Only ++ or -- are allowed for the loop variable increment or decrement.
  • The loop counter must be integral.
  • No change of the loop counter is allowed within the loop.
  • The loop counter must not be used on the left side of an assignment.
  • No address operator (&) is allowed on the loop counter within the loop.
  • Only small loops are unrolled:

    Loops with few statements within the loop.

    Loops with fewer than 16 increments or decrements of the loop counter.

    The bound may be changed with the optional argument = i<number>.

    The -Cu=i20 option unrolls loops with a maximum of 20 iterations.

Main Optimize Target: Optimize for There are various points where the Compiler has to select between two possibilities: it can either generate fast, but large code, or small but slower code.

The Compiler generally optimizes on code size. It often has to decide between a runtime routine or an expanded code. The programmer can decide whether to select between the slower and shorter or the faster and longer code sequence by setting a command line switch.

  • The Code Size (-Os) option directs the Compiler to optimize the code for smaller code size. The Compiler trades faster-larger code for slower-smaller code.
  • The Execution Time (-Ot) option directs the Compiler to optimize the code for faster execution time. The Compiler replaces slower/smaller code with faster/larger code. This option only affects some special code sequences. This option has to be set together with other optimization options (e.g., register optimization) to get best results.
Optimize dead assignments Optimizes dead assignments. The Compiler removes assignments to unused local variables.

There are three possible settings for this option:

  • always (even if HLI present in function): Always optimize dead assignments (even if HLI is present in current function). The Compiler does not consider inline assembler accesses.
Note: This option is unsafe when inline assembler code contains accesses to local variables.
  • yes, but never if HLI present in function : No optimization occurs. This generates the best possible debug information, and produces larger and slower code.
  • never : Optimize dead assignments if HLI is not present in the current function.
Create sub-functions with common code Performs the reverse of inlining. It detects common code parts in the generated code. The Compiler moves the common code to a different place and replaces all occurrences with a JSR to the moved code. At the end of the common code, the Compiler inserts an RTS instruction. The Compiler increases all SP uses by an address size. This optimization takes care of stack allocation, control flow, and of functions having arguments on the stack.

Inline assembler code is never treated as common code. Options are:

  • Default
  • Disable (-Onf)
  • Off (-Of)
Dynamic options configuration for functions (-OdocF) Allows the Compiler to select from a set of options to reach the smallest code size for every function. Without this feature, you must set fixed Compiler switches over the whole compilation unit. With this feature, the Compiler finds the best option combination from a user-defined set for every function.
Inlining (C[n] or OFF) (-Oi) Enables inline expansion. If there is a #pragma INLINE before a function definition, all calls of this function are replaced by the code of this function, if possible.

Using the -Oi=c0 option switches off inlining. Functions marked with the #pragma INLINE are still inlined. To disable inlining, use the -Oi=OFF option.

Disable alias checking (-Ona) Prevents the Compiler from redefining these variables, which allows you to reuse already-loaded variables or equivalent constants. Use this option only when you are sure no real writes of aliases to a variable memory location will occur.
Do generate copy down information for zero values (-OnCopyDown) Using this option, the compiler does not generate a copy down for i.

The initialization with zero optimization shown for the arr array only works in the HIWARE format. The ELF format requires initializing the whole array to zero.

Disable CONST variable by constant replacement (-OnCstVar) Allows you to switch OFF the replacement of CONST variable by the constant value.
Disable code generation for NULL Pointer to Member check (-OnPMNC) Before assigning a pointer to a member in C++, you must ensure that the pointer to the member is not NULL in order to generate correct and safe code. In embedded systems development, the difficulty becomes generating the denser code while avoiding overhead whenever possible (this NULL check code is a good example). This option enables you to switch off the code generation for the NULL check.
Large return value type Compiler supports this option even though returning a 'large' return value may be not as efficient as using an additional pointer. The Compiler introduces an additional parameter for the return value if the return value cannot be passed in registers. Options are:
  • Default
  • Large return value pointer, always with temporary (-Rpt)
  • Large return value pointer and temporary elimination (-Rpe)
Optimize bitfields and volatile bitfields Use this option to optimize bitfields and volatile bitfields. The compiler changes the access order or combines many accesses into one, even if the bitfields are declared as volatile.
Keep loop induction variables in registers Limits the number of loop induction variables the Compiler keeps in registers. Specify any number down to zero (no loop induction variables). The compiler reads and writes loop induction variables within the loop (for example, loop counter), and attempts to keep the variables in registers to reduce execution time and code size. The Compiler takes the optimal number (code density) when this option is not specified. Specifying a high number of loop induction variables may increase code size, particularly for spill and merge code.
Disable optimize bitfields Prevents the Compiler from combining sequences of bitfield assignments containing constants. This simplifies debugging and makes the code more readable.
Disable ICG level branch tail merging Switches the ICG level branch tail merging off. This simplifies debugging and produces more readable code.
Disable any constant folding Prevents the Compiler from folding constants over statement boundaries. All arithmetical operations are coded. This option must be set when using the library functions setjmp() and longjmp(), or the Compiler makes wrong assumptions.
Disable constant folding in the case of a new constant This option prevents the Compiler from folding constants when the resulting constant is new. The option affects only those processors where constants are difficult to load (e.g., RISC processors). On other processors this option makes no change.
Disable any low level common subexpression elimination Prevents the Compiler from reusing common subexpressions, such as array indexes and array base addresses. The code size may increase. The low-level CSE does not have the alias problems of the frontend CSE and is therefore switched on by default.

The two CSE optimizations do not cover the same cases. The low-level CSE has a finer granularity but does not handle all cases of the frontend CSE.

Use this option only to generate more readable code for debugging.

Allocate local variables into registers Allocates local variables (char or int) in registers. The number of local variables allocated in registers depends on the number of available registers. Use this option when using variables as loop counters or switch selectors or when the processor requires register operands for multiple operations (for example, RISC processors). Compiling with this option may increase your code size (spill and merge code).

This optimization may increase code complexity when using High-Level Languages, making debugging more difficult.

Disable frame pointer optimization (-OnX) Prevents the Compiler from converting stack pointer-relative accesses into X-relative accesses. The frame optimizer tries to convert all SP-relative accesses (local variables, spills) into shorter and faster X-relative accesses. In addition, the Compiler traces the value of H:X and removes useless TSX and AIX instructions. Using -OnX to switch the frame optimizer off facilitates debugging.