1.3.7. Optimization Options

To enable optimization passes in the c29clang compiler, select a level of optimization from among the following -O[0|1|2|3|g|s|z] options. In general, the options below represent various levels of optimization with some options designed to favor smaller compiler generated code size over performance, while others favor performance at the cost of increased compiler generated code size.

1.3.7.1. Optimization Level Options

Note

Optimization Option Recommendations

  • The -O0 option is not recommended.

  • The -O1 option is recommended for maximum debuggability.

  • The -Oz option is recommended if small compiler generated code size is a priority.

  • The -O3 option is recommended for optimizing performance, but it is likely to increase compiler-generated code size.

-O0

Performs no optimization.

This optimization level is not recommended for C29x devices; when no optimization is performed, operations are inefficient and runtime behavior is significantly degraded. Use at least the -O1 optimization level.

-O1, -O

Enables restricted optimizations, providing a good trade-off between code size and debuggability. This option is recommended for maximum debuggability.

-O2

Enables most optimizations, but disables some optimizations that may result in larger compiler-generated code size.

-O3

Enables all optimizations available at -O2 plus others that may increase compiler-generated code size. This option is recommended for optimizing performance, but it is likely to increase code size.

This optimization level enables software pipelining.

-Og

Enables restricted optimizations while preserving debuggability. All optimizations available at -O1 are performed with the addition of some optimizations from -O2.

By default, the -Og option enables the -fextend-variable-liveness=all option, which improves debuggability of user variables.

-Os

Enables all optimizations available at -O2 plus additional optimizations designed to reduce code size. In comparison to the -Oz option, the -Os option avoids code size optimizations that are likely to harm performance.

-Oz

Enables all optimizations available at -O2 plus additional optimizations designed to reduce code size. In comparison to the -Os option, the -Oz option performs additional code size optimizations that may harm performance. This optimization setting is recommended if small code size is a priority.

-Ofast

This option is deprecated. It enables all optimizations available at -O3 plus additional aggressive optimizations that are not guaranteed to be in strict compliance with language standards. If you want this behavior, it is recommended that you use the -O3 option in combination with -ffast-math.

1.3.7.3. More Specialized Optimization Options

1.3.7.3.1. Floating-Point Arithmetic

-ffast-math, -fno-fast-math

Enable or disable ‘fast-math’ mode during compilation. By default, the ‘fast-math’ mode is disabled. Enabling ‘fast-math’ mode allows the compiler to perform aggressive, not necessarily value-safe, assumptions about floating-point math, such as:

  • Assume floating-point math is consistent with regular algebraic rules for real numbers (e.g. addition and multiplication are associative, x/y == x * 1/y, and (a + b) * c == a * c + b * c).

  • Operands to floating-point operations are never NaNs or Inf values.

  • +0 and -0 are interchangeable.

Enabling the -ffast-math option also causes the following options to be set:

  • -ffp-contract=fast

  • -fno-honor-nans

  • -ffp-model=fast

  • -fno-rounding-math

  • -fno-signed-zeros

Use of the ‘fast-math’ mode also instructs the compiler to predefine the __FAST_MATH__ macro symbol.

The deprecated -Ofast optimization option automatically enabled the -ffast-math option. If you want the behavior provided by the -Ofast option, it is recommended that you use the -O3 and -ffast-math options in combination.

-ffp-model=<precise|strict|fast>

-ffp-model is an umbrella option that is used to establish a model of floating-point semantics that the compiler will operate under. The available arguments to the -ffp-model option will imply settings for the other, single-purpose floating-point options, including -ffast-math, -ffp-contract, and frounding-math (described below).

The available arguments to the -ffp-model option are:

  • precise - With the exception of floating-point contraction optimizations, all other optimizations that are not value-safe on floating-point data are disabled (ffp-contract=on and -fno-fast-math). The c29clang compiler assumes this floating-point model by default.

  • strict - Disables floating-point contraction optimizations (-ffp-contract=off), honors dynamically-set floating-point rounding modes (-frounding-math), and disables all ‘fast-math’ floating-point optimizations (-fno-fast-math).

  • fast - Enables all ‘fast-math’ floating-point optimizations (-ffast-math) and enables floating-point contraction optimizations across C/C++ statements (-ffp-contract=fast).

-ffp-contract=<fast|on|off|fast-honor-pragmas>

Instruct the compiler whether and to what degree it is allowed to form fused floating-point operations, such as floating-point multiply and add (FMA) instructions. This optimization is also known as floating-point contraction. Fused floating-point operations are permitted to produce more precise results than would be otherwise computed if the operations were performed separately.

The available arguments to the -ffp-contract option are:

  • fast - Allows fusing of floating-point operations across C/C++ statements, and ignores any FP_CONTRACT or clang fp contract pragmas that would otherwise affect the compiler’s ability to apply floating-point contraction optimizations.

  • on - Allows floating-point contraction within a given C/C++ statement. The floating-point contraction behavior can be affected by the use of FP_CONTRACT or clang fp contract pragmas.

  • off - Disables all floating-point contraction optimizations.

  • fast-honor-pragma - Same as the fast argument, but the user can alter the behavior via the use of the FP_CONTRACT and/or clang fp contract pragmas.

-fhonor-nans, -fno-honor-nans

Instructs the compiler to check for and properly handle floating-point NaN values. Use of the -fno-honor-nans can improve code if the compiler can assume that it doesn’t need to check for and enforce the proper handling of floating-point NaN values.

-frounding-math, -fno-rounding-math

By default, the compiler assumes that the -fno-rounding-mode option is in effect. This instructs the compiler to always round-to-nearest for floating-point operations.

The C standard runtime library provides functions such as fesetround and fesetenv that allow you to dynamically alter the floating-point rounding mode. If the -frounding-math option is specified, the compiler honors any dynamically-set floating-point rounding mode. This can be used to prevent optimizations that may affect the result of a floating-point operation if the current rounding mode has changed or is different from the default (round-to-nearest). For example, floating-point constant folding may be inhibited if the result is not exactly representable.

-fsigned-zeros, -fno-signed-zeros

Assumes the presence of signed floating-point zero values. Use of the -fno-signed-zeros option can improve code if the compiler can assume that it doesn’t need to account for the presence of signed floating-point zero values.

1.3.7.3.2. Inlining and Outlining

Function inlining is supported by the C29x compiler; however, function outlining is not currently supported.

-finline-functions, -fno-inline-functions

Inline suitable functions. The -fno-inline-functions option disables this optimization.

-finline-hint-functions

Inline functions that are explicitly or implicitly marked as inline.

1.3.7.3.3. Loop Unrolling

-funroll-loops, -fno-unroll-loops

Enable optimizer to unroll loops. The -fno-unroll-loops option disables this optimization.

1.3.7.3.4. Variable Liveness

-fextend-variable-liveness=[all|this|none]

This option causes user variables (and the this pointer in C++ non-static member functions) to remain “live” during compilation so that they are not optimized out. The result is easier debugging and profiling, but less efficient generated code. This behavior is useful when debugging applications that require some level of optimization in order to run.

The possible settings are as follows:

  • all This setting causes all user variables and the “this” pointer to remain live. This is the default if the -fextend-variable-liveness option is used with no setting specified. The -Og option enables this setting by default.

  • this Only the “this” pointer in C++ non-static member functions remains live.

  • none Variables may be optimized out by the compiler. This is the same as not specifying the -fextend-variable-liveness option at all.