2.3.9. Controlling code generation

The following options allow you to control various aspects of the code generated by the compiler, such as optimization, use of the code and data areas, endianness, and alignment. Refer to Pragmas for information on additional code generation options that are controlled using pragmas. This section describes:

Defining optimization criteria

-Ospace

Optimize to reduce image size at the expense of increased execution time. For example, large structure copies are done by out-of-line function calls instead of inline code.

-Otime

Optimize to reduce execution time at the expense of a larger image. For example, compile:

while (expression) body…;

as:

if (expression) {
	do body…;
	while (expression);
}

If neither -Otime or -Ospace is specified, the compiler uses a balance between the two. You can compile time-critical parts of your code with -Otime, and the rest with -Ospace. You should not specify both -Otime and -Ospace at the same time.

-O, number

Specifies the level of optimization to be used. The optimization levels are:

-O0

Turn off all optimization, except some simple source transformations. This is the default optimization level if debug tables are generated with -g+. It gives the best debug view and the lowest level of optimization.

-O1

Turn off the following optimizations:

  • structure splitting

  • range splitting

  • cross-jumping

  • conditional execution.

If this option is specified and debug tables are generated with -g+ it gives a satisfactory debug view with good code density.

-O2

Generate fully optimized code. If used with -g+, this option produces fully optimized code that is acceptable to the debugger, though the mapping of object code to source code is not always clear.

This is the default optimization level if debug tables are not generated.

Optimization options have the following effect on the debug view produced when compiling with -g+:

  • If DWARF1 debug tables are generated (-dwarf1 compiler option) and a procedure call standard that does not use a frame-pointer register is used (always the case with Thumb, and the default with ARM), local variables that have been allocated to the stack cannot be displayed by the debugger, regardless of optimization level. In addition, stack backtrace is not possible.

  • For all debug tables formats, if optimization levels 1 and higher are used the debugger may display misleading values for local variables. If a variable is not live at the point where its value is interrogated, its location may be used for some other variable. In addition, the compiler replaces some local variables with constant values at each place the variable is used.

  • For all debug table formats, if optimization level 2 is used the value of variables that have been subject to range splitting or structure splitting cannot be displayed.

Refer to Pragmas controlling optimization for more information on controlling optimization.

Setting the number of instructions for literals

-zi, Number

The compiler selects a value for the maximum number of instructions allowed to generate an integer literal inline before using LDR rx,=value on the basis of the -Otime, -Ospace, and -processor options.

You can alter this behavior by setting Number to an integer between 1 and 4. Lower numbers generate less code at the possible expense of speed, depending on your memory system. The effect of altering this value is small, and is usually not significant.

Controlling code and data areas

-fw

Allows string literals to be writable, as expected by some UNIX code, by allocating them in the program data area rather than the notionally read-only code area. This also stops the compiler reusing a multiply occurring string literal.

-fy

Treats enumerations as signed integers. This option is off by default (no forced integers).

-zc

Make char signed. It is normally unsigned in C++ and ANSI C modes, and signed in PCC mode. The sign of char is set by the last option specified that would normally affect it. For example, if you specify both the -ansic and -zc options and you want to make char signed in ANSI C mode, you must specify the -zc option after the -ansic option.

-zo

Generates one AOF area for each function. This can result in increased code size.

Normally the compiler generates one AOF function for each C compilation unit, and at least one AOF function for each C++ compilation unit.

This option enables the linker to remove unused functions when the -remove linker option is specified.

-zt

Disallows tentative declarations. If this option is specified, the compiler assumes that any occurrence of a top level construct such as int i; is a definition without initializer, rather than a tentative definition. Any subsequent definition with initializer in the same scope will generate an error. This may fault code that conforms to the ANSI specification.

This option has effect only for C, not for C++. Tentative declarations are not permitted in C++. This option is useful in combination with the -zz and -zas options.

-zz, ZI_Threshold_Size

Sets the value of the zero-initialized data threshold size. The compiler will place uninitialized global variables in the Zero Initialized (ZI) data area if their size is greater than ZI_Threshold_Size bytes.

For example, you can force uninitialized global variables of any size to be placed in the ZI data area by specifying -zz0, though this may increase your code size.

Use this option in combination with -zt to avoid increased code size. Option -zzt provides a convenient shorthand. The default threshold size is 8 bytes.

-zzt, ZI_Threshold_Size

Combines the -zt and -zz options. For example, specify -zzt0 to force the compiler to disallow tentative declarations and place all uninitialized global variables in the ZI data area.

Setting endianness

-bigend

Compiles code for an ARM operating with big-endian memory. The most significant byte has lowest address.

-littleend

Compiles code for an ARM operating with little-endian memory. The least significant byte has lowest address. This is the default.

Controlling SWI calling standards

-fz

Instructs the compiler that an inline SWI may overwrite the contents of the link register. This option is usually used for modules that run in Supervisor mode, and that contain inline SWIs. You must use this option when compiling code that contains inline SWIs.

Setting load and store options

-za, Number

Specifies whether LDR may only access word-aligned addresses. Valid values are:

-za0

LDR is not restricted to accessing word-aligned addresses. This is the default.

-za1

LDR may only access word-aligned addresses.

-zr, Number

Limits the number of register values transferred by load multiple and store multiple instructions generated by the compiler to Number. Valid values for Number are 3 to 16 inclusively. The default value is 16.

You can use this option to reduce interrupt latency. Note that the inline assembler is not subject to the limit imposed by the -zr option.

The Thumb compiler does not support this option.

Setting alignment options

-zas, Number

Specifies the minimum byte alignment for structures. Valid values for Number are:


1, 2, 4, 8

The default is 4 for both ARM and Thumb compilers. This allows structure copying to be implemented more efficiently by copying in units of words, rather than bytes. Setting a lower value reduces the amount of padding required, at the expense of the speed of structure copying.

-zap, Number

Specifies whether pointers to structures are assumed to be aligned on at least the minimum byte alignment boundaries, as set by the -zas option. Valid values are:

-zap1

Pointers to structures are assumed to be aligned on at least the minimum byte alignment boundaries set by -zas. This is the default.

-zap0

Pointers to structures are not assumed to be aligned on at least the minimum byte alignment boundaries set by -zas. Casting short[ ] to struct {short, short,...} does not cause a problem.

-zat, Number

Specifies the minimum byte alignment for top-level static objects, such as global variables. Valid values for Number are:


1, 2, 4, 8

The default is 4 for the ARM compilers and 1 for the Thumb compilers.

Copyright © 1997, 1998 ARM Limited. All rights reserved.ARM DUI 0041C