These options control various sorts of optimizations.
Without any optimization option, the compiler’s goal is to reduce the cost of compilation and to make debugging produce the expected results. Statements are independent: if you stop the program with a breakpoint between statements, you can then assign a new value to any variable or change the program counter to any other statement in the function and get exactly the results you would expect from the source code.
Turning on optimization flags makes the compiler attempt to improve the performance and/or code size at the expense of compilation time and possibly the ability to debug the program.
The compiler performs optimization based on the knowledge it has of the program. Com- piling multiple files at once to a single output file mode allows the compiler to use informa- tion gained from all of the files when compiling each of them.
Not all optimizations are controlled directly by a flag. Only optimizations that have a flag are listed.
-O
-O1 Optimize. Optimizing compilation takes somewhat more time, and a lot more memory for a large function.
With ‘-O’, the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.
‘-O’ turns on the following optimization flags:
-fauto-inc-dec -fcprop-registers -fdce
-fdefer-pop -fdelayed-branch -fdse
-fguess-branch-probability -fif-conversion2
-fif-conversion
-finline-small-functions -fipa-pure-const
-fipa-reference
-fmerge-constants -fsplit-wide-types -ftree-builtin-call-dce
-ftree-ccp -ftree-ch
-ftree-copyrename -ftree-dce
-ftree-dominator-opts -ftree-dse
-ftree-fre -ftree-sra -ftree-ter -funit-at-a-time
‘-O’ also turns on ‘-fomit-frame-pointer’ on machines where doing so does not interfere with debugging.
-O2 Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. As compared to ‘-O’, this option increases both compilation time and the performance of the generated code.
‘-O2’ turns on all optimization flags specified by ‘-O’. It also turns on the following optimization flags:
-fthread-jumps
-falign-functions -falign-jumps -falign-loops -falign-labels -fcaller-saves
-fcrossjumping
-fcse-follow-jumps -fcse-skip-blocks -fdelete-null-pointer-checks
-fexpensive-optimizations -fgcse -fgcse-lm
-findirect-inlining -foptimize-sibling-calls -fpeephole2
-fregmove
-freorder-blocks -freorder-functions -frerun-cse-after-loop
-fsched-interblock -fsched-spec -fschedule-insns -fschedule-insns2 -fstrict-aliasing -fstrict-overflow -ftree-switch-conversion
-ftree-pre -ftree-vrp
Please note the warning under ‘-fgcse’ about invoking ‘-O2’ on programs that use computed gotos.
-O3 Optimize yet more. ‘-O3’ turns on all optimizations specified by
‘-O2’ and also turns on the ‘-finline-functions’, ‘-funswitch-loops’,
‘-fpredictive-commoning’, ‘-fgcse-after-reload’ and ‘-ftree-vectorize’
options.
-O0 Reduce compilation time and make debugging produce the expected results.
This is the default.
-Os Optimize for size. ‘-Os’ enables all ‘-O2’ optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.
‘-Os’ disables the following optimization flags:
-falign-functions -falign-jumps -falign-loops
-falign-labels -freorder-blocks -freorder-blocks-and-partition -fprefetch-loop-arrays -ftree-vect-loop-version
If you use multiple ‘-O’ options, with or without level numbers, the last such option is the one that is effective.
Options of the form ‘-fflag’ specify machine-independent flags. Most flags have both positive and negative forms; the negative form of ‘-ffoo’ would be ‘-fno-foo’. In the table below, only one of the forms is listed—the one you typically will use. You can figure out the other form by either removing ‘no-’ or adding it.
The following options control specific optimizations. They are either activated by ‘-O’
options or are related to ones that are. You can use the following flags in the rare cases when “fine-tuning” of optimizations to be performed is desired.
-fno-default-inline
Do not make member functions inline by default merely because they are defined inside the class scope (C++ only). Otherwise, when you specify ‘-O’, member
functions defined inside class scope are compiled inline by default; i.e., you don’t need to add ‘inline’ in front of the member function name.
-fno-defer-pop
Always pop the arguments to each function call as soon as that function returns.
For machines which must pop arguments after a function call, the compiler normally lets arguments accumulate on the stack for several function calls and pops them all at once.
Disabled at levels ‘-O’, ‘-O2’, ‘-O3’, ‘-Os’.
-fforward-propagate
Perform a forward propagation pass on RTL. The pass tries to combine two instructions and checks if the result can be simplified. If loop unrolling is active, two passes are performed and the second is scheduled after loop unrolling.
This option is enabled by default at optimization levels ‘-O2’, ‘-O3’, ‘-Os’.
-fomit-frame-pointer
Don’t keep the frame pointer in a register for functions that don’t need one.
This avoids the instructions to save, set up and restore frame pointers; it also makes an extra register available in many functions. It also makes debugging impossible on some machines.
On some machines, such as the VAX, this flag has no effect, because the stan- dard calling sequence automatically handles the frame pointer and nothing is saved by pretending it doesn’t exist. The machine-description macro FRAME_
POINTER_REQUIRED controls whether a target machine supports this flag. See Section “Register Usage” in GNU Compiler Collection (GCC) Internals.
Enabled at levels ‘-O’, ‘-O2’, ‘-O3’, ‘-Os’.
-foptimize-sibling-calls
Optimize sibling and tail recursive calls.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-fno-inline
Don’t pay attention to the inline keyword. Normally this option is used to keep the compiler from expanding any functions inline. Note that if you are not optimizing, no functions can be expanded inline.
-finline-small-functions
Integrate functions into their callers when their body is smaller than expected function call code (so overall size of program gets smaller). The compiler heuris- tically decides which functions are simple enough to be worth integrating in this way.
Enabled at level ‘-O2’.
-findirect-inlining
Inline also indirect calls that are discovered to be known at compile time thanks to previous inlining. This option has any effect only when inlining itself is turned on by the ‘-finline-functions’ or ‘-finline-small-functions’ options.
Enabled at level ‘-O2’.
-finline-functions
Integrate all simple functions into their callers. The compiler heuristically de- cides which functions are simple enough to be worth integrating in this way.
If all calls to a given function are integrated, and the function is declared static, then the function is normally not output as assembler code in its own right.
Enabled at level ‘-O3’.
-finline-functions-called-once
Consider all static functions called once for inlining into their caller even if they are not marked inline. If a call to a given function is integrated, then the function is not output as assembler code in its own right.
Enabled at levels ‘-O1’, ‘-O2’, ‘-O3’ and ‘-Os’.
-fearly-inlining
Inline functions marked by always_inline and functions whose body seems smaller than the function call overhead early before doing
‘-fprofile-generate’ instrumentation and real inlining pass. Doing so makes profiling significantly cheaper and usually inlining faster on programs having large chains of nested wrapper functions.
Enabled by default.
-finline-limit=n
By default, GCC limits the size of functions that can be inlined. This flag allows coarse control of this limit. n is the size of functions that can be inlined in number of pseudo instructions.
Inlining is actually controlled by a number of parameters, which may be spec- ified individually by using ‘--param name=value’. The ‘-finline-limit=n’
option sets some of these parameters as follows:
max-inline-insns-single is set ton/2.
max-inline-insns-auto is set ton/2.
See below for a documentation of the individual parameters controlling inlining and for the defaults of these parameters.
Note: there may be no value to ‘-finline-limit’ that results in default be- havior.
Note: pseudo instruction represents, in this particular context, an abstract measurement of function’s size. In no way does it represent a count of assembly instructions and as such its exact meaning might change from one release to an another.
-fkeep-inline-functions
In C, emitstaticfunctions that are declaredinlineinto the object file, even if the function has been inlined into all of its callers. This switch does not affect functions using the extern inline extension in GNU C89. In C++, emit any and all inline functions into the object file.
-fkeep-static-consts
Emit variables declared static constwhen optimization isn’t turned on, even if the variables aren’t referenced.
GCC enables this option by default. If you want to force the compiler to check if the variable was referenced, regardless of whether or not optimization is turned on, use the ‘-fno-keep-static-consts’ option.
-fmerge-constants
Attempt to merge identical constants (string constants and floating point con- stants) across compilation units.
This option is the default for optimized compilation if the assembler and linker support it. Use ‘-fno-merge-constants’ to inhibit this behavior.
Enabled at levels ‘-O’, ‘-O2’, ‘-O3’, ‘-Os’.
-fmerge-all-constants
Attempt to merge identical constants and identical variables.
This option implies ‘-fmerge-constants’. In addition to ‘-fmerge-constants’
this considers e.g. even constant initialized arrays or initialized constant vari- ables with integral or floating point types. Languages like C or C++require each variable, including multiple instances of the same variable in recursive calls, to have distinct locations, so using this option will result in non-conforming be- havior.
-fmodulo-sched
Perform swing modulo scheduling immediately before the first scheduling pass.
This pass looks at innermost loops and reorders their instructions by overlap- ping different iterations.
-fmodulo-sched-allow-regmoves
Perform more aggressive SMS based modulo scheduling with register moves allowed. By setting this flag certain anti-dependences edges will be deleted which will trigger the generation of reg-moves based on the life-range analysis.
This option is effective only with ‘-fmodulo-sched’ enabled.
-fno-branch-count-reg
Do not use “decrement and branch” instructions on a count register, but instead generate a sequence of instructions that decrement a register, compare it against zero, then branch based upon the result. This option is only meaningful on architectures that support such instructions, which include x86, PowerPC, IA- 64 and S/390.
The default is ‘-fbranch-count-reg’.
-fno-function-cse
Do not put function addresses in registers; make each instruction that calls a constant function contain the function’s address explicitly.
This option results in less efficient code, but some strange hacks that alter the assembler output may be confused by the optimizations performed when this option is not used.
The default is ‘-ffunction-cse’
-fno-zero-initialized-in-bss
If the target supports a BSS section, GCC by default puts variables that are initialized to zero into BSS. This can save space in the resulting code.
This option turns off this behavior because some programs explicitly rely on variables going to the data section. E.g., so that the resulting executable can find the beginning of that section and/or make assumptions based on that.
The default is ‘-fzero-initialized-in-bss’.
-fmudflap -fmudflapth -fmudflapir
For front-ends that support it (C and C++), instrument all risky pointer/array dereferencing operations, some standard library string/heap functions, and some other associated constructs with range/validity tests. Modules so in- strumented should be immune to buffer overflows, invalid heap use, and some other classes of C/C++ programming errors. The instrumentation relies on a separate runtime library (‘libmudflap’), which will be linked into a program if ‘-fmudflap’ is given at link time. Run-time behavior of the instrumented program is controlled by the MUDFLAP_OPTIONSenvironment variable. See env MUDFLAP_OPTIONS=-help a.out for its options.
Use ‘-fmudflapth’ instead of ‘-fmudflap’ to compile and to link if your pro- gram is multi-threaded. Use ‘-fmudflapir’, in addition to ‘-fmudflap’ or
‘-fmudflapth’, if instrumentation should ignore pointer reads. This produces less instrumentation (and therefore faster execution) and still provides some protection against outright memory corrupting writes, but allows erroneously read data to propagate within a program.
-fthread-jumps
Perform optimizations where we check to see if a jump branches to a location where another comparison subsumed by the first is found. If so, the first branch is redirected to either the destination of the second branch or a point immedi- ately following it, depending on whether the condition is known to be true or false.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-fsplit-wide-types
When using a type that occupies multiple registers, such as long long on a 32-bit system, split the registers apart and allocate them independently. This normally generates better code for those types, but may make debugging more difficult.
Enabled at levels ‘-O’, ‘-O2’, ‘-O3’, ‘-Os’.
-fcse-follow-jumps
In common subexpression elimination (CSE), scan through jump instructions when the target of the jump is not reached by any other path. For example, when CSE encounters an if statement with an else clause, CSE will follow the jump when the condition tested is false.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-fcse-skip-blocks
This is similar to ‘-fcse-follow-jumps’, but causes CSE to follow jumps which conditionally skip over blocks. When CSE encounters a simple if statement with no else clause, ‘-fcse-skip-blocks’ causes CSE to follow the jump around the body of the if.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-frerun-cse-after-loop
Re-run common subexpression elimination after loop optimizations has been performed.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-fgcse Perform a global common subexpression elimination pass. This pass also per- forms global constant and copy propagation.
Note: When compiling a program using computed gotos, a GCC extension, you may get better runtime performance if you disable the global common subexpression elimination pass by adding ‘-fno-gcse’ to the command line.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-fgcse-lm
When ‘-fgcse-lm’ is enabled, global common subexpression elimination will attempt to move loads which are only killed by stores into themselves. This allows a loop containing a load/store sequence to be changed to a load outside the loop, and a copy/store within the loop.
Enabled by default when gcse is enabled.
-fgcse-sm
When ‘-fgcse-sm’ is enabled, a store motion pass is run after global common subexpression elimination. This pass will attempt to move stores out of loops.
When used in conjunction with ‘-fgcse-lm’, loops containing a load/store se- quence can be changed to a load before the loop and a store after the loop.
Not enabled at any optimization level.
-fgcse-las
When ‘-fgcse-las’ is enabled, the global common subexpression elimination pass eliminates redundant loads that come after stores to the same memory location (both partial and full redundancies).
Not enabled at any optimization level.
-fgcse-after-reload
When ‘-fgcse-after-reload’ is enabled, a redundant load elimination pass is performed after reload. The purpose of this pass is to cleanup redundant spilling.
-funsafe-loop-optimizations
If given, the loop optimizer will assume that loop indices do not overflow, and that the loops with nontrivial exit condition are not infinite. This enables a wider range of loop optimizations even if the loop optimizer itself cannot prove that these assumptions are valid. Using ‘-Wunsafe-loop-optimizations’, the compiler will warn you if it finds this kind of loop.
-fcrossjumping
Perform cross-jumping transformation. This transformation unifies equivalent code and save code size. The resulting code may or may not perform better than without cross-jumping.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-fauto-inc-dec
Combine increments or decrements of addresses with memory accesses. This pass is always skipped on architectures that do not have instructions to support this. Enabled by default at ‘-O’ and higher on architectures that support this.
-fdce Perform dead code elimination (DCE) on RTL. Enabled by default at ‘-O’ and higher.
-fdse Perform dead store elimination (DSE) on RTL. Enabled by default at ‘-O’ and higher.
-fif-conversion
Attempt to transform conditional jumps into branch-less equivalents. This include use of conditional moves, min, max, set flags and abs instructions, and some tricks doable by standard arithmetics. The use of conditional execution on chips where it is available is controlled by if-conversion2.
Enabled at levels ‘-O’, ‘-O2’, ‘-O3’, ‘-Os’.
-fif-conversion2
Use conditional execution (where available) to transform conditional jumps into branch-less equivalents.
Enabled at levels ‘-O’, ‘-O2’, ‘-O3’, ‘-Os’.
-fdelete-null-pointer-checks
Use global dataflow analysis to identify and eliminate useless checks for null pointers. The compiler assumes that dereferencing a null pointer would have halted the program. If a pointer is checked after it has already been derefer- enced, it cannot be null.
In some environments, this assumption is not true, and programs can safely dereference null pointers. Use ‘-fno-delete-null-pointer-checks’ to disable this optimization for programs which depend on that behavior.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-fexpensive-optimizations
Perform a number of minor optimizations that are relatively expensive.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-foptimize-register-move -fregmove
Attempt to reassign register numbers in move instructions and as operands of other simple instructions in order to maximize the amount of register tying.
This is especially helpful on machines with two-operand instructions.
Note ‘-fregmove’ and ‘-foptimize-register-move’ are the same optimiza- tion.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.
-fira-algorithm=algorithm
Use specified coloring algorithm for the integrated register allocator. Thealgo- rithmargument should bepriorityorCB. The first algorithm specifies Chow’s priority coloring, the second one specifies Chaitin-Briggs coloring. The second algorithm can be unimplemented for some architectures. If it is implemented, it is the default because Chaitin-Briggs coloring as a rule generates a better code.
-fira-region=region
Use specified regions for the integrated register allocator. The regionargument should be one of all, mixed, or one. The first value means using all loops as register allocation regions, the second value which is the default means using all loops except for loops with small register pressure as the regions, and third one means using all function as a single region. The first value can give best result for machines with small size and irregular register set, the third one results in faster and generates decent code and the smallest size code, and the default value usually give the best results in most cases and for most architectures.
-fira-coalesce
Do optimistic register coalescing. This option might be profitable for architec- tures with big regular register files.
-fno-ira-share-save-slots
Switch off sharing stack slots used for saving call used hard registers living through a call. Each hard register will get a separate stack slot and as a result function stack frame will be bigger.
-fno-ira-share-spill-slots
Switch off sharing stack slots allocated for pseudo-registers. Each pseudo- register which did not get a hard register will get a separate stack slot and as a result function stack frame will be bigger.
-fira-verbose=n
Set up how verbose dump file for the integrated register allocator will be. De- fault value is 5. If the value is greater or equal to 10, the dump file will be stderr as if the value were n minus 10.
-fdelayed-branch
If supported for the target machine, attempt to reorder instructions to exploit instruction slots available after delayed branch instructions.
Enabled at levels ‘-O’, ‘-O2’, ‘-O3’, ‘-Os’.
-fschedule-insns
If supported for the target machine, attempt to reorder instructions to eliminate execution stalls due to required data being unavailable. This helps machines that have slow floating point or memory load instructions by allowing other instructions to be issued until the result of the load or floating point instruction is required.
Enabled at levels ‘-O2’, ‘-O3’, ‘-Os’.