2.4 Optimization differences

Arm® Compiler 6 provides more performance optimization settings than are present in Arm Compiler 5. However, the optimizations that are performed at each optimization level might differ between the two toolchains.

The table compares the optimization settings and functions in Arm Compiler 5 and Arm Compiler 6.

Table 2-3 Optimization settings

Description Arm Compiler 5 Arm Compiler 6
Optimization levels for performance.
  • -Otime -O0
  • -Otime -O1
  • -Otime -O2
  • -Otime -O3

Note:

The Arm Compiler 5 -O0 option is more similar to the Arm Compiler 6 -O1 option than the Arm Compiler 6 -O0 option.
  • -O0
  • -O1
  • -O2
  • -O3
  • -Ofast
  • -Omax
Optimization levels for code size.
  • -Ospace -O0
  • -Ospace -O1
  • -Ospace -O2
  • -Ospace -O3

Note:

The Arm Compiler 5 -O0 option is more similar to the Arm Compiler 6 -O1 option than the Arm Compiler 6 -O0 option.
  • -Os
  • -Oz
Default -Ospace -O2 -O0
Best trade-off between image size, performance, and debug. -Ospace -O2 -O1
Highest optimization for performance -Otime -O3 -Omax
Highest optimization for code size -Ospace -O3 -Oz

Arm Compiler 6 provides an aggressive optimization setting, -Omax, which automatically enables a feature called Link Time Optimization. For more information, see -flto.

When using -Omax, armclang can perform link time optimizations that were not possible in Arm Compiler 5. These link time optimizations can expose latent bugs in the final image. Therefore, an image built with Arm Compiler 5 might have a different behavior to the image built with Arm Compiler 6.

For example, unused variables without the volatile keyword might be removed when using -Omax in Arm Compiler 6. If the unused variable is actually a volatile variable that requires the volatile keyword, then the removal of the variable can cause the generated image to behave unexpectedly. Since Arm Compiler 5 does not have this aggressive optimization setting, it might not have removed the unused variable, and the resulting image might behave as expected, and therefore the error in the code would be more difficult to detect.

Note:

If the main() function has no arguments (no argc and argv), then Arm Compiler 5 applies a particular optimization at all optimization levels including -O0. Arm Compiler 6 applies this optimization only for optimization levels other than -O0.

When main() is compiled with Arm Compiler 6 at any optimization level except -O0, the compiler defines the symbol __ARM_use_no_argv if main() does not have input arguments. This symbol enables the linker to select an optimized library that does not include code to handle input arguments to main().

When main() is compiled with Arm Compiler 6 at -O0, the compiler does not define the symbol __ARM_use_no_argv. Therefore, the linker selects a default library that includes code to handle input arguments to main(). This library contains semihosting code.

If your main() function does not have arguments and you are compiling at -O0 with Arm Compiler 6, you can select the optimized library by manually defining the symbol __ARM_use_no_argv using inline assembly:

__asm(".global __ARM_use_no_argv\n\t" "__ARM_use_no_argv:\n\t");

Also note that:

  • Microlib does not support the symbol __ARM_use_no_argv. Only define this symbol when using the standard C library.
  • Semihosting code can cause a HardFault on systems that are unable to handle semihosting code. To avoid this HardFault, you must define one or both of:
    • __use_no_semihosting
    • __ARM_use_no_argv
  • If you define __use_no_semihosting without __ARM_use_no_argv, then the library code to handle argc and argv requires you to retarget the following functions:
    • _ttywrch()
    • _sys_exit()
    • _sys_command_string()
Non-ConfidentialPDF file icon PDF versionDUI0742J
Copyright © 2014–2017, 2019 Arm Limited or its affiliates. All rights reserved.