Both Clang and Flang rely on AOCC optimizer and code generator stages to transform the LLVM IR and generate the best code for the target x86 platform.
Optimization options categorized by type are listed here.
Optimization Level Options
-
-O0No optimization: this level compiles the fastest and generates the most debuggable code.
-
-O1Between levels
-O0and-O2. -
-O2Default option and enables most optimizations.
-
-O3Enables all optimizations which take longer to perform or may generate larger code (in an attempt to make the program run faster).
The
-O3level in AOCC has more optimizations than the base LLVM version. These optimizations include improved handling of indirect calls and advanced vectorization. -
-OfastEnables all the optimizations from
-O3along with other aggressive optimizations that may violate strict compliance with language standards.The
-Ofastlevel in AOCC has more optimizations than the base LLVM version. These optimizations include partial unswitching, improvements to inlining, and unrolling. -
-fltoGenerates output files in LLVM formats suitable for link time optimization. When used with-S, this option generates LLVM intermediate language assembly files. Else, it generates LLVM bit-code format object files (which may be passed on to the linker depending on the stage selection options).-fltois equivalent to-flto=full.-
-flto=full[Default] -
-flto=thin[Not supported, fall back to Full] -
-flto=forcethin[Beta]
-
-
-m32Generates code for a 32-bit environment. The 32-bit environment setsint,long, andpointerto 32 bits and generates code that runs on any i386 system. The compiler generates x86 or IA32 32-bit ABI. The default on a 32-bit host is 32-bit ABI.Note: SUSE Linux Enterprise Server does not support the compilation of 32-bit applications from SP1. It only offers runtime support for the 32-bit binaries. -
-m64Generates code for a 64-bit environment. The 64-bit environment sets
intto 32 bits,longandpointerto 64 bits and generates code for the x86-64 architecture. The default on a 64-bit host is 64-bit ABI. -
-ffast-mathEnables a range of optimizations that provide faster, though sometimes less precise, mathematical operations that may not conform to the IEEE-754 specifications. When this option is specified, the __STDC_IEC_559__ macro is ignored even if set by the system headers.
-
-fopenmpEnables handling of the OpenMP directives and generates parallel code. The OpenMP library to be linked can be specified through the
-fopenmp=<library>option.Note: If-fopenmpor-fopenmp=<library>(for example:-fopenmp=libompor-fopenmp=libgomp) is specified, AOCC picks OpenMP library from the AOCC installed lib directory by default. To use an alternate version of the OpenMP library located at/path/to/lib/, use the following compilation command.-
$ clang -fopenmp -I/path/to/include /path/to/lib/library test.c -
$ clang -fopenmp=<library> -I/path/to/include /path/to/lib/library test.c
While running the application, add /path/to/lib/ to your
LD_LIBRARY_PATHusing the following command.$ export LD_LIBRARY_PATH=/path/to/lib/:$LD_LIBRARY_PATH -
-
-OsSimilar to the level
-O2but with extra optimizations to reduce the code size. -
-OzSimilar to the level
-Os(and thus-O2) but reduces the code size further. -
-OEquivalent to the level
-O2. -
-O4 and higherEquivalent to the level
-O3. -
-zoptEnables the subset of scalar, vector, and loop transformations including advanced variants of loop invariant code motion, SLP and loop vectorizations, loop-fusion, loop-interchange, loop-unswitch, loop tiling, and loop distribution.
-
-fPICEnabled by default, this option generates Position Independent Code (PIC) for shared and static libraries. Use
-fno-PICto disable PIC generation. -
-fPIEEnabled by default, this option generates PIC for executables and static libraries. Use-fno-PIEto disable PIC generation.Note: As-fPICand-fPIEare default options since AOCC 4.1, location independent code is generated by default. With AOCC 4.1 or later, static libraries that are statically linked and not using-fPICoptions so far must be rebuilt with AOCC with these default options. Else, it could display a linker error. Alternatively, use the options-fno-PIC/-fno-PIEwith AOCC to disable generating location independent code.
Floating Point Options
-
-ffp-modelSpecifies floating point behavior of the compiler.
Valid Values
preciseandfastwhere,-
precisedisables the optimizations that are not value-safe on floating-point data. FP contraction (FMA) is disabled. -
fastbehaves similar to specifying-ffast-math.
This
-ffp-modelbehavior is applicable only for AOCC Flang. For Clang, refer to the Clang floating point documentation.Usage
-ffp-model={precise, fast} -
Vector Optimization Options
-
-enable-strided-vectorizationEnables strided memory vectorization as an enhancement to the interleaved vectorization framework present in LLVM. It enables the effective use of gather/scatter instruction patterns. Use this option along with the interleave vectorization option.
Usage
-mllvm -enable-strided-vectorization -
-global-vectorize-slp={true,false}Vectorizes the straight-line code inside a basic block with data reordering vector operations. This option is set to
falseby default.Usage
-mllvm -global-vectorize-slp={true,false} -
-enable-loop-vectorization-with-conditionsEnables efficient vectorization of loops with conditions by conditionally executing the vector instructions as opposed to flattening the loop body and vectorizing. The vectorized code uses vector versions of compare instructions to guard the instructions in the loop body and uses masked instructions to guard against unsafe memory operations. By default, this option is enabled under
-O3.Usage
-mllvm -enable-loop-vectorization-with-conditions -
-legalize-vector-library-callsSplits the unsupported higher vector factor version of vector library calls into supported vector factor version of vector library calls for enabling vectorization. By default, this option is enabled under
-O3.Usage
-mllvm -legalize-vector-library-calls -
-vectorize-non-contiguous-memory-aggressivelyEnables vectorization involving non-contiguous memory locations by generating multiple loads/stores and inserts. By default, this option is enabled under
-O3.Usage
-mllvm -vectorize-non-contiguous-memory-aggressively -
-fvector-transformEnables the subset of vector transformations including improved variants of SLP and loop vectorization. It is enabled under
-zopt.Usage
-fvector-transform -
-fepilog-vectorization-of-inductionsEnables epilog vectorization of loops that require vectorization of loop induction variables.
Usage
-fepilog-vectorization-of-inductions -
-fenable-restrict-based-lvEnables support for considering restrict qualifiers on local variables as non-alias in dependency analysis, which leads to enhanced loop vectorization opportunities.
Usage
-fenable-restrict-based-lv -
-enable-conditional-fixed-valueEnables vectorization for updating scalar values conditionally using a fixed constant.
Usage
-mllvm -enable-conditional-fixed-value
Loop Optimization Options
-
-enable-partial-unswitchEnables partial loop un-switching, which is an enhancement to the existing loop unswitching optimization in LLVM. Partial loop un-switching hoists a condition inside a loop from a path for which the execution condition remains invariant, whereas the original loop un-switching works for a condition that is completely loop invariant. The condition inside the loop gets hoisted out from the invariant path and original loop is retained for the path where condition is variant.
Usage
-mllvm -enable-partial-unswitch -
-aggressive-loop-unswitchEnables a more aggressive loop unswitching heuristic, including implicit support for partial loop unswitching. It allows loops to be unswitched beyond the default cost threshold when a branch condition is reused multiple times within the loop, making the resulting code duplication worthwhile by eliminating redundant control flow.
To limit code bloat, the heuristic favors branch conditions that appear frequently inside the loop. The aggressiveness is controlled by the following option, with the default value of 3.
-mllvm -unswitch-identical-branches-min-count=<n>Usage
-mllvm -aggressive-loop-unswitch -mllvm -unswitch-identical-branches-min-count=<n>where n is a positive integer and lower value of <n> facilitates more unswitching.
-
-lv-function-specializationGenerates specialized function versions when the loops inside the function are vectorizable and the arguments are not aliased with each other.
Usage
-mllvm -lv-function-specialization -
-loop-splittingEnables splitting of loops into multiple loops to eliminate the branches, which compare the loop induction with an invariant or constant expression. By default, this option is enabled under
-O3. To disable this optimization, use-loop-splitting=falseUsage
-mllvm -loop-splitting -
-enable-ipo-loop-splitEnables splitting loops into multiple loops to eliminate branches, which compares the loop induction with a constant expression. This constant expression can be derived through inter-procedural analysis. By default, this option is enabled under
-O3. To disable this optimization, use-enable-ipo-loop-split=falseUsage
-mllvm -enable-ipo-loop-split -
-enable-loop-fusionEnables classical loop fusion transformation where the bodies of multiple loop nests are fused into one loop nest. The transformation checks various legality criteria involving the bounds of the loop nests involved, the control flow nesting of the loop nests, and so on. By default, the transformation is
offbut you can enable it by using this option. Loop fusion enables reuse of memory access operations across the loop nests and is also beneficial for cache performance. As part of the profitability check for this transformation, it uses code size thresholds which control the size of the fused loop body created.Usage
-mllvm -enable-loop-fusion -
-enable-loopinterchangeEnables the classical loop interchange or loop permutation transformation on a loop nest. It reorders the loops in a multi-dimensional loop nest, checking for various legality criteria in the process. By default, the transformation is
offbut you can enable it by using this option. Loop interchange tries to find a reordering of the loops in a multi-dimensional loop nest such that the number of loop invariant expressions that may be hoisted out from an inner loop to a loop at a higher level may be maximized.Usage
-mllvm -enable-loopinterchange -
-fuse-tile-inner-loopEnables fusion of adjacent tiled loops as a part of loop tiling transformation. By default, this option is set to
false.Usage
-mllvm -fuse-tile-inner-loop -
-enable-loop-distribute-advEnables advanced loop distribution which improves loop vectorization by separating out the portions of the loop affecting vectorization. By default, this flag is
disabled.Usage
-mllvm -enable-loop-distribute-adv -
-floop-transformEnables the subset of loop transformations including improved variants of loop-fusion, loop-interchange, loop blocking, and distribution. It is enabled under
-zopt.Usage
-floop-transform -
-faggressive-loop-transformEnables the subset of loop transformations including improved variants of loop unswitching, loop-tiling, and loop versioning licm. It is enabled under
-zopt.Usage
-faggressive-loop-transform -
-fstrip-miningEnables loop strip mining optimization. This optimization breaks a large loop into smaller segments or strips to improve temporal and spatial locality. This option should be invoked with
-flto.Usage
-flto -fstrip-mining -
-ldist-scalar-expandEnables a feature of advanced loop distribution which distributes the loop with scalar expansion of non-affine accesses for better vectorization.
Usage
-Wl,-mllvm -Wl,-ldist-scalar-expand -
-falign-loopsAligns the starting address of loops in the generated machine code to a specified boundary (example: 16, 32, 64 bytes).
Usage
-falign-loops=32The option
-mllvm -align-loopsis the opt, llc tool counterpart of-falign-loopswhich work for AMD Zen architectures only. This option takes the base 2 logarithm value of the preferred loop alignment for Zen architectures. The smallest possible alignment size is 2^3 = 8 bytes. Although values below 3 are allowed, they are not recommended. -
-falign-functionsAligns the starting address of each function in the machine code to a specified byte boundary such as 16, 32, 64, or 128 bytes.
Note: According to the SysV ABI for x86-64, the stack must be 16-byte aligned before executing a call instruction.Usage
-falign-functions=32The option
-mllvm -align-functionsis the opt, llc tool counterpart of-falign-functionswhich work for AMD Zen architectures only. This option takes the base 2 logarithm value of the preferred function alignment for Zen architectures. The smallest possible alignment size is 2^3 = 8 bytes. Although values below 3 are allowed, they are not recommended.
Math Options
-
-convert-pow-exp-to-int={true,false}Converts the call to floating point exponent version of
powto its integer exponent version if the floating-point exponent can be converted to integer. This option is set totrueby default.Usage
-mllvm -convert-pow-exp-to-int={true, false} -
-freciprocal-mathAllows replacing division x/y by multiplication with the reciprocal x * (1/y), which may allow sharing the reciprocal (1/y) between multiple expressions. Unlike with
-mrecip, no additional approximation is allowed when calculating the reciprocal (1/y). However, extra rounding errors will still occur compared to calculating x/y directly.Usage
-freciprocal-math
Inline Optimization Options
-
-inline-recursion=[1,2,3,4]Enables inlining for recursive functions based on heuristics with level 4 being most aggressive. The default level will be 2. Higher levels may lead to code-bloat due to expansion of recursive functions at call sites.
- For level 1-2: Enables inlining for recursive functions using heuristics with inline depth 1. Level 2 uses more aggressive heuristics.
- For level 3: Enables inlining for all recursive functions with inline depth 1.
- For level 4: Enables inlining for all recursive function with inline depth 10.
This is more effective with
-fltoas the whole program analysis is required to perform this optimization.Usage
-flto -finline-recursion=[1,2,3,4] -
-mllvm -inline-threshold=<N>Sets the compiler’s inlining threshold to the specified value. This threshold guides the inliner’s heuristics in determining which functions to inline.
Usage
-mllvm -inline-threshold=1000 -
-extra-inlinerEnables more aggressive inlining during the link time. When this option is enabled, the compiler becomes more aggressive in its inlining decisions, even beyond the default heuristics. This flag can be particularly useful in scenarios where performance is critical, and the cost of increased binary size is acceptable.
Usage
-Wl,-mllvm -Wl,-extra-inliner
Memory Layout Optimization Options
-
-fstruct-layout={1,2,3,4,5,6,7,8,9}Analyzes the whole program to determine if the structures in the code can be peeled, if dead or redundant fields can be deleted, and if the pointer or integer fields in the structure can be compressed. If feasible, this optimization transforms the code to enable these improvements. This transformation is likely to improve cache utilization and memory bandwidth. It is expected to improve the scalability of programs executed on multiple cores.
This enables only under-fltoas the whole program analysis is required to perform this optimization. You can choose different levels of aggressiveness with which this optimization can be applied to your application with 1 being the least aggressive and 7 being the most aggressive level.-
-fstruct-layout=1enables structure peeling. -
-fstruct-layout=2enables structure peeling and selectively compresses self-referential pointers in these structures to 32-bit pointers, wherever safe. -
-fstruct-layout=3enables structure peeling and selectively compresses self-referential pointers in these structures to 16-bit pointers, wherever safe. -
-fstruct-layout=4enables structure peeling, pointer compression as in level 2 and further enables compression of structure fields that are of 64-bit to 32-bit integer type. This is performed under a strict safety check. -
-fstruct-layout=5enables structure peeling, pointer compression as in level 3 and further enables compression of structure fields that are of 64-bit to 32-bit integer type. This is performed under a strict safety check. -
-fstruct-layout=6enables structure peeling, pointer compression as in level 2 and further enables compression of structure fields that are of 64-bit to 32-bit integer type. This is performed under a strict safety check. -
-fstruct-layout=7enables structure peeling, pointer compression as in level 3 and further enables compression of structure fields that are of 64-bit to 16-bit integer type. -
-fstruct-layout=8enables structure peeling, pointer compression, 64-bit integer type compression as in level 6 and creates optimal ordering of peeled structure fields that could improve runtime performance. -
-fstruct-layout=9enables structure peeling, pointer compression, 64-bit integer type compression as in level 7 and creates optimal ordering of peeled structure fields that could improve runtime performance.
Usage
-flto -fstruct-layout={1,2,3,4,5,6,7,8,9}Note:-
-fstruct-layout=4and-fstruct-layout=5are derived from-fstruct-layout=2and-fstruct-layout=3respectively, with the added feature of safe compression of 64-bit to 32-bit integer fields in structures. Going from-fstruct-layout=4to-fstruct-layout=5may result in higher performance if the pointer values are such that the pointers can be compressed to 16 bits. -
-fstruct-layout=6and-fstruct-layout=7are derived from-fstruct-layout=2and-fstruct-layout=3respectively, with the added feature of compression of 64-bit to 32-bit integer fields in structures. These are similar to-fstruct-layout=4and-fstruct-layout=5, but here, the integer fields of the structures are always compressed from 64 bits to 32 bits, without any safety guarantee. - This optimization is currently restricted to C/C++ inputs only. Also, avoid using this option when linking C/C++ objects with the Fortran objects.
-
-
-fremap-arraysTransforms the data layout of a single dimensional array to provide better cache locality. This optimization is effective only under
-fltoas the whole program analysis is required to perform this optimization, which can be invoked as-flto -fremap-arrays.Usage
-flto -fremap-arrays -
-reduce-array-computations={1,2,3}Performs array dataflow analysis and optimizes the unused array computations.
-
-reduce-array-computations=1: Eliminates the computations on unused array elements. -
-reduce-array-computations=2: Eliminates the computations on zero valued array elements. -
-reduce-array-computations=3: Eliminates the computations on unused and zero valued array elements (combination of 1 and 2).
This optimization is effective with
-fltoas the whole program analysis is required to perform this optimization, which can be invoked as-flto -reduce-array-computations={1,2,3}.Usage
-flto -mllvm -reduce-array-computations={1,2,3} -
Instruction Level Optimization Options
-
-enable-X86-prefetchingEnables the generation of x86 prefetch instruction for the memory references inside a loop/inside an inner most loop of a loop nest to prefetch the second dimension of multidimensional array/memory references in the inner most of a loop nest.
Usage
-mllvm -enable-X86-prefetching -
-suppress-fmasIdentifies the reduction patterns on FMA and suppresses the FMA generation as it is not profitable on the reduction patterns.
Usage
-mllvm -suppress-fmas -
-fnt-storeGenerates a non-temporal store instruction for array accesses in a loop with a large trip count.
Usage
-fnt-store -
-fnt-store=aggressiveGenerates non-temporal store instruction for array accesses in a loop, whose iteration count cannot be determined at compile time. In this case, compiler assumes the iteration count is huge.
Usage
-fnt-store=aggressive -
-enable-redundant-movsRemoves any redundant
movoperations including redundant loads from memory and stores to memory. This can be invoked using-Wl,-plugin-opt=-enable-redundant-movs.Usage
-Wl,-plugin-opt=-enable-redundant-movs -
-merge-constantAttempts to promote frequently occurring constants to registers. The aim is to reduce the size of the instruction encoding for instructions using constants and obtain a performance improvement.
Usage
-mllvm -merge-constant -
-mrecip={all,none,sqrt,vec-sqrt,'!'sqrt,'!'vec-sqrt,div,vec-div,'!'div,'!'vec-div}-
-mrecip={all,none}Reciprocal instruction generations can be enabled/disabled by using
all/none.Usage
-
-march=znver{4,5} -mrecip=all -
-march=znver{4,5} -mrecip=none
-
-
-mrecip=sqrt,vec-sqrtGenerates reciprocal square root instructions for float and double.
Prefixing
vec-generates reciprocal square root instructions for vector types. By default, this option is enabled under-march=znver{4,5}.Usage
-march=znver{4,5} -mrecip=sqrt,vec-sqrt -
-mrecip=div,vec-divGenerates reciprocal division instruction for float and double.
Prefixing
vec-generates reciprocal division instruction for vector types.Usage
-march=znver{4,5} -mrecip=div,vec-div -
-mrecip='!'sqrt,'!'vec-sqrt,'!'div,'!'vec-divPrefixing
‘!’prevents the generation of corresponding reciprocal instructions.Usage
-march=znver{4,5} -mrecip='!'sqrt,'!'vec-sqrt,'!'div,'!'vec-div
These approximate instructions are generated only when
-funsafe-math-optimizationsand-ffinite-math-onlyare enabled (which is implied by-ffast-mathor-Ofast). -
-
-optimize-strided-mem-costOptimizes the cost model for strided access to memory.
Usage
-mllvm -optimize-strided-mem-cost -
-fenable-aggressive-gatherThis option enables generation of gather instructions for cases where it is profitable.
Usage
-fenable-aggressive-gather
Scalar Optimization Options
-
-enable-licm-vrpEnables estimation of the virtual register pressure before performing loop invariant code motion. This estimation is used to control the number of loop invariants that will be hoisted during the loop invariant code motion.
Usage
-mllvm -enable-licm-vrp -
-do-block-reorder={none,simple,complex,advanced}Enables reordering of control predicates based on cost to execute the expensive predicates less frequently.
-
none: Disables this optimization -
simple: Reorders simple expressions (default) -
complex: Reorders the control predicates involving exceptions -
advanced: Reorders the control predicates involving exceptions by ensuring the memory safety of load operations in the reordered predicatesUsage
-
-mllvm -do-block-reorder={none, simple, complex, advanced} -
-Wl,-mllvm -Wl,-do-block-reorder={none, simple, complex, advanced}
Limitation
The
advancedvariant has dependency on amdalloc-ext library. Refer to amdalloc-ext in Linking AMD Library for more details. It is recommended you use amdalloc-ext alone as the allocator library for theadvancedvariant.Usage
-Wl,-mllvm -Wl,-do-block-reorder=advanced -lamdalloc-extamdalloc-ext Restriction
Supported only in 64-bit mode on Linux platforms, this library is not thread-safe and so should not be used in any multi-threaded application.
-
-
-
-fscalar-transformEnables a subset of scalar transformations including improved variants of various code movement optimizations such as hoisting and invariant code motion. It is enabled under
-zopt.Usage
-fscalar-transform
Profile Guided Optimization Options
-
-fprofile-instr-generateGenerate instrumented code to collect execution counts into
<file>(overridden byLLVM_PROFILE_FILEenvironment variable). -
-fprofile-instr-use=<profiled data file>Uses the profiling files generated from the program compiled with
-fprofile-instr-generateto guide the optimization decisions.Usage-
$clang -fprofile-instr-generate code.c -o code.out $LLVM_PROFILE_FILE=pfname.raw ./code.out $llvm-profdata merge -output=pfname.data pfname.raw $clang -fprofile-instr-use=pfname.data code.c -o code.out -
$clang -fprofile-instr-generate=pfname.raw code.c -o code.out $./code.out $llvm-profdata merge -output=pfname.data pfname.raw $clang -fprofile-instr-use=pfname.data code.c -o code.out
-
Miscellaneous Options
-
-fitodcallsPromotes indirect to direct calls by placing conditional calls. Application or benchmarks that have small and deterministic set of target functions for function pointers that are passed as call parameters benefit from this optimization. Indirect-to-direct call promotion transforms the code to use all possible determined targets under runtime checks and falls back to the original code for all the other cases. Runtime checks are introduced by the compiler for each of these possible function pointer targets followed by direct calls to the targets.
This is a link time optimization, which is invoked as
-flto -fitodcalls.Usage
-flto -fitodcalls -
-fitodcallsbyclonePerforms value specialization for functions with function pointers passed as an argument. It does this specialization by generating a clone of the function. The cloning of the function happens in the call chain as needed to allow conversion of indirect function call to direct call.
This complements
-fitodcallsoptimization and is also a link time optimization, which is invoked as-flto -fitodcallsbyclone.Usage
-flto -fitodcallsbyclone -
-function-specializeOptimizes the functions with compile time constant formal arguments. This option is enabled by default under
-O3.Usage
-mllvm -function-specialize -
-favoid-fpe-causing-optRestricts a few optimizations that leads to floating point exceptions.
Usage
-favoid-fpe-causing-opt